@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 +1 @@
1
- {"version":3,"file":"converter.js","names":["_exhaustiveCheck"],"sources":["../src/converter.ts"],"sourcesContent":["import type {\n AppendMessage,\n DataMessagePart,\n ThreadAssistantMessage,\n ThreadUserMessage,\n} from \"@assistant-ui/core\";\nimport {\n parseDataUrl,\n resolveFilePartSource,\n} from \"@assistant-ui/core/internal\";\nimport type { StreamingTimingAccessors } from \"@assistant-ui/core/react\";\n\n/** Known content block types from @langchain/core messages. */\nexport type LangChainContentBlock =\n | { type: \"text\"; text: string }\n | { type: \"text_delta\"; text: string }\n | { type: \"image_url\"; image_url: string | { url?: string } }\n | { type: \"thinking\"; thinking: string }\n | {\n type: \"reasoning\";\n summary?: Array<{ type: \"summary_text\"; text?: string }>;\n reasoning?: string;\n }\n | {\n type: \"file\";\n data: string;\n mime_type: string;\n source_type?: \"base64\";\n metadata?: { filename?: string };\n }\n | {\n type: \"file\";\n url: string;\n mime_type?: string;\n source_type: \"url\";\n metadata?: { filename?: string };\n }\n | {\n type: \"file\";\n id: string;\n mime_type?: string;\n source_type: \"id\";\n metadata?: { filename?: string };\n }\n | {\n type: \"audio\";\n data: string;\n mime_type: string;\n source_type: \"base64\";\n }\n | { type: \"tool_use\" | \"input_json_delta\" };\n\ntype ConvertedContentPart =\n | ThreadUserMessage[\"content\"][number]\n | ThreadAssistantMessage[\"content\"][number];\n\nexport const convertLangChainContentBlock = (\n part: LangChainContentBlock,\n): ConvertedContentPart | null | undefined => {\n const type = part.type;\n switch (type) {\n case \"text\":\n case \"text_delta\":\n return {\n type: \"text\" as const,\n text: typeof part.text === \"string\" ? part.text : \"\",\n };\n case \"image_url\": {\n const image =\n typeof part.image_url === \"string\"\n ? part.image_url\n : part.image_url?.url;\n if (!image) return null;\n return { type: \"image\" as const, image };\n }\n case \"file\":\n return {\n type: \"file\" as const,\n filename: part.metadata?.filename ?? \"file\",\n data:\n part.source_type === \"url\"\n ? part.url\n : part.source_type === \"id\"\n ? part.id\n : part.data,\n mimeType: part.mime_type ?? \"application/octet-stream\",\n ...((part.source_type === \"url\" || part.source_type === \"id\") && {\n sourceType: part.source_type,\n }),\n };\n case \"audio\": {\n const mimeType = part.mime_type ?? \"application/octet-stream\";\n const subtype = mimeType.startsWith(\"audio/\")\n ? mimeType.slice(\"audio/\".length)\n : undefined;\n return {\n type: \"file\" as const,\n filename: subtype ? `audio.${subtype}` : \"audio\",\n data: part.data,\n mimeType,\n };\n }\n case \"thinking\":\n return hasVisibleText(part.thinking)\n ? { type: \"reasoning\" as const, text: part.thinking }\n : null;\n case \"reasoning\": {\n const text = getReasoningText(part);\n return text ? { type: \"reasoning\" as const, text } : null;\n }\n case \"tool_use\":\n case \"input_json_delta\":\n return null;\n default:\n return undefined;\n }\n};\n\nconst hasVisibleText = (text: unknown): boolean =>\n typeof text === \"string\" && text.trim() !== \"\";\n\n/**\n * Audio output arrives outside the content array: providers leave `content`\n * empty and put the spoken text in `additional_kwargs.audio.transcript`. The\n * audio bytes stay behind because no provider reports their media type, and a\n * streamed response carries raw PCM rather than a playable file.\n */\nexport const withAudioTranscript = <T extends { type: string; text?: unknown }>(\n parts: readonly T[],\n additionalKwargs: Record<string, unknown> | undefined,\n): readonly (T | { type: \"text\"; text: string })[] => {\n const audio = additionalKwargs?.audio as { transcript?: unknown } | undefined;\n const transcript = audio?.transcript;\n if (typeof transcript !== \"string\" || !hasVisibleText(transcript))\n return parts;\n if (parts.some((part) => part.type === \"text\" && hasVisibleText(part.text)))\n return parts;\n return [\n ...parts.filter((part) => part.type !== \"text\"),\n { type: \"text\" as const, text: transcript },\n ];\n};\n\nexport const getCustomMetadata = (\n additionalKwargs: Record<string, unknown> | undefined,\n): Record<string, unknown> =>\n (additionalKwargs?.metadata as Record<string, unknown>) ?? {};\n\nexport const uiMessageToDataPart = <\n TUIMessage extends { name: string; props: Record<string, unknown> },\n>(\n ui: TUIMessage,\n): DataMessagePart => ({\n type: \"data\",\n name: ui.name,\n data: ui.props,\n});\n\n/**\n * Audio media types that reach a provider's audio input through the LangChain\n * `audio` block. langchain-core derives OpenAI's `input_audio.format` by\n * splitting `mime_type` on `/`, and that format is a wav-or-mp3 enum, so\n * `audio/mpeg` passes the converter and is rejected at the provider.\n */\nconst audioBlockMimeTypes = new Map<string, \"audio/mp3\" | \"audio/wav\">([\n [\"audio/mp3\", \"audio/mp3\"],\n [\"audio/mpeg\", \"audio/mp3\"],\n [\"audio/wav\", \"audio/wav\"],\n [\"audio/wave\", \"audio/wav\"],\n [\"audio/x-wav\", \"audio/wav\"],\n]);\n\nexport const getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...(msg.attachments?.flatMap((a) => a.content) ?? []),\n ];\n\n const hasNonText = allContent.some(\n (part) =>\n part.type === \"file\" || part.type === \"image\" || part.type === \"audio\",\n );\n const hasText = allContent.some((part) => part.type === \"text\");\n if (hasNonText && !hasText) {\n allContent.unshift({ type: \"text\", text: \" \" });\n }\n\n const content = allContent.flatMap((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\" as const, text: part.text };\n case \"image\":\n return { type: \"image_url\" as const, image_url: { url: part.image } };\n case \"file\": {\n const metadata = { filename: part.filename ?? \"file\" };\n if (part.sourceType === \"id\") {\n return {\n type: \"file\" as const,\n id: part.data,\n mime_type: part.mimeType,\n filename: metadata.filename,\n metadata,\n source_type: \"id\" as const,\n };\n }\n const source = resolveFilePartSource(part);\n if (source.kind === \"url\") {\n return {\n type: \"file\" as const,\n url: source.url,\n mime_type: part.mimeType,\n filename: metadata.filename,\n metadata,\n source_type: \"url\" as const,\n };\n }\n const audioMimeType = audioBlockMimeTypes.get(\n source.mimeType.toLowerCase(),\n );\n if (audioMimeType) {\n return {\n type: \"audio\" as const,\n data: source.data,\n mime_type: audioMimeType,\n source_type: \"base64\" as const,\n };\n }\n return {\n type: \"file\" as const,\n data: source.data,\n mime_type: source.mimeType,\n filename: metadata.filename,\n metadata,\n source_type: \"base64\" as const,\n };\n }\n case \"audio\": {\n const parsed = parseDataUrl(part.audio.data);\n return {\n type: \"audio\" as const,\n data: parsed?.data ?? part.audio.data,\n mime_type: `audio/${part.audio.format}`,\n source_type: \"base64\" as const,\n };\n }\n case \"data\":\n return [];\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n default: {\n const _exhaustiveCheck: \"reasoning\" | \"source\" | \"generative-ui\" = type;\n throw new Error(\n `Unsupported append message part type: ${_exhaustiveCheck}`,\n );\n }\n }\n });\n\n if (content.length === 1 && content[0]?.type === \"text\") {\n return content[0].text ?? \"\";\n }\n return content;\n};\n\nconst getReasoningText = (part: {\n readonly summary?: ReadonlyArray<{ readonly text?: string }>;\n readonly reasoning?: string;\n}): string => {\n const summary = part.summary?.map((s) => s?.text ?? \"\").join(\"\\n\\n\\n\") ?? \"\";\n if (hasVisibleText(summary)) return summary;\n const reasoning = part.reasoning ?? \"\";\n return hasVisibleText(reasoning) ? reasoning : \"\";\n};\n\nexport const createLangChainStreamingTimingAccessors = <\n TMessage extends {\n id?: string | undefined;\n content?: unknown;\n tool_calls?: readonly unknown[] | undefined;\n },\n>(\n getType: (message: TMessage) => string,\n): StreamingTimingAccessors<TMessage> => {\n const findAiMessage = (\n messages: readonly TMessage[],\n messageId: string,\n ): TMessage | undefined =>\n messages.find(\n (message) => getType(message) === \"ai\" && message.id === messageId,\n );\n\n const getTextLength = (\n messages: readonly TMessage[],\n messageId: string,\n ): number => {\n const message = findAiMessage(messages, messageId);\n if (!message) return 0;\n const content = message.content;\n if (typeof content === \"string\") return content.length;\n if (!Array.isArray(content)) return 0;\n let len = 0;\n for (const part of content as readonly LangChainContentBlock[]) {\n if (typeof part !== \"object\" || part === null) continue;\n switch (part.type) {\n case \"text\":\n case \"text_delta\":\n if (typeof part.text === \"string\") len += part.text.length;\n break;\n case \"thinking\":\n if (hasVisibleText(part.thinking)) len += part.thinking.length;\n break;\n case \"reasoning\":\n len += getReasoningText(part).length;\n break;\n }\n }\n return len;\n };\n\n const getToolCallCount = (\n messages: readonly TMessage[],\n messageId: string,\n ): number => findAiMessage(messages, messageId)?.tool_calls?.length ?? 0;\n\n const getAssistantMessageId = (\n messages: readonly TMessage[],\n ): string | undefined => {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i];\n if (message && getType(message) === \"ai\" && message.id) return message.id;\n }\n return undefined;\n };\n\n return {\n getAssistantMessageId,\n getTextLength,\n getToolCallCount,\n };\n};\n\n/**\n * Resolve the assistant message a `UIMessage` belongs to: the parent id comes\n * from `metadata.message_id` (Python SDK) or `metadata.id` (JS SDK).\n */\nexport const getUIMessageParentId = (ui: {\n metadata?: { message_id?: string; id?: string } | undefined;\n}): string | undefined => ui.metadata?.message_id ?? ui.metadata?.id;\n\n/**\n * Group the graph's accumulated `UIMessage`s by the assistant message they\n * belong to. Non-array state and entries without a parent link are dropped.\n */\nexport const groupUIMessagesByParent = <\n T extends {\n metadata?: { message_id?: string; id?: string } | undefined;\n },\n>(\n value: unknown,\n): Map<string, T[]> => {\n const map = new Map<string, T[]>();\n if (!Array.isArray(value)) return map;\n for (const ui of value as T[]) {\n const parentId = getUIMessageParentId(ui);\n if (!parentId) continue;\n const existing = map.get(parentId);\n if (existing) {\n existing.push(ui);\n } else {\n map.set(parentId, [ui]);\n }\n }\n return map;\n};\n"],"mappings":";;AAwDA,MAAa,gCACX,SAC4C;CAE5C,QADa,KAAK,MAClB;EACE,KAAK;EACL,KAAK,cACH,OAAO;GACL,MAAM;GACN,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;EACpD;EACF,KAAK,aAAa;GAChB,MAAM,QACJ,OAAO,KAAK,cAAc,WACtB,KAAK,YACL,KAAK,WAAW;GACtB,IAAI,CAAC,OAAO,OAAO;GACnB,OAAO;IAAE,MAAM;IAAkB;GAAM;EACzC;EACA,KAAK,QACH,OAAO;GACL,MAAM;GACN,UAAU,KAAK,UAAU,YAAY;GACrC,MACE,KAAK,gBAAgB,QACjB,KAAK,MACL,KAAK,gBAAgB,OACnB,KAAK,KACL,KAAK;GACb,UAAU,KAAK,aAAa;GAC5B,IAAK,KAAK,gBAAgB,SAAS,KAAK,gBAAgB,SAAS,EAC/D,YAAY,KAAK,YACnB;EACF;EACF,KAAK,SAAS;GACZ,MAAM,WAAW,KAAK,aAAa;GACnC,MAAM,UAAU,SAAS,WAAW,QAAQ,IACxC,SAAS,MAAM,CAAe,IAC9B,KAAA;GACJ,OAAO;IACL,MAAM;IACN,UAAU,UAAU,SAAS,YAAY;IACzC,MAAM,KAAK;IACX;GACF;EACF;EACA,KAAK,YACH,OAAO,eAAe,KAAK,QAAQ,IAC/B;GAAE,MAAM;GAAsB,MAAM,KAAK;EAAS,IAClD;EACN,KAAK,aAAa;GAChB,MAAM,OAAO,iBAAiB,IAAI;GAClC,OAAO,OAAO;IAAE,MAAM;IAAsB;GAAK,IAAI;EACvD;EACA,KAAK;EACL,KAAK,oBACH,OAAO;EACT,SACE;CACJ;AACF;AAEA,MAAM,kBAAkB,SACtB,OAAO,SAAS,YAAY,KAAK,KAAK,MAAM;;;;;;;AAQ9C,MAAa,uBACX,OACA,qBACoD;CAEpD,MAAM,cADQ,kBAAkB,MAAA,EACN;CAC1B,IAAI,OAAO,eAAe,YAAY,CAAC,eAAe,UAAU,GAC9D,OAAO;CACT,IAAI,MAAM,MAAM,SAAS,KAAK,SAAS,UAAU,eAAe,KAAK,IAAI,CAAC,GACxE,OAAO;CACT,OAAO,CACL,GAAG,MAAM,QAAQ,SAAS,KAAK,SAAS,MAAM,GAC9C;EAAE,MAAM;EAAiB,MAAM;CAAW,CAC5C;AACF;AAEA,MAAa,qBACX,qBAEC,kBAAkB,YAAwC,CAAC;AAE9D,MAAa,uBAGX,QACqB;CACrB,MAAM;CACN,MAAM,GAAG;CACT,MAAM,GAAG;AACX;;;;;;;AAQA,MAAM,sCAAsB,IAAI,IAAuC;CACrE,CAAC,aAAa,WAAW;CACzB,CAAC,cAAc,WAAW;CAC1B,CAAC,aAAa,WAAW;CACzB,CAAC,cAAc,WAAW;CAC1B,CAAC,eAAe,WAAW;AAC7B,CAAC;AAED,MAAa,qBAAqB,QAAuB;CACvD,MAAM,aAAa,CACjB,GAAG,IAAI,SACP,GAAI,IAAI,aAAa,SAAS,MAAM,EAAE,OAAO,KAAK,CAAC,CACrD;CAEA,MAAM,aAAa,WAAW,MAC3B,SACC,KAAK,SAAS,UAAU,KAAK,SAAS,WAAW,KAAK,SAAS,OACnE;CACA,MAAM,UAAU,WAAW,MAAM,SAAS,KAAK,SAAS,MAAM;CAC9D,IAAI,cAAc,CAAC,SACjB,WAAW,QAAQ;EAAE,MAAM;EAAQ,MAAM;CAAI,CAAC;CAGhD,MAAM,UAAU,WAAW,SAAS,SAAS;EAC3C,MAAM,OAAO,KAAK;EAClB,QAAQ,MAAR;GACE,KAAK,QACH,OAAO;IAAE,MAAM;IAAiB,MAAM,KAAK;GAAK;GAClD,KAAK,SACH,OAAO;IAAE,MAAM;IAAsB,WAAW,EAAE,KAAK,KAAK,MAAM;GAAE;GACtE,KAAK,QAAQ;IACX,MAAM,WAAW,EAAE,UAAU,KAAK,YAAY,OAAO;IACrD,IAAI,KAAK,eAAe,MACtB,OAAO;KACL,MAAM;KACN,IAAI,KAAK;KACT,WAAW,KAAK;KAChB,UAAU,SAAS;KACnB;KACA,aAAa;IACf;IAEF,MAAM,SAAS,sBAAsB,IAAI;IACzC,IAAI,OAAO,SAAS,OAClB,OAAO;KACL,MAAM;KACN,KAAK,OAAO;KACZ,WAAW,KAAK;KAChB,UAAU,SAAS;KACnB;KACA,aAAa;IACf;IAEF,MAAM,gBAAgB,oBAAoB,IACxC,OAAO,SAAS,YAAY,CAC9B;IACA,IAAI,eACF,OAAO;KACL,MAAM;KACN,MAAM,OAAO;KACb,WAAW;KACX,aAAa;IACf;IAEF,OAAO;KACL,MAAM;KACN,MAAM,OAAO;KACb,WAAW,OAAO;KAClB,UAAU,SAAS;KACnB;KACA,aAAa;IACf;GACF;GACA,KAAK,SAEH,OAAO;IACL,MAAM;IACN,MAHa,aAAa,KAAK,MAAM,IAG1B,CAAC,EAAE,QAAQ,KAAK,MAAM;IACjC,WAAW,SAAS,KAAK,MAAM;IAC/B,aAAa;GACf;GAEF,KAAK,QACH,OAAO,CAAC;GACV,KAAK,aACH,MAAM,IAAI,MAAM,sCAAsC;GACxD,SAEE,MAAM,IAAI,MACR,yCAAyCA,MAC3C;EAEJ;CACF,CAAC;CAED,IAAI,QAAQ,WAAW,KAAK,QAAQ,EAAE,EAAE,SAAS,QAC/C,OAAO,QAAQ,EAAE,CAAC,QAAQ;CAE5B,OAAO;AACT;AAEA,MAAM,oBAAoB,SAGZ;CACZ,MAAM,UAAU,KAAK,SAAS,KAAK,MAAM,GAAG,QAAQ,EAAE,CAAC,CAAC,KAAK,QAAQ,KAAK;CAC1E,IAAI,eAAe,OAAO,GAAG,OAAO;CACpC,MAAM,YAAY,KAAK,aAAa;CACpC,OAAO,eAAe,SAAS,IAAI,YAAY;AACjD;AAEA,MAAa,2CAOX,YACuC;CACvC,MAAM,iBACJ,UACA,cAEA,SAAS,MACN,YAAY,QAAQ,OAAO,MAAM,QAAQ,QAAQ,OAAO,SAC3D;CAEF,MAAM,iBACJ,UACA,cACW;EACX,MAAM,UAAU,cAAc,UAAU,SAAS;EACjD,IAAI,CAAC,SAAS,OAAO;EACrB,MAAM,UAAU,QAAQ;EACxB,IAAI,OAAO,YAAY,UAAU,OAAO,QAAQ;EAChD,IAAI,CAAC,MAAM,QAAQ,OAAO,GAAG,OAAO;EACpC,IAAI,MAAM;EACV,KAAK,MAAM,QAAQ,SAA6C;GAC9D,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM;GAC/C,QAAQ,KAAK,MAAb;IACE,KAAK;IACL,KAAK;KACH,IAAI,OAAO,KAAK,SAAS,UAAU,OAAO,KAAK,KAAK;KACpD;IACF,KAAK;KACH,IAAI,eAAe,KAAK,QAAQ,GAAG,OAAO,KAAK,SAAS;KACxD;IACF,KAAK,aACH,OAAO,iBAAiB,IAAI,CAAC,CAAC;GAElC;EACF;EACA,OAAO;CACT;CAEA,MAAM,oBACJ,UACA,cACW,cAAc,UAAU,SAAS,CAAC,EAAE,YAAY,UAAU;CAEvE,MAAM,yBACJ,aACuB;EACvB,KAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;GAC7C,MAAM,UAAU,SAAS;GACzB,IAAI,WAAW,QAAQ,OAAO,MAAM,QAAQ,QAAQ,IAAI,OAAO,QAAQ;EACzE;CAEF;CAEA,OAAO;EACL;EACA;EACA;CACF;AACF;;;;;AAMA,MAAa,wBAAwB,OAEX,GAAG,UAAU,cAAc,GAAG,UAAU;;;;;AAMlE,MAAa,2BAKX,UACqB;CACrB,MAAM,sBAAM,IAAI,IAAiB;CACjC,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO;CAClC,KAAK,MAAM,MAAM,OAAc;EAC7B,MAAM,WAAW,qBAAqB,EAAE;EACxC,IAAI,CAAC,UAAU;EACf,MAAM,WAAW,IAAI,IAAI,QAAQ;EACjC,IAAI,UACF,SAAS,KAAK,EAAE;OAEhB,IAAI,IAAI,UAAU,CAAC,EAAE,CAAC;CAE1B;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"converter.js","names":["_exhaustiveCheck"],"sources":["../src/converter.ts"],"sourcesContent":["import type {\n AppendMessage,\n DataMessagePart,\n MessageModality,\n ThreadAssistantMessage,\n ThreadUserMessage,\n} from \"@assistant-ui/core\";\nimport {\n parseDataUrl,\n resolveFilePartSource,\n} from \"@assistant-ui/core/internal\";\nimport type { StreamingTimingAccessors } from \"@assistant-ui/core/react\";\n\n/** Known content block types from @langchain/core messages. */\nexport type LangChainContentBlock =\n | { type: \"text\"; text: string }\n | { type: \"text_delta\"; text: string }\n | { type: \"image_url\"; image_url: string | { url?: string } }\n | { type: \"thinking\"; thinking: string }\n | {\n type: \"reasoning\";\n summary?: Array<{ type: \"summary_text\"; text?: string }>;\n reasoning?: string;\n }\n | {\n type: \"file\";\n data: string;\n mime_type: string;\n source_type?: \"base64\";\n metadata?: { filename?: string };\n }\n | {\n type: \"file\";\n url: string;\n mime_type?: string;\n source_type: \"url\";\n metadata?: { filename?: string };\n }\n | {\n type: \"file\";\n id: string;\n mime_type?: string;\n source_type: \"id\";\n metadata?: { filename?: string };\n }\n | {\n type: \"audio\";\n data: string;\n mime_type: string;\n source_type: \"base64\";\n }\n | { type: \"tool_use\" | \"input_json_delta\" };\n\ntype ConvertedContentPart =\n | ThreadUserMessage[\"content\"][number]\n | ThreadAssistantMessage[\"content\"][number];\n\nexport const convertLangChainContentBlock = (\n part: LangChainContentBlock,\n): ConvertedContentPart | null | undefined => {\n const type = part.type;\n switch (type) {\n case \"text\":\n case \"text_delta\":\n return {\n type: \"text\" as const,\n text: typeof part.text === \"string\" ? part.text : \"\",\n };\n case \"image_url\": {\n const image =\n typeof part.image_url === \"string\"\n ? part.image_url\n : part.image_url?.url;\n if (!image) return null;\n return { type: \"image\" as const, image };\n }\n case \"file\":\n return {\n type: \"file\" as const,\n filename: part.metadata?.filename ?? \"file\",\n data:\n part.source_type === \"url\"\n ? part.url\n : part.source_type === \"id\"\n ? part.id\n : part.data,\n mimeType: part.mime_type ?? \"application/octet-stream\",\n ...((part.source_type === \"url\" || part.source_type === \"id\") && {\n sourceType: part.source_type,\n }),\n };\n case \"audio\": {\n const mimeType = part.mime_type ?? \"application/octet-stream\";\n const subtype = mimeType.startsWith(\"audio/\")\n ? mimeType.slice(\"audio/\".length)\n : undefined;\n return {\n type: \"file\" as const,\n filename: subtype ? `audio.${subtype}` : \"audio\",\n data: part.data,\n mimeType,\n };\n }\n case \"thinking\":\n return hasVisibleText(part.thinking)\n ? { type: \"reasoning\" as const, text: part.thinking }\n : null;\n case \"reasoning\": {\n const text = getReasoningText(part);\n return text ? { type: \"reasoning\" as const, text } : null;\n }\n case \"tool_use\":\n case \"input_json_delta\":\n return null;\n default:\n return undefined;\n }\n};\n\nconst hasVisibleText = (text: unknown): boolean =>\n typeof text === \"string\" && text.trim() !== \"\";\n\n/**\n * Audio output arrives outside the content array: providers leave `content`\n * empty and put the spoken text in `additional_kwargs.audio.transcript`. The\n * audio bytes stay behind because no provider reports their media type, and a\n * streamed response carries raw PCM rather than a playable file.\n */\nexport const withAudioTranscript = <T extends { type: string; text?: unknown }>(\n parts: readonly T[],\n additionalKwargs: Record<string, unknown> | undefined,\n): readonly (T | { type: \"text\"; text: string })[] => {\n const audio = additionalKwargs?.audio as { transcript?: unknown } | undefined;\n const transcript = audio?.transcript;\n if (typeof transcript !== \"string\" || !hasVisibleText(transcript))\n return parts;\n if (parts.some((part) => part.type === \"text\" && hasVisibleText(part.text)))\n return parts;\n return [\n ...parts.filter((part) => part.type !== \"text\"),\n { type: \"text\" as const, text: transcript },\n ];\n};\n\nexport const getCustomMetadata = (\n additionalKwargs: Record<string, unknown> | undefined,\n): Record<string, unknown> =>\n (additionalKwargs?.metadata as Record<string, unknown>) ?? {};\n\nexport const getMessageModality = (\n additionalKwargs: Record<string, unknown> | undefined,\n): MessageModality | undefined =>\n additionalKwargs?.modality === \"voice\" ? \"voice\" : undefined;\n\nexport const uiMessageToDataPart = <\n TUIMessage extends { name: string; props: Record<string, unknown> },\n>(\n ui: TUIMessage,\n): DataMessagePart => ({\n type: \"data\",\n name: ui.name,\n data: ui.props,\n});\n\n/**\n * Audio media types that reach a provider's audio input through the LangChain\n * `audio` block. langchain-core derives OpenAI's `input_audio.format` by\n * splitting `mime_type` on `/`, and that format is a wav-or-mp3 enum, so\n * `audio/mpeg` passes the converter and is rejected at the provider.\n */\nconst audioBlockMimeTypes = new Map<string, \"audio/mp3\" | \"audio/wav\">([\n [\"audio/mp3\", \"audio/mp3\"],\n [\"audio/mpeg\", \"audio/mp3\"],\n [\"audio/wav\", \"audio/wav\"],\n [\"audio/wave\", \"audio/wav\"],\n [\"audio/x-wav\", \"audio/wav\"],\n]);\n\nexport const getMessageContent = (msg: AppendMessage) => {\n const allContent = [\n ...msg.content,\n ...(msg.attachments?.flatMap((a) => a.content) ?? []),\n ];\n\n const hasNonText = allContent.some(\n (part) =>\n part.type === \"file\" || part.type === \"image\" || part.type === \"audio\",\n );\n const hasText = allContent.some((part) => part.type === \"text\");\n if (hasNonText && !hasText) {\n allContent.unshift({ type: \"text\", text: \" \" });\n }\n\n const content = allContent.flatMap((part) => {\n const type = part.type;\n switch (type) {\n case \"text\":\n return { type: \"text\" as const, text: part.text };\n case \"image\":\n return { type: \"image_url\" as const, image_url: { url: part.image } };\n case \"file\": {\n const metadata = { filename: part.filename ?? \"file\" };\n if (part.sourceType === \"id\") {\n return {\n type: \"file\" as const,\n id: part.data,\n mime_type: part.mimeType,\n filename: metadata.filename,\n metadata,\n source_type: \"id\" as const,\n };\n }\n const source = resolveFilePartSource(part);\n if (source.kind === \"url\") {\n return {\n type: \"file\" as const,\n url: source.url,\n mime_type: part.mimeType,\n filename: metadata.filename,\n metadata,\n source_type: \"url\" as const,\n };\n }\n const audioMimeType = audioBlockMimeTypes.get(\n source.mimeType.toLowerCase(),\n );\n if (audioMimeType) {\n return {\n type: \"audio\" as const,\n data: source.data,\n mime_type: audioMimeType,\n source_type: \"base64\" as const,\n };\n }\n return {\n type: \"file\" as const,\n data: source.data,\n mime_type: source.mimeType,\n filename: metadata.filename,\n metadata,\n source_type: \"base64\" as const,\n };\n }\n case \"audio\": {\n const parsed = parseDataUrl(part.audio.data);\n return {\n type: \"audio\" as const,\n data: parsed?.data ?? part.audio.data,\n mime_type: `audio/${part.audio.format}`,\n source_type: \"base64\" as const,\n };\n }\n case \"data\":\n return [];\n case \"tool-call\":\n throw new Error(\"Tool call appends are not supported.\");\n default: {\n const _exhaustiveCheck: \"reasoning\" | \"source\" | \"generative-ui\" = type;\n throw new Error(\n `Unsupported append message part type: ${_exhaustiveCheck}`,\n );\n }\n }\n });\n\n if (content.length === 1 && content[0]?.type === \"text\") {\n return content[0].text ?? \"\";\n }\n return content;\n};\n\nconst getReasoningText = (part: {\n readonly summary?: ReadonlyArray<{ readonly text?: string }>;\n readonly reasoning?: string;\n}): string => {\n const summary = part.summary?.map((s) => s?.text ?? \"\").join(\"\\n\\n\\n\") ?? \"\";\n if (hasVisibleText(summary)) return summary;\n const reasoning = part.reasoning ?? \"\";\n return hasVisibleText(reasoning) ? reasoning : \"\";\n};\n\nexport const createLangChainStreamingTimingAccessors = <\n TMessage extends {\n id?: string | undefined;\n content?: unknown;\n tool_calls?: readonly unknown[] | undefined;\n },\n>(\n getType: (message: TMessage) => string,\n): StreamingTimingAccessors<TMessage> => {\n const findAiMessage = (\n messages: readonly TMessage[],\n messageId: string,\n ): TMessage | undefined =>\n messages.find(\n (message) => getType(message) === \"ai\" && message.id === messageId,\n );\n\n const getTextLength = (\n messages: readonly TMessage[],\n messageId: string,\n ): number => {\n const message = findAiMessage(messages, messageId);\n if (!message) return 0;\n const content = message.content;\n if (typeof content === \"string\") return content.length;\n if (!Array.isArray(content)) return 0;\n let len = 0;\n for (const part of content as readonly LangChainContentBlock[]) {\n if (typeof part !== \"object\" || part === null) continue;\n switch (part.type) {\n case \"text\":\n case \"text_delta\":\n if (typeof part.text === \"string\") len += part.text.length;\n break;\n case \"thinking\":\n if (hasVisibleText(part.thinking)) len += part.thinking.length;\n break;\n case \"reasoning\":\n len += getReasoningText(part).length;\n break;\n }\n }\n return len;\n };\n\n const getToolCallCount = (\n messages: readonly TMessage[],\n messageId: string,\n ): number => findAiMessage(messages, messageId)?.tool_calls?.length ?? 0;\n\n const getAssistantMessageId = (\n messages: readonly TMessage[],\n ): string | undefined => {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i];\n if (message && getType(message) === \"ai\" && message.id) return message.id;\n }\n return undefined;\n };\n\n return {\n getAssistantMessageId,\n getTextLength,\n getToolCallCount,\n };\n};\n\n/**\n * Resolve the assistant message a `UIMessage` belongs to: the parent id comes\n * from `metadata.message_id` (Python SDK) or `metadata.id` (JS SDK).\n */\nexport const getUIMessageParentId = (ui: {\n metadata?: { message_id?: string; id?: string } | undefined;\n}): string | undefined => ui.metadata?.message_id ?? ui.metadata?.id;\n\n/**\n * Group the graph's accumulated `UIMessage`s by the assistant message they\n * belong to. Non-array state and entries without a parent link are dropped.\n */\nexport const groupUIMessagesByParent = <\n T extends {\n metadata?: { message_id?: string; id?: string } | undefined;\n },\n>(\n value: unknown,\n): Map<string, T[]> => {\n const map = new Map<string, T[]>();\n if (!Array.isArray(value)) return map;\n for (const ui of value as T[]) {\n const parentId = getUIMessageParentId(ui);\n if (!parentId) continue;\n const existing = map.get(parentId);\n if (existing) {\n existing.push(ui);\n } else {\n map.set(parentId, [ui]);\n }\n }\n return map;\n};\n"],"mappings":"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"}
@@ -1,25 +1,23 @@
1
- import { LangChainBaseMessage } from "./types.js";
2
- //#region src/findForkCheckpointInHistory.d.ts
1
+ import type { LangChainBaseMessage } from "./types.js";
3
2
  type ForkCheckpointHistoryState = {
4
- values?: Record<string, unknown> | undefined;
5
- checkpoint?: {
6
- checkpoint_id?: string | null | undefined;
7
- } | undefined;
3
+ values?: Record<string, unknown> | undefined;
4
+ checkpoint?: {
5
+ checkpoint_id?: string | null | undefined;
6
+ } | undefined;
8
7
  };
9
8
  type ForkHistoryCursor = {
10
- configurable: {
11
- checkpoint_id: string;
12
- };
9
+ configurable: {
10
+ checkpoint_id: string;
11
+ };
13
12
  };
14
- type ForkCheckpointClient = {
15
- threads: {
16
- getHistory: (threadId: string, options?: {
17
- limit?: number;
18
- before?: ForkHistoryCursor;
19
- }) => Promise<readonly ForkCheckpointHistoryState[]>;
20
- };
13
+ export type ForkCheckpointClient = {
14
+ threads: {
15
+ getHistory: (threadId: string, options?: {
16
+ limit?: number;
17
+ before?: ForkHistoryCursor;
18
+ }) => Promise<readonly ForkCheckpointHistoryState[]>;
19
+ };
21
20
  };
22
- declare const findForkCheckpointInHistory: (client: ForkCheckpointClient, threadId: string, messagesUpToParent: readonly LangChainBaseMessage[], messagesKey: string, pageSize?: number) => Promise<string | null>;
23
- //#endregion
24
- export { ForkCheckpointClient, findForkCheckpointInHistory };
21
+ export declare const findForkCheckpointInHistory: (client: ForkCheckpointClient, threadId: string, messagesUpToParent: readonly LangChainBaseMessage[], messagesKey: string, pageSize?: number) => Promise<string | null>;
22
+ export {};
25
23
  //# sourceMappingURL=findForkCheckpointInHistory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"findForkCheckpointInHistory.d.ts","names":[],"sources":["../src/findForkCheckpointInHistory.ts"],"mappings":";;KAEK;EACH,SAAS;EACT;IAAe;;;KAGZ;EAAsB;IAAgB;;;KAE/B;EACV;IACE,aACE,kBACA;MAAY;MAAgB,SAAS;UAClC,iBAAiB;;;cAIb,8BACX,QAAQ,sBACR,kBACA,6BAA6B,wBAC7B,qBACA,sBACC"}
1
+ {"version":3,"file":"findForkCheckpointInHistory.d.ts","sourceRoot":"","sources":["../src/findForkCheckpointInHistory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAgB;AAEpD,KAAK,0BAA0B,GAAG;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC7C,UAAU,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;CACxE,CAAC;AAEF,KAAK,iBAAiB,GAAG;IAAE,YAAY,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAErE,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE;QACP,UAAU,EAAE,CACV,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;SAAE,KACrD,OAAO,CAAC,SAAS,0BAA0B,EAAE,CAAC,CAAC;KACrD,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,QAAQ,oBAAoB,EAC5B,UAAU,MAAM,EAChB,oBAAoB,SAAS,oBAAoB,EAAE,EACnD,aAAa,MAAM,EACnB,iBAAc,KACb,OAAO,CAAC,MAAM,GAAG,IAAI,CA2CvB,CAAC"}
package/dist/hooks.d.ts CHANGED
@@ -1,66 +1,65 @@
1
- import { LangChainBaseMessage } from "./types.js";
2
- import { AssembledToolCall, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot } from "@langchain/react";
3
- //#region src/hooks.d.ts
1
+ import type { AssembledToolCall, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot } from "@langchain/react";
2
+ import type { LangChainBaseMessage } from "./types.js";
4
3
  /**
5
4
  * Read the current LangGraph interrupt state from the runtime extras.
6
5
  */
7
- declare const useLangChainInterruptState: () => {
8
- value?: unknown;
6
+ export declare const useLangChainInterruptState: () => {
7
+ value?: unknown;
9
8
  } | undefined;
10
9
  /**
11
10
  * Read every interrupt pending at the current checkpoint, each with `id`
12
11
  * and `value`. Defaults to an empty array. Pair with `useLangChainRespondAll`
13
12
  * (keyed by interrupt id) to resolve several at once.
14
13
  */
15
- declare const useLangChainInterrupts: () => readonly {
16
- id?: string;
17
- value?: unknown;
14
+ export declare const useLangChainInterrupts: () => readonly {
15
+ id?: string;
16
+ value?: unknown;
18
17
  }[];
19
18
  /** Read the last run/hydration error from the runtime extras. */
20
- declare const useLangChainError: () => unknown;
19
+ export declare const useLangChainError: () => unknown;
21
20
  /**
22
21
  * Read the root tool calls assembled by `useStream` from the `tools`
23
22
  * channel. Defaults to an empty array, so consumers can `.map` without
24
23
  * a guard. Useful for rendering pending/streamed tool calls and
25
24
  * approval UIs.
26
25
  */
27
- declare const useLangChainToolCalls: () => readonly AssembledToolCall<string, unknown, unknown>[];
26
+ export declare const useLangChainToolCalls: () => readonly AssembledToolCall<string, unknown, unknown>[];
28
27
  /** Subagents discovered on the current run (multi-agent graphs). */
29
- declare const useLangChainSubagents: () => ReadonlyMap<string, SubagentDiscoverySnapshot>;
28
+ export declare const useLangChainSubagents: () => ReadonlyMap<string, SubagentDiscoverySnapshot>;
30
29
  /** Subgraphs discovered on the current run. */
31
- declare const useLangChainSubgraphs: () => ReadonlyMap<string, SubgraphDiscoverySnapshot>;
30
+ export declare const useLangChainSubgraphs: () => ReadonlyMap<string, SubgraphDiscoverySnapshot>;
32
31
  /**
33
32
  * The underlying `useStream` handle, for advanced views — pass it to v1's
34
33
  * `useMessages(stream, target)` / `useToolCalls(stream, target)` with a
35
34
  * subagent/subgraph from `useLangChainSubagents` / `useLangChainSubgraphs`.
36
35
  * `undefined` outside the runtime provider.
37
36
  */
38
- declare const useLangChainStream: () => import("@langchain/react").AnyStream | undefined;
37
+ export declare const useLangChainStream: () => import("@langchain/react").AnyStream | undefined;
39
38
  /**
40
39
  * Returns a function to submit raw state updates to the LangGraph agent,
41
40
  * bypassing the normal message flow. Useful for sending interrupt resume
42
41
  * commands.
43
42
  */
44
- declare const useLangChainSubmit: () => (values: Record<string, unknown> | null | undefined, options?: Record<string, unknown>) => Promise<void>;
43
+ export declare const useLangChainSubmit: () => (values: Record<string, unknown> | null | undefined, options?: Record<string, unknown>) => Promise<void>;
45
44
  /**
46
45
  * Resume a LangGraph interrupt with a response payload via
47
46
  * `useStream().respond`. Preferred over `useLangChainSendCommand`; it
48
47
  * carries the response cleanly and handles interrupt namespaces.
49
48
  */
50
- declare const useLangChainRespond: () => (response: unknown, options?: Record<string, unknown>) => Promise<void>;
49
+ export declare const useLangChainRespond: () => (response: unknown, options?: Record<string, unknown>) => Promise<void>;
51
50
  /**
52
51
  * Resume several LangGraph interrupts pending at the same checkpoint in
53
52
  * one run via `useStream().respondAll`. Use when a run pauses on multiple
54
53
  * interrupts at once; sequential `useLangChainRespond` calls can't service
55
54
  * them (the first resume starts a run, stranding the rest).
56
55
  */
57
- declare const useLangChainRespondAll: () => (responsesById: Record<string, unknown>, options?: Record<string, unknown>) => Promise<void>;
56
+ export declare const useLangChainRespondAll: () => (responsesById: Record<string, unknown>, options?: Record<string, unknown>) => Promise<void>;
58
57
  /**
59
58
  * Submit a list of LangChain-shaped messages on the current thread.
60
59
  * Parity helper for migrating from `useLangGraphSend`. Routes to
61
60
  * `useStream().submit({ [messagesKey]: messages }, options)`.
62
61
  */
63
- declare const useLangChainSend: () => (messages: readonly LangChainBaseMessage[], options?: Record<string, unknown>) => Promise<void>;
62
+ export declare const useLangChainSend: () => (messages: readonly LangChainBaseMessage[], options?: Record<string, unknown>) => Promise<void>;
64
63
  /**
65
64
  * Submit a `useStream` command (e.g. interrupt resume). Parity helper
66
65
  * for migrating from `useLangGraphSendCommand`. Note that v1's command
@@ -68,7 +67,7 @@ declare const useLangChainSend: () => (messages: readonly LangChainBaseMessage[]
68
67
  * `{ resume: string }` form; to carry a payload, use the input or
69
68
  * `stream.respond` instead.
70
69
  */
71
- declare const useLangChainSendCommand: () => (command: Record<string, unknown>) => Promise<void>;
70
+ export declare const useLangChainSendCommand: () => (command: Record<string, unknown>) => Promise<void>;
72
71
  /**
73
72
  * Read a custom LangGraph state key from the current thread. Mirrors
74
73
  * `useStream().values[key]` from `@langchain/react` and updates when the
@@ -80,8 +79,6 @@ declare const useLangChainSendCommand: () => (command: Record<string, unknown>)
80
79
  * const files = useLangChainState<Record<string, string>>("files", {});
81
80
  * ```
82
81
  */
83
- declare function useLangChainState<T>(key: string): T | undefined;
84
- declare function useLangChainState<T>(key: string, defaultValue: T): T;
85
- //#endregion
86
- export { useLangChainError, useLangChainInterruptState, useLangChainInterrupts, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls };
82
+ export declare function useLangChainState<T>(key: string): T | undefined;
83
+ export declare function useLangChainState<T>(key: string, defaultValue: T): T;
87
84
  //# sourceMappingURL=hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","names":[],"sources":["../src/hooks.ts"],"mappings":";;;;;;cAwBa;EAAA;;;;;;;cAQA;EAAA;EAAA;;;cAOA;;;;;;;cASA,sCAAqB;;cAIrB,6BAAqB,oBAAA;;cAIrB,6BAAqB,oBAAA;;;;;;;cASrB,qDAAkB;;;;;;cAQlB,2BAGT,QAAQ,4CACR,UAAU,4BAAuB;;;;;;cASxB,4BAEH,mBAAmB,UAAU,4BAAuB;;;;;;;cAUjD,+BAGT,eAAe,yBACf,UAAU,4BAAuB;;;;;;cASxB,yBAGT,mBAAmB,wBACnB,UAAU,4BAAuB;;;;;;;;cAcxB,gCAEH,SAAS,4BAAuB;;;;;;;;;;;;iBAc1B,kBAAkB,GAAG,cAAc;iBACnC,kBAAkB,GAAG,aAAa,cAAc,IAAI"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EACjB,yBAAyB,EACzB,yBAAyB,EAC1B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAgB;AAYpD;;GAEG;AACH,eAAO,MAAM,0BAA0B;;aACa,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;GAIhC,CAAC;AAEJ,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,eACkB,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,8DAC6C,CAAC;AAEhF,oEAAoE;AACpE,eAAO,MAAM,qBAAqB,sDAC2C,CAAC;AAE9E,+CAA+C;AAC/C,eAAO,MAAM,qBAAqB,sDAC2C,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,wDACkB,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,SAG3B,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAClD,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBAEpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,SAEtB,UAAU,OAAO,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBAE7D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,SAG/B,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBAEpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,SAGzB,UAAU,SAAS,oBAAoB,EAAE,EACzC,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBAKpC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,SAE1B,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,kBACzC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;AACjE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { LangChainContentBlock } from "./converter.js";
2
- import { LangChainBaseMessage, LangChainToolCall, RemoveUIMessage, UIMessage, UseStreamRuntimeOptions } from "./types.js";
3
- import { convertLangChainBaseMessage } from "./convertMessages.js";
4
- import { useLangChainError, useLangChainInterruptState, useLangChainInterrupts, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls } from "./hooks.js";
5
- import { useStreamRuntime } from "./useStreamRuntime.js";
6
- import { useLangChainStreamingTiming } from "./streamingTiming.js";
7
- import { SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot } from "@langchain/react";
8
- export { type LangChainBaseMessage, type LangChainContentBlock, type LangChainToolCall, type RemoveUIMessage, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type UIMessage, type UseStreamRuntimeOptions, convertLangChainBaseMessage, useLangChainError, useLangChainInterruptState, useLangChainInterrupts, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainStreamingTiming, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls, useStreamRuntime };
1
+ export { useStreamRuntime } from "./useStreamRuntime.js";
2
+ export { useLangChainError, useLangChainInterrupts, useLangChainInterruptState, useLangChainRespond, useLangChainRespondAll, useLangChainSend, useLangChainSendCommand, useLangChainState, useLangChainStream, useLangChainSubagents, useLangChainSubgraphs, useLangChainSubmit, useLangChainToolCalls, } from "./hooks.js";
3
+ export { convertLangChainBaseMessage } from "./convertMessages.js";
4
+ export { useLangChainStreamingTiming } from "./streamingTiming.js";
5
+ export type { SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, } from "@langchain/react";
6
+ export type { LangChainBaseMessage, LangChainContentBlock, LangChainToolCall, RemoveUIMessage, UIMessage, UseStreamRuntimeOptions, } from "./types.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,8BAA2B;AAEtD,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,0BAA0B,EAC1B,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,GACtB,mBAAgB;AAEjB,OAAO,EAAE,2BAA2B,EAAE,6BAA0B;AAChE,OAAO,EAAE,2BAA2B,EAAE,6BAA0B;AAEhE,YAAY,EACV,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,uBAAuB,GACxB,mBAAgB"}
@@ -1,8 +1,7 @@
1
- import { LangChainBaseMessage } from "./types.js";
2
- import { ForkCheckpointClient } from "./findForkCheckpointInHistory.js";
3
- //#region src/resolveForkCheckpoint.d.ts
1
+ import type { LangChainBaseMessage } from "./types.js";
2
+ import { type ForkCheckpointClient } from "./findForkCheckpointInHistory.js";
4
3
  type MessageMetadataSnapshot = ReadonlyMap<string, {
5
- readonly parentCheckpointId: string | undefined;
4
+ readonly parentCheckpointId: string | undefined;
6
5
  }> | undefined;
7
6
  /**
8
7
  * Hydration seeds every message with the head's parent checkpoint, so only the
@@ -10,7 +9,6 @@ type MessageMetadataSnapshot = ReadonlyMap<string, {
10
9
  * server history by message id. A `null` `parentId` edits the first human
11
10
  * message and forks from the thread's initial (empty-message) checkpoint.
12
11
  */
13
- declare const resolveForkCheckpoint: (client: ForkCheckpointClient, threadId: string, messages: readonly LangChainBaseMessage[], parentId: string | null, sourceId: string | null | undefined, metadata: MessageMetadataSnapshot, messagesKey: string) => Promise<string | null>;
14
- //#endregion
15
- export { resolveForkCheckpoint };
12
+ export declare const resolveForkCheckpoint: (client: ForkCheckpointClient, threadId: string, messages: readonly LangChainBaseMessage[], parentId: string | null, sourceId: string | null | undefined, metadata: MessageMetadataSnapshot, messagesKey: string) => Promise<string | null>;
13
+ export {};
16
14
  //# sourceMappingURL=resolveForkCheckpoint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolveForkCheckpoint.d.ts","names":[],"sources":["../src/resolveForkCheckpoint.ts"],"mappings":";;;KAMK,0BACD;WAA+B;;;;;;;;cAStB,wBACX,QAAQ,sBACR,kBACA,mBAAmB,wBACnB,yBACA,qCACA,UAAU,yBACV,wBACC"}
1
+ {"version":3,"file":"resolveForkCheckpoint.d.ts","sourceRoot":"","sources":["../src/resolveForkCheckpoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAgB;AACpD,OAAO,EAEL,KAAK,oBAAoB,EAC1B,yCAAsC;AAEvC,KAAK,uBAAuB,GACxB,WAAW,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC,GACxE,SAAS,CAAC;AAEd;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,oBAAoB,EAC5B,UAAU,MAAM,EAChB,UAAU,SAAS,oBAAoB,EAAE,EACzC,UAAU,MAAM,GAAG,IAAI,EACvB,UAAU,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,UAAU,uBAAuB,EACjC,aAAa,MAAM,KAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAwBvB,CAAC"}
@@ -1,6 +1,3 @@
1
- import { LangChainRuntimeExtras } from "./types.js";
2
- //#region src/runtimeExtras.d.ts
3
- declare const langChainExtras: import("@assistant-ui/core/react").RuntimeExtras<LangChainRuntimeExtras>;
4
- //#endregion
5
- export { langChainExtras };
1
+ import type { LangChainRuntimeExtras } from "./types.js";
2
+ export declare const langChainExtras: import("@assistant-ui/core/react").RuntimeExtras<LangChainRuntimeExtras>;
6
3
  //# sourceMappingURL=runtimeExtras.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtimeExtras.d.ts","names":[],"sources":["../src/runtimeExtras.ts"],"mappings":";;cAGa,oDAAe,cAAA"}
1
+ {"version":3,"file":"runtimeExtras.d.ts","sourceRoot":"","sources":["../src/runtimeExtras.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,mBAAgB;AAEtD,eAAO,MAAM,eAAe,0EACqC,CAAC"}
@@ -1,6 +1,3 @@
1
- import { SdkIdentity } from "assistant-cloud";
2
- //#region src/sdkIdentity.d.ts
3
- declare const LANGCHAIN_SDK: SdkIdentity;
4
- //#endregion
5
- export { LANGCHAIN_SDK };
1
+ import type { SdkIdentity } from "assistant-cloud";
2
+ export declare const LANGCHAIN_SDK: SdkIdentity;
6
3
  //# sourceMappingURL=sdkIdentity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sdkIdentity.d.ts","names":[],"sources":["../src/sdkIdentity.ts"],"mappings":";;cAEa,eAAe"}
1
+ {"version":3,"file":"sdkIdentity.d.ts","sourceRoot":"","sources":["../src/sdkIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,eAAO,MAAM,aAAa,EAAE,WAM3B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  //#region src/sdkIdentity.ts
2
2
  const LANGCHAIN_SDK = {
3
3
  name: "@assistant-ui/react-langchain",
4
- version: "0.0.31"
4
+ version: "0.0.33"
5
5
  };
6
6
  //#endregion
7
7
  export { LANGCHAIN_SDK };
@@ -1,14 +1,11 @@
1
- import { LangChainBaseMessage } from "./types.js";
2
- import { MessageTiming } from "@assistant-ui/core";
3
- //#region src/streamingTiming.d.ts
4
- declare const langChainStreamingTimingAccessors: import("@assistant-ui/core").StreamingTimingAccessors<LangChainBaseMessage>;
1
+ import type { MessageTiming } from "@assistant-ui/core";
2
+ import type { LangChainBaseMessage } from "./types.js";
3
+ export declare const langChainStreamingTimingAccessors: import("@assistant-ui/core").StreamingTimingAccessors<LangChainBaseMessage>;
5
4
  /**
6
5
  * Tracks per-message streaming timing for LangChain messages. Delegates to
7
6
  * the shared `useStreamingTiming` primitive in `@assistant-ui/core/react`,
8
7
  * adapted to the `LangChainBaseMessage` shape (`_getType() -> "ai"`, content
9
8
  * blocks including text/thinking/reasoning, `tool_calls`).
10
9
  */
11
- declare const useLangChainStreamingTiming: (messages: readonly LangChainBaseMessage[], isRunning: boolean) => Record<string, MessageTiming>;
12
- //#endregion
13
- export { langChainStreamingTimingAccessors, useLangChainStreamingTiming };
10
+ export declare const useLangChainStreamingTiming: (messages: readonly LangChainBaseMessage[], isRunning: boolean) => Record<string, MessageTiming>;
14
11
  //# sourceMappingURL=streamingTiming.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"streamingTiming.d.ts","names":[],"sources":["../src/streamingTiming.ts"],"mappings":";;;cAQa,gEAAiC,yBAAA;;;;;;;cASjC,8BACX,mBAAmB,wBACnB,uBACC,eAAe"}
1
+ {"version":3,"file":"streamingTiming.d.ts","sourceRoot":"","sources":["../src/streamingTiming.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAgB;AAEpD,eAAO,MAAM,iCAAiC,6EACiC,CAAC;AAEhF;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,GACtC,UAAU,SAAS,oBAAoB,EAAE,EACzC,WAAW,OAAO,KACjB,MAAM,CAAC,MAAM,EAAE,aAAa,CAC6C,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { BaseMessage } from "@langchain/core/messages";
2
+ import { type ProjectionSpec } from "@langchain/langgraph-sdk/stream";
3
+ type MessagesProjection = ProjectionSpec<BaseMessage[]>;
4
+ /**
5
+ * The SDK's messages projection subscribes at the protocol's default depth
6
+ * of 1 and applies every delivered event, so a nested subagent's `values`
7
+ * snapshots rebuild its parent's store from the child's state while the child
8
+ * runs. The projection exposes no depth option, so this spec opens it against
9
+ * a thread whose subscription is pinned to depth 0: the namespace the SDK
10
+ * sets stays and only events at exactly that namespace are delivered, the
11
+ * rule the SDK's root projection already applies. The client unions every
12
+ * subscription's depth into the server filter, so a depth 0 subscription
13
+ * narrows nothing for other consumers.
14
+ */
15
+ export declare const subagentMessagesProjection: (namespace: readonly string[]) => MessagesProjection;
16
+ export {};
17
+ //# sourceMappingURL=subagentMessagesProjection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagentMessagesProjection.d.ts","sourceRoot":"","sources":["../src/subagentMessagesProjection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,iCAAiC,CAAC;AAEzC,KAAK,kBAAkB,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;AAgBxD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B,GACrC,WAAW,SAAS,MAAM,EAAE,KAC3B,kBAcF,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { messagesProjection } from "@langchain/langgraph-sdk/stream";
2
+ //#region src/subagentMessagesProjection.ts
3
+ const exactDepthThread = (thread) => new Proxy(thread, { get(target, property) {
4
+ if (property === "subscribe") return (...[params]) => target.subscribe({
5
+ ...params,
6
+ depth: 0
7
+ });
8
+ const value = Reflect.get(target, property, target);
9
+ return typeof value === "function" ? value.bind(target) : value;
10
+ } });
11
+ /**
12
+ * The SDK's messages projection subscribes at the protocol's default depth
13
+ * of 1 and applies every delivered event, so a nested subagent's `values`
14
+ * snapshots rebuild its parent's store from the child's state while the child
15
+ * runs. The projection exposes no depth option, so this spec opens it against
16
+ * a thread whose subscription is pinned to depth 0: the namespace the SDK
17
+ * sets stays and only events at exactly that namespace are delivered, the
18
+ * rule the SDK's root projection already applies. The client unions every
19
+ * subscription's depth into the server filter, so a depth 0 subscription
20
+ * narrows nothing for other consumers.
21
+ */
22
+ const subagentMessagesProjection = (namespace) => {
23
+ const projection = messagesProjection(namespace);
24
+ return {
25
+ key: `exact|${projection.key}`,
26
+ namespace: projection.namespace,
27
+ initial: projection.initial,
28
+ open({ thread, store, rootBus }) {
29
+ return projection.open({
30
+ thread: exactDepthThread(thread),
31
+ store,
32
+ rootBus
33
+ });
34
+ }
35
+ };
36
+ };
37
+ //#endregion
38
+ export { subagentMessagesProjection };
39
+
40
+ //# sourceMappingURL=subagentMessagesProjection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagentMessagesProjection.js","names":[],"sources":["../src/subagentMessagesProjection.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n messagesProjection,\n type ProjectionSpec,\n} from \"@langchain/langgraph-sdk/stream\";\n\ntype MessagesProjection = ProjectionSpec<BaseMessage[]>;\n\ntype ProjectionThread = Parameters<MessagesProjection[\"open\"]>[0][\"thread\"];\n\nconst exactDepthThread = (thread: ProjectionThread): ProjectionThread =>\n new Proxy(thread, {\n get(target, property) {\n if (property === \"subscribe\") {\n return (...[params]: Parameters<ProjectionThread[\"subscribe\"]>) =>\n target.subscribe({ ...params, depth: 0 });\n }\n const value = Reflect.get(target, property, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n });\n\n/**\n * The SDK's messages projection subscribes at the protocol's default depth\n * of 1 and applies every delivered event, so a nested subagent's `values`\n * snapshots rebuild its parent's store from the child's state while the child\n * runs. The projection exposes no depth option, so this spec opens it against\n * a thread whose subscription is pinned to depth 0: the namespace the SDK\n * sets stays and only events at exactly that namespace are delivered, the\n * rule the SDK's root projection already applies. The client unions every\n * subscription's depth into the server filter, so a depth 0 subscription\n * narrows nothing for other consumers.\n */\nexport const subagentMessagesProjection = (\n namespace: readonly string[],\n): MessagesProjection => {\n const projection = messagesProjection(namespace);\n return {\n key: `exact|${projection.key}`,\n namespace: projection.namespace,\n initial: projection.initial,\n open({ thread, store, rootBus }) {\n return projection.open({\n thread: exactDepthThread(thread),\n store,\n rootBus,\n });\n },\n };\n};\n"],"mappings":";;AAUA,MAAM,oBAAoB,WACxB,IAAI,MAAM,QAAQ,EAChB,IAAI,QAAQ,UAAU;CACpB,IAAI,aAAa,aACf,QAAQ,GAAG,CAAC,YACV,OAAO,UAAU;EAAE,GAAG;EAAQ,OAAO;CAAE,CAAC;CAE5C,MAAM,QAAQ,QAAQ,IAAI,QAAQ,UAAU,MAAM;CAClD,OAAO,OAAO,UAAU,aAAa,MAAM,KAAK,MAAM,IAAI;AAC5D,EACF,CAAC;;;;;;;;;;;;AAaH,MAAa,8BACX,cACuB;CACvB,MAAM,aAAa,mBAAmB,SAAS;CAC/C,OAAO;EACL,KAAK,SAAS,WAAW;EACzB,WAAW,WAAW;EACtB,SAAS,WAAW;EACpB,KAAK,EAAE,QAAQ,OAAO,WAAW;GAC/B,OAAO,WAAW,KAAK;IACrB,QAAQ,iBAAiB,MAAM;IAC/B;IACA;GACF,CAAC;EACH;CACF;AACF"}