@mgamadeus/ddd-agents 0.1.0-alpha.22 → 0.1.0-alpha.23

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 (143) hide show
  1. package/README.md +3 -2
  2. package/dist/chat.js +22 -72
  3. package/dist/chat.js.map +1 -1
  4. package/dist/chunks/{ConversationMarkdown-W7NHglmL.js → ConversationMarkdown-CJhAnuVa.js} +110 -8
  5. package/dist/chunks/ConversationMarkdown-CJhAnuVa.js.map +1 -0
  6. package/dist/chunks/{WebSearchResultsConversationWidget-BvnLWHyi.js → WebSearchResultsConversationWidget-DRBQvycE.js} +140 -1125
  7. package/dist/chunks/WebSearchResultsConversationWidget-DRBQvycE.js.map +1 -0
  8. package/dist/chunks/{canvasBodies-9SuF6NAB.js → canvasBodies-DLjDkviP.js} +9 -6
  9. package/dist/chunks/canvasBodies-DLjDkviP.js.map +1 -0
  10. package/dist/chunks/{canvas-behaviours-BRFR1ALE.js → decide-canvas-open-DBWoWtAC.js} +18 -2
  11. package/dist/chunks/decide-canvas-open-DBWoWtAC.js.map +1 -0
  12. package/dist/chunks/entity-detail-name-3A82gDAp.js +15 -0
  13. package/dist/chunks/entity-detail-name-3A82gDAp.js.map +1 -0
  14. package/dist/chunks/icon-names-Di6c4zLo.js +86 -0
  15. package/dist/chunks/icon-names-Di6c4zLo.js.map +1 -0
  16. package/dist/chunks/index-7Qc_3GbG.js +1046 -0
  17. package/dist/chunks/index-7Qc_3GbG.js.map +1 -0
  18. package/dist/chunks/{widget-image-readiness-signal-DeOuL89j.js → widget-image-readiness-signal-D3ci53xr.js} +2 -2
  19. package/dist/chunks/{widget-image-readiness-signal-DeOuL89j.js.map → widget-image-readiness-signal-D3ci53xr.js.map} +1 -1
  20. package/dist/chunks/{widget-name-resolver-DyIY6Zu4.js → widget-name-resolver-C8SfpiR5.js} +48 -116
  21. package/dist/chunks/widget-name-resolver-C8SfpiR5.js.map +1 -0
  22. package/dist/client-testing.js +68 -1
  23. package/dist/client-testing.js.map +1 -1
  24. package/dist/files/chat/Conversation.module.scss +268 -0
  25. package/dist/files/chat/ConversationViewBody/ConversationViewBody.module.scss +336 -0
  26. package/dist/files/chat/_conversation-tokens.scss +37 -0
  27. package/dist/files/image-render/WidgetImageRender.module.scss +22 -0
  28. package/dist/files/kit/ComposedViewConversationWidget.md +59 -0
  29. package/dist/files/kit/components/data/data.preview-fixtures.json +3298 -0
  30. package/dist/files/kit/components/embedding/widget.preview-fixtures.json +147 -0
  31. package/dist/files/kit/components/entity/entity-link.preview-fixtures.json +340 -0
  32. package/dist/files/kit/components/form/form.preview-fixtures.json +319 -0
  33. package/dist/files/kit/components/inputs/button.preview-fixtures.json +301 -0
  34. package/dist/files/kit/components/inputs/checkbox.preview-fixtures.json +35 -0
  35. package/dist/files/kit/components/inputs/date-picker.preview-fixtures.json +36 -0
  36. package/dist/files/kit/components/inputs/input.preview-fixtures.json +55 -0
  37. package/dist/files/kit/components/inputs/radio-group.preview-fixtures.json +76 -0
  38. package/dist/files/kit/components/inputs/select.preview-fixtures.json +314 -0
  39. package/dist/files/kit/components/inputs/slider.preview-fixtures.json +178 -0
  40. package/dist/files/kit/components/inputs/tabs.preview-fixtures.json +304 -0
  41. package/dist/files/kit/components/inputs/textarea.preview-fixtures.json +37 -0
  42. package/dist/files/kit/components/layout/layout.preview-fixtures.json +892 -0
  43. package/dist/files/kit/components/map/map.preview-fixtures.json +339 -0
  44. package/dist/files/kit/components/media/image-group.preview-fixtures.json +228 -0
  45. package/dist/files/kit/components/media/image.preview-fixtures.json +61 -0
  46. package/dist/files/kit/components/media/video-card/video-card.preview-fixtures.json +121 -0
  47. package/dist/files/kit/components/media/video.preview-fixtures.json +68 -0
  48. package/dist/files/kit/components/rich/code.preview-fixtures.json +105 -0
  49. package/dist/files/kit/components/rich/diagram.preview-fixtures.json +89 -0
  50. package/dist/files/kit/components/rich/math.preview-fixtures.json +152 -0
  51. package/dist/files/kit/components/rich/svg.preview-fixtures.json +243 -0
  52. package/dist/files/kit/components/text/badge.preview-fixtures.json +44 -0
  53. package/dist/files/kit/components/text/caption.preview-fixtures.json +31 -0
  54. package/dist/files/kit/components/text/favicon.preview-fixtures.json +69 -0
  55. package/dist/files/kit/components/text/label.preview-fixtures.json +48 -0
  56. package/dist/files/kit/components/text/link.preview-fixtures.json +103 -0
  57. package/dist/files/kit/components/text/markdown.preview-fixtures.json +29 -0
  58. package/dist/files/kit/components/text/source-ref.preview-fixtures.json +51 -0
  59. package/dist/files/kit/components/text/text.preview-fixtures.json +106 -0
  60. package/dist/files/kit/components/text/title.preview-fixtures.json +172 -0
  61. package/dist/files/kit/composed-view-widget-contract.json +88 -0
  62. package/dist/files/kit/composed-view.preview-fixtures.json +376 -0
  63. package/dist/files/renderer/conversation-widget-layout.module.scss +47 -0
  64. package/dist/files/renderer/widget-tree/composed-node-schema.json +3428 -0
  65. package/dist/files/styles/_conversation-widget-container.scss +6 -0
  66. package/dist/files/styles/_media.scss +50 -0
  67. package/dist/files/styles/_spacings.scss +23 -0
  68. package/dist/files/styles/_surfaces.scss +28 -0
  69. package/dist/files/widgets/ClockConversationWidget/ClockConversationWidget.md +53 -0
  70. package/dist/files/widgets/ClockConversationWidget/clock.preview-fixtures.json +76 -0
  71. package/dist/files/widgets/ConceptExplainerConversationWidget/ConceptExplainerConversationWidget.md +86 -0
  72. package/dist/files/widgets/ConceptExplainerConversationWidget/concept-explainer.preview-fixtures.json +23 -0
  73. package/dist/files/widgets/ConversationSearchResultsConversationWidget/ConversationSearchResultsConversationWidget.md +59 -0
  74. package/dist/files/widgets/ConversationSearchResultsConversationWidget/conversation-search-results.preview-fixtures.json +85 -0
  75. package/dist/files/widgets/CurrencyConverterConversationWidget/CurrencyConverterConversationWidget.md +51 -0
  76. package/dist/files/widgets/CurrencyConverterConversationWidget/currency-converter.preview-fixtures.json +73 -0
  77. package/dist/files/widgets/CustomVisualizationConversationWidget/CustomVisualizationConversationWidget.md +83 -0
  78. package/dist/files/widgets/CustomVisualizationConversationWidget/custom-visualization.preview-fixtures.json +227 -0
  79. package/dist/files/widgets/CustomVisualizationConversationWidget/sandbox-frame/custom-visualization-frame.html +188 -0
  80. package/dist/files/widgets/EntityMentionConversationWidget/EntityMentionConversationWidget.md +55 -0
  81. package/dist/files/widgets/EntityMentionConversationWidget/entity-mention.preview-fixtures.json +55 -0
  82. package/dist/files/widgets/MultiChoiceConversationWidget/MultiChoiceConversationWidget.md +61 -0
  83. package/dist/files/widgets/MultiChoiceConversationWidget/multi-choice-widget-contract.json +43 -0
  84. package/dist/files/widgets/MultiChoiceConversationWidget/multi-choice.preview-fixtures.json +103 -0
  85. package/dist/files/widgets/QuickRepliesConversationWidget/QuickRepliesConversationWidget.md +65 -0
  86. package/dist/files/widgets/QuickRepliesConversationWidget/quick-replies-widget-contract.json +43 -0
  87. package/dist/files/widgets/QuickRepliesConversationWidget/quick-replies.preview-fixtures.json +45 -0
  88. package/dist/files/widgets/SuggestedActions/SuggestedActions.md +60 -0
  89. package/dist/files/widgets/SuggestedActions/suggested-actions.preview-fixtures.json +19 -0
  90. package/dist/files/widgets/ToolTraceConversationWidget/ToolTraceConversationWidget.md +48 -0
  91. package/dist/files/widgets/ToolTraceConversationWidget/tool-trace.preview-fixtures.json +32 -0
  92. package/dist/files/widgets/WebSearchResultsConversationWidget/WebSearchResultsConversationWidget.md +49 -0
  93. package/dist/files/widgets/WebSearchResultsConversationWidget/web-search-results.preview-fixtures.json +57 -0
  94. package/dist/files/widgets/WritingDraftConversationWidget/WritingDraftConversationWidget.md +66 -0
  95. package/dist/files/widgets/WritingDraftConversationWidget/writing-draft.preview-fixtures.json +129 -0
  96. package/dist/image-render.js +11 -10
  97. package/dist/image-render.js.map +1 -1
  98. package/dist/index.js +32 -28
  99. package/dist/index.js.map +1 -1
  100. package/dist/kit.js +11 -2
  101. package/dist/kit.js.map +1 -1
  102. package/dist/preview.js +7 -6
  103. package/dist/provider.js +71 -0
  104. package/dist/provider.js.map +1 -0
  105. package/dist/renderer.js +138 -63
  106. package/dist/renderer.js.map +1 -1
  107. package/dist/styles.css +32 -17
  108. package/dist/types/client/testing/test-conversation-widgets.d.ts +25 -0
  109. package/dist/types/client/testing/widget-hydration-stand-ins.d.ts +33 -0
  110. package/dist/types/entries/chat.d.ts +10 -0
  111. package/dist/types/entries/client-testing.d.ts +2 -0
  112. package/dist/types/entries/index.d.ts +4 -3
  113. package/dist/types/entries/kit.d.ts +7 -0
  114. package/dist/types/entries/preview.d.ts +1 -0
  115. package/dist/types/entries/provider.d.ts +1 -0
  116. package/dist/types/entries/renderer.d.ts +16 -0
  117. package/dist/types/entries/widgets.d.ts +13 -0
  118. package/dist/types/kit/components/data/apex-chart-component.d.ts +3 -0
  119. package/dist/types/kit/components/data/chart-model.d.ts +164 -0
  120. package/dist/types/kit/components/data/data-value-format.d.ts +44 -0
  121. package/dist/types/kit/components/data/use-chart-palette.d.ts +9 -0
  122. package/dist/types/kit/components/data/use-number-locale.d.ts +5 -0
  123. package/dist/types/provider/index.d.ts +1 -0
  124. package/dist/types/renderer/_access/ConversationWidgetGateSkeleton.d.ts +6 -0
  125. package/dist/types/renderer/_agent-space/use-conversation-widget-agent-space-fallback.d.ts +16 -0
  126. package/dist/types/renderer/canvas/use-anchor-widget-agent-space-key.d.ts +17 -0
  127. package/dist/types/renderer/conversationWidgetRegistry.d.ts +6 -0
  128. package/dist/types/renderer/read-conversation-widget-variant.d.ts +22 -0
  129. package/dist/types/widgets/_shared/CardFooter.d.ts +6 -0
  130. package/dist/types/widgets/_shared/WidgetLabel.d.ts +8 -0
  131. package/dist/types/widgets/_shared/entity-update-channel.d.ts +17 -0
  132. package/dist/types/widgets/_shared/use-element-visible.d.ts +6 -0
  133. package/dist/widgets.js +120 -27
  134. package/dist/widgets.js.map +1 -1
  135. package/package.json +74 -1
  136. package/public-api.json +761 -0
  137. package/dist/chunks/ConversationMarkdown-W7NHglmL.js.map +0 -1
  138. package/dist/chunks/WebSearchResultsConversationWidget-BvnLWHyi.js.map +0 -1
  139. package/dist/chunks/canvas-behaviours-BRFR1ALE.js.map +0 -1
  140. package/dist/chunks/canvasBodies-9SuF6NAB.js.map +0 -1
  141. package/dist/chunks/decide-canvas-open-Ct-wnNEJ.js +0 -20
  142. package/dist/chunks/decide-canvas-open-Ct-wnNEJ.js.map +0 -1
  143. package/dist/chunks/widget-name-resolver-DyIY6Zu4.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"ConversationMarkdown-W7NHglmL.js","sources":["../../src/renderer/render-report/widget-render-report-collector.ts","../../src/renderer/widget-windowing.tsx","../../src/renderer/conversationWidgetAstPlugin.ts","../../src/renderer/restoreTextDirectivesPlugin.ts","../../src/renderer/WindowedWidget/WindowedWidget.tsx","../../src/renderer/ConversationWidgetHost.tsx","../../src/renderer/MarkdownLink.tsx","../../src/renderer/ConversationMarkdown.tsx"],"sourcesContent":["import { createContext } from \"react\";\nimport type { WidgetRenderReporter, WidgetRenderReportEntry } from \"./widget-render-report\";\n\n/**\n * The render reports of the widget blocks of live messages, collected per message. The chat host\n * (`AgentChat`) owns one collector and hands it down; `ConversationWidgetHost` registers every block of a JUST-DELIVERED\n * message (never a replayed one) and gives the widget a reporter for it. A block that reports nothing counts as\n * `mounted`. Once a message's blocks have settled — none `pending` for `settleMs`, or `maxWaitMs` after the first block\n * at the latest — the collector calls `onSettled` ONCE for that message with its blocks in document order; the host\n * sends the signal only when a block is not `mounted` or rendered with a note (a `mounted` entry with a code: figures\n * without a source), so a clean render costs nothing.\n */\n\nexport interface WidgetRenderBlockReport {\n widgetName: string;\n /** The block's offset in the message's markdown — document order, and the block's identity in the message. */\n sourceOffset: number;\n entry: WidgetRenderReportEntry;\n}\n\nexport interface WidgetRenderReportCollector {\n /** Counts one block of one live message as `mounted` unless it already reported (a child reports before its host mounts). */\n registerBlock: (messageId: string | number, widgetName: string, sourceOffset: number) => void;\n /** The reporter of one block of one live message. */\n reporterForBlock: (messageId: string | number, widgetName: string, sourceOffset: number) => WidgetRenderReporter;\n /** Forget every pending timer (the host unmounts or the conversation switches). */\n dispose: () => void;\n}\n\nexport interface WidgetRenderReportCollectorOptions {\n onSettled: (messageId: string, blocks: WidgetRenderBlockReport[]) => void;\n settleMs?: number;\n maxWaitMs?: number;\n}\n\ninterface MessageReports {\n blocksByKey: Map<string, WidgetRenderBlockReport>;\n firstReportAt: number;\n settleTimer: ReturnType<typeof setTimeout> | null;\n isSent: boolean;\n}\n\nexport const createWidgetRenderReportCollector = (\n options: WidgetRenderReportCollectorOptions,\n): WidgetRenderReportCollector => {\n const { onSettled, settleMs = 1500, maxWaitMs = 20000 } = options;\n const reportsByMessageId = new Map<string, MessageReports>();\n\n const scheduleSettleCheck = (messageId: string) => {\n const messageReports = reportsByMessageId.get(messageId);\n if (!messageReports || messageReports.isSent) return;\n if (messageReports.settleTimer !== null) clearTimeout(messageReports.settleTimer);\n const hasPendingBlock = [...messageReports.blocksByKey.values()].some((block) => block.entry.status === \"pending\");\n const waitedMs = Date.now() - messageReports.firstReportAt;\n const delayMs = hasPendingBlock ? Math.max(0, Math.min(settleMs * 4, maxWaitMs - waitedMs)) : settleMs;\n messageReports.settleTimer = setTimeout(() => {\n messageReports.settleTimer = null;\n const isStillPending = [...messageReports.blocksByKey.values()].some((block) => block.entry.status === \"pending\");\n if (isStillPending && Date.now() - messageReports.firstReportAt < maxWaitMs) {\n scheduleSettleCheck(messageId);\n return;\n }\n messageReports.isSent = true;\n onSettled(\n messageId,\n [...messageReports.blocksByKey.values()].sort((first, second) => first.sourceOffset - second.sourceOffset),\n );\n }, delayMs);\n };\n\n const recordBlock = (\n messageId: string,\n widgetName: string,\n sourceOffset: number,\n entry: WidgetRenderReportEntry | null,\n ) => {\n let messageReports = reportsByMessageId.get(messageId);\n if (!messageReports) {\n messageReports = { blocksByKey: new Map(), firstReportAt: Date.now(), settleTimer: null, isSent: false };\n reportsByMessageId.set(messageId, messageReports);\n }\n if (messageReports.isSent) return;\n const blockKey = `${widgetName}@${sourceOffset}`;\n const knownBlock = messageReports.blocksByKey.get(blockKey);\n if (entry === null && knownBlock) return;\n messageReports.blocksByKey.set(blockKey, { widgetName, sourceOffset, entry: entry ?? { status: \"mounted\" } });\n scheduleSettleCheck(messageId);\n };\n\n return {\n registerBlock: (messageId, widgetName, sourceOffset) =>\n recordBlock(String(messageId), widgetName, sourceOffset, null),\n reporterForBlock: (messageId, widgetName, sourceOffset) => ({\n report: (entry: WidgetRenderReportEntry) => recordBlock(String(messageId), widgetName, sourceOffset, entry),\n }),\n dispose: () => {\n for (const messageReports of reportsByMessageId.values()) {\n if (messageReports.settleTimer !== null) clearTimeout(messageReports.settleTimer);\n }\n reportsByMessageId.clear();\n },\n };\n};\n\n/** The collector of the chat the widget lives in; absent = nobody listens (another host, a story, the e-mail capture). */\nexport const WidgetRenderReportCollectorContext = createContext<WidgetRenderReportCollector | null>(null);\n\n/** The stored prefix of a render-report signal — the inspector and the tests read it; never reworded. */\nexport const WIDGET_RENDER_REPORT_SIGNAL_PREFIX = \"Widget render report for message\";\n\n/** The signal source (backend `AIConversationSignalSource::FRONTEND_WIDGET_RENDER_REPORT`). */\nexport const WIDGET_RENDER_REPORT_SIGNAL_SOURCE = \"FRONTEND_WIDGET_RENDER_REPORT\";\n\nconst MAX_DETAIL_CHARACTERS = 400;\n\n/** The backend's cap on a signal text (`AIConversationMessage::MAX_SIGNAL_TEXT_CHARS`). */\nconst MAX_SIGNAL_TEXT_CHARS = 2000;\n/** Room kept for the \"… and N more\" line. */\nconst OMITTED_LINE_RESERVE = 80;\n\n/**\n * The model-visible signal for a settled message — null when every block mounted cleanly (nothing to tell). One line\n * per block that is not `mounted`, or that mounted with a note (a code: `INLINE_VALUE_WITHOUT_SOURCE`): its position\n * among the message's widgets, its name and its occurrence among widgets of that name, its status and code, the\n * detail. The closing sentence asks for the honest answer about a block the owner did not see, and for\n * a note that the next widget fixes it.\n */\nexport const buildWidgetRenderReportSignal = (messageId: string, blocks: WidgetRenderBlockReport[]): string | null => {\n const occurrenceByName = new Map<string, number>();\n const blockLines: string[] = [];\n blocks.forEach((block, blockPosition) => {\n const occurrence = (occurrenceByName.get(block.widgetName) ?? 0) + 1;\n occurrenceByName.set(block.widgetName, occurrence);\n if (block.entry.status === \"mounted\" && !block.entry.code) return;\n const status = block.entry.status === \"pending\" ? \"pending (did not finish loading)\" : block.entry.status;\n const code = block.entry.code ? ` ${block.entry.code}` : \"\";\n const detail = block.entry.detail ? ` — ${block.entry.detail.slice(0, MAX_DETAIL_CHARACTERS)}` : \"\";\n blockLines.push(`- widget ${blockPosition + 1} (${block.widgetName} #${occurrence}): ${status}${code}${detail}`);\n });\n if (blockLines.length === 0) return null;\n const header = `${WIDGET_RENDER_REPORT_SIGNAL_PREFIX} ${messageId}:`;\n const hasBlockNotShown = blocks.some((block) => block.entry.status !== \"mounted\");\n const hasNote = blocks.some((block) => block.entry.status === \"mounted\" && block.entry.code);\n const closing = [\n hasBlockNotShown\n ? \"The owner did not see these widgets as intended. In your next answer say so in one line where it matters and \" +\n 'give the content in prose; never refer to \"the widget above\" for them.'\n : \"\",\n hasNote\n ? \"The widgets marked mounted were shown; fix the noted part in every widget you write from now on (a figure you \" +\n \"researched names its publisher and page in `source`). Do not resend the widget for the note alone.\"\n : \"\",\n ]\n .filter((sentence) => sentence !== \"\")\n .join(\" \");\n // The backend keeps the first MAX_SIGNAL_TEXT_CHARS of a signal: whole lines only, the rest counted in one line.\n const keptLines: string[] = [];\n let signalLength = header.length + 1 + closing.length + OMITTED_LINE_RESERVE;\n for (const blockLine of blockLines) {\n if (signalLength + blockLine.length + 1 > MAX_SIGNAL_TEXT_CHARS) break;\n keptLines.push(blockLine);\n signalLength += blockLine.length + 1;\n }\n const omittedCount = blockLines.length - keptLines.length;\n if (omittedCount > 0) keptLines.push(`- … and ${omittedCount} more widget(s) that did not render as intended`);\n return `${header}\\n${keptLines.join(\"\\n\")}\\n${closing}`;\n};\n\nexport interface ParsedWidgetRenderReport {\n messageId: string;\n blocks: Array<{\n position: number;\n widgetName: string;\n occurrence: number;\n status: string;\n code: string | null;\n detail: string | null;\n }>;\n}\n\nconst REPORT_LINE =\n /^- widget (\\d+) \\(([A-Za-z]+) #(\\d+)\\): (mounted|empty|failed|pending)(?: \\(did not finish loading\\))?(?: ([A-Z_]+))?(?: — (.*))?$/;\n\n/** The report a stored signal text carries, or null for another text — the admin inspector's reader. */\nexport const parseWidgetRenderReportSignal = (signalText: string): ParsedWidgetRenderReport | null => {\n const lines = signalText.split(\"\\n\");\n const header = new RegExp(`^${WIDGET_RENDER_REPORT_SIGNAL_PREFIX} (\\\\S+):$`).exec(lines[0] ?? \"\");\n if (!header) return null;\n const blocks: ParsedWidgetRenderReport[\"blocks\"] = [];\n for (const line of lines.slice(1)) {\n const match = REPORT_LINE.exec(line);\n if (!match) continue;\n blocks.push({\n position: Number(match[1]),\n widgetName: match[2],\n occurrence: Number(match[3]),\n status: match[4],\n code: match[5] ?? null,\n detail: match[6] ?? null,\n });\n }\n return { messageId: header[1], blocks };\n};\n","import React, { createContext, RefObject, useContext, useEffect, useState } from \"react\";\n\n/**\n * Viewport-windowing for chat widgets. Heavy interactive widgets (maps, lists, hydrating components) are mounted ONLY\n * while near the viewport and unmounted back to a placeholder when far away — so a long conversation keeps a CONSTANT\n * number of widgets mounted no matter how far you scroll. Two thresholds give hysteresis (reveal early, hide late) so a\n * small scroll wobble never thrashes mount/unmount.\n *\n * The IntersectionObserver root is the chat scroll container, supplied via {@link WidgetWindowRootContext} by the chat\n * host (ConversationViewBody). Observers are POOLED per (root, margin): all placeholders share two observers, not two each.\n */\nexport const WidgetWindowRootContext = createContext<HTMLElement | null>(null);\n\n/** Mount when the widget is within this margin of the viewport. */\nconst REVEAL_MARGIN_PX = 600;\n/** Unmount only once it is beyond this (larger) margin — the gap to REVEAL is the hysteresis band. */\nconst HIDE_MARGIN_PX = 2000;\n\ntype Pool = { observer: IntersectionObserver; callbacks: Map<Element, (entry: IntersectionObserverEntry) => void> };\n// Keyed by root (null = viewport) → margin string → the shared observer + its per-element callbacks.\nconst poolsByRoot = new Map<Element | null, Map<string, Pool>>();\n\n/** Register `element` with the shared observer for (root, rootMargin); returns a disposer. */\nconst observeShared = (\n root: Element | null,\n rootMargin: string,\n element: Element,\n onEntry: (entry: IntersectionObserverEntry) => void,\n): (() => void) => {\n let byMargin = poolsByRoot.get(root);\n if (!byMargin) {\n byMargin = new Map();\n poolsByRoot.set(root, byMargin);\n }\n let pool = byMargin.get(rootMargin);\n if (!pool) {\n const callbacks = new Map<Element, (entry: IntersectionObserverEntry) => void>();\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n callbacks.get(entry.target)?.(entry);\n }\n },\n { root, rootMargin },\n );\n pool = { observer, callbacks };\n byMargin.set(rootMargin, pool);\n }\n pool.callbacks.set(element, onEntry);\n pool.observer.observe(element);\n\n return () => {\n const currentByMargin = poolsByRoot.get(root);\n const currentPool = currentByMargin?.get(rootMargin);\n if (!currentPool) return;\n currentPool.observer.unobserve(element);\n currentPool.callbacks.delete(element);\n if (currentPool.callbacks.size === 0) {\n currentPool.observer.disconnect();\n currentByMargin!.delete(rootMargin);\n if (currentByMargin!.size === 0) poolsByRoot.delete(root);\n }\n };\n};\n\n/**\n * Drives a widget's mounted/unmounted state from its viewport proximity.\n *\n * - `pinned` (the freshly-delivered widget) → always revealed, never observed: a live widget must not unmount while its\n * one-shot effects (canvas auto-open) are in play, and re-mounting it later would re-fire them.\n * - otherwise: starts at `initialRevealed` (the cheap index-window guess for first paint), then the reveal observer\n * mounts it when it scrolls within REVEAL_MARGIN and the hide observer unmounts it past HIDE_MARGIN.\n *\n * Returns `[revealed, reveal]` — `reveal` lets the placeholder force a manual mount (the \"Show\" affordance).\n */\nexport const useWidgetWindow = (\n targetRef: RefObject<HTMLElement | null>,\n options: { initialRevealed: boolean; pinned: boolean },\n): [boolean, () => void] => {\n const { initialRevealed, pinned } = options;\n const root = useContext(WidgetWindowRootContext);\n const [revealed, setRevealed] = useState(initialRevealed || pinned);\n\n useEffect(() => {\n if (pinned) {\n setRevealed(true);\n return undefined;\n }\n const element = targetRef.current;\n if (!element || typeof IntersectionObserver === \"undefined\") return undefined;\n\n const disposeReveal = observeShared(root, `${REVEAL_MARGIN_PX}px 0px`, element, (entry) => {\n if (entry.isIntersecting) setRevealed(true);\n });\n const disposeHide = observeShared(root, `${HIDE_MARGIN_PX}px 0px`, element, (entry) => {\n if (!entry.isIntersecting) setRevealed(false);\n });\n return () => {\n disposeReveal();\n disposeHide();\n };\n // Re-attach when the scroll root resolves (it is null on the first frame, then the container element).\n }, [root, pinned, targetRef]);\n\n return [revealed, () => setRevealed(true)];\n};\n","import { visit } from \"unist-util-visit\";\nimport { conversationWidgetRegistry, type ConversationWidgetEntry } from \"./conversationWidgetRegistry\";\nimport { resolveCanonicalWidgetName } from \"./widget-name-resolver\";\nimport { exceedsJsonContainerDepth } from \"./widget-tree/bounded-json\";\n\n/** Whether a `::Name{payload='…'}` payload nests deeper than the backend decodes — MALFORMED there, dropped here. */\nconst isPayloadTooDeep = (payload: unknown): boolean => {\n if (typeof payload !== \"string\") return false;\n try {\n return exceedsJsonContainerDepth(JSON.parse(payload));\n } catch {\n return false;\n }\n};\n\n/**\n * Maps the `::Name` nodes a message carries onto the registered components by rewriting `data.hName` to the CANONICAL\n * registry name — which is what `ConversationMarkdown` keys its component map by.\n *\n * The name on the node is whatever the message contains, so a stored conversation delivers the legacy\n * `::ExampleWidgetDirective{payload='…'}` form (and stored server `component` parts carry `\"name\":\"<Canonical>Directive\"`,\n * which `normalize-server-message-to-markdown` turns into exactly that). Resolution therefore goes\n * through `resolveCanonicalWidgetName` — the one legacy rule — never a direct set lookup, or every old message would\n * degrade to the `:name` plain-text fallback.\n */\nexport default function conversationWidgetAstPlugin() {\n const canonicalNames = new Set(conversationWidgetRegistry.widgets.map((w: ConversationWidgetEntry) => w.name));\n\n return (tree: any) => {\n // `\"leafDirective\"` is remark-directive's node type — its contract, not our vocabulary. It is the only form a\n // widget ever travels in: `remarkWidgetFencePlugin` produces it from a ```widget fence, and the stored `::Name`\n // syntax parses into it.\n visit(tree, [\"leafDirective\"], (node, index, parent) => {\n const canonicalName = resolveCanonicalWidgetName(node.name, canonicalNames);\n\n if (\n canonicalName &&\n index !== undefined &&\n index !== null &&\n parent &&\n isPayloadTooDeep(node.attributes?.payload)\n ) {\n parent.children[index] = { type: \"text\", value: \"\" };\n return;\n }\n\n if (canonicalName) {\n // Map properties to attributes for react-markdown\n node.data = {\n hName: canonicalName,\n hProperties: node.attributes || {},\n ...node.data,\n };\n return node;\n }\n\n // `index === 0` is falsy — a plain `!index` check would skip the text\n // fallback for a node that is its parent's first child.\n if (index === undefined || index === null || !parent) {\n return node;\n }\n\n // An unknown name becomes plain text. Keep the node's children so a `::Unknown[label]` form degrades to its\n // label instead of silently swallowing it.\n const asText = { type: \"text\", value: `:${node.name}` };\n parent.children.splice(index, 1, asText, ...(node.children ?? []));\n const prev = parent.children[index - 1];\n if (prev?.type === \"text\") {\n prev.value += asText.value;\n parent.children.splice(index, 1);\n }\n });\n };\n}\n","import { visit } from \"unist-util-visit\";\n\n/**\n * remark-directive parses EVERY `:name` run as a text directive — including the `:00` / `:30` inside a time such as\n * `08:00–16:30` (digits are valid directive names). Text directives are not part of our widget vocabulary (widgets\n * travel as leaf directives only, see `conversationWidgetAstPlugin`), so a text directive is always prose that the\n * parser misread: without this pass the customer chat rendered \"Montag: 08:00–16:30\" as \"08\" / \"–16\" (the `:00`\n * and `:30` swallowed, the unknown nodes rendered as breaks) while the admin inspector, which does not load\n * remark-directive, showed the line intact.\n *\n * Restores every text directive to the exact source slice it was parsed from, merging it into the neighbouring text\n * nodes so the paragraph reads as one run again.\n */\nexport default function restoreTextDirectivesPlugin() {\n return (tree: any, file: any) => {\n const source = String(file?.value ?? \"\");\n visit(tree, \"textDirective\", (node: any, index: number | undefined, parent: any) => {\n if (index === undefined || index === null || !parent) {\n return;\n }\n const start = node.position?.start?.offset;\n const end = node.position?.end?.offset;\n const literal =\n typeof start === \"number\" && typeof end === \"number\" && end > start\n ? source.slice(start, end)\n : `:${node.name}${node.children?.length ? `[${node.children.map((c: any) => c.value ?? \"\").join(\"\")}]` : \"\"}`;\n const asText = { type: \"text\", value: literal };\n parent.children.splice(index, 1, asText);\n // Merge with the neighbours so \"08\" + \":00\" + \"–16\" becomes one text node again.\n const prev = parent.children[index - 1];\n if (prev?.type === \"text\") {\n prev.value += asText.value;\n parent.children.splice(index, 1);\n const next = parent.children[index];\n if (next?.type === \"text\") {\n prev.value += next.value;\n parent.children.splice(index, 1);\n }\n return index - 1;\n }\n const next = parent.children[index + 1];\n if (next?.type === \"text\") {\n asText.value += next.value;\n parent.children.splice(index + 1, 1);\n }\n return index;\n });\n };\n}\n","import { InteractiveSurface, Text } from \"../../provider/components\";\nimport React, { useEffect, useRef } from \"react\";\nimport { translateText } from \"../../provider/environment\";\nimport { useWidgetWindow } from \"../widget-windowing\";\nimport styles from \"../HiddenWidgetPlaceholder/HiddenWidgetPlaceholder.module.scss\";\n\nexport interface WindowedWidgetProps {\n children: React.ReactNode;\n /** First-paint guess from the index window: recent messages start mounted, older ones start as a placeholder. */\n initialRevealed: boolean;\n /** The freshly-delivered widget — kept mounted (never windowed out) so its one-shot effects don't re-fire. */\n pinned: boolean;\n}\n\n/** Default reserved height for a widget that has never been measured (an old one that has not been scrolled to yet). */\nconst DEFAULT_PLACEHOLDER_MIN_HEIGHT = 80;\n\n/**\n * Mounts a chat widget only while it is near the viewport (see {@link useWidgetWindow}); far from the viewport it\n * collapses to a lightweight placeholder. The wrapper element is STABLE across the toggle so the shared\n * IntersectionObserver keeps tracking it. The placeholder reserves the widget's last measured height, so re-hiding it\n * causes ZERO layout shift (no scroll jump); revealing again restores the real widget (self-hydrating widgets re-fetch\n * with a brief skeleton).\n */\nexport const WindowedWidget = ({ children, initialRevealed, pinned }: WindowedWidgetProps) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const [revealed, reveal] = useWidgetWindow(wrapperRef, { initialRevealed, pinned });\n // Remembered so the placeholder can reserve exactly the height the widget occupied.\n const lastHeightRef = useRef<number | undefined>(undefined);\n\n useEffect(() => {\n const element = wrapperRef.current;\n if (!revealed || !element || typeof ResizeObserver === \"undefined\") return undefined;\n const measure = () => {\n if (wrapperRef.current) lastHeightRef.current = wrapperRef.current.offsetHeight;\n };\n measure();\n const resizeObserver = new ResizeObserver(measure);\n resizeObserver.observe(element);\n return () => resizeObserver.disconnect();\n }, [revealed]);\n\n return (\n <div ref={wrapperRef}>\n {revealed ? (\n children\n ) : (\n <InteractiveSurface\n hoverable\n className={styles.placeholder}\n style={{ minHeight: lastHeightRef.current ?? DEFAULT_PLACEHOLDER_MIN_HEIGHT }}\n >\n <button\n type=\"button\"\n className={styles.placeholderButton}\n onClick={reveal}\n aria-label={translateText(\"Show hidden widget\")}\n >\n <Text>Older interactive content is hidden.</Text>\n <span className={styles.cta}>\n <Text>Show</Text>\n </span>\n </button>\n </InteractiveSurface>\n )}\n </div>\n );\n};\n","import React, { useContext, useEffect, useMemo } from \"react\";\nimport styles from \"./ConversationMarkdown.module.scss\";\nimport { ConversationWidgetEntry } from \"./conversationWidgetRegistry\";\nimport { ConversationWidgetFeatureGate } from \"./_access/ConversationWidgetFeatureGate\";\nimport { readWidgetAgentSpaceKeyAttribute } from \"./_agent-space/widget-agent-space-key-attribute\";\nimport { ConversationWidgetErrorBoundary } from \"./ConversationWidgetErrorBoundary\";\nimport { WindowedWidget } from \"./WindowedWidget/WindowedWidget\";\nimport { WidgetRenderReportContext } from \"./render-report/widget-render-report\";\nimport { WidgetRenderReportCollectorContext } from \"./render-report/widget-render-report-collector\";\n\nexport type ConversationWidgetRenderProps = Record<string, unknown> & {\n children?: React.ReactNode;\n fresh?: boolean;\n interactive?: boolean;\n justDelivered?: boolean;\n messageId?: string | number;\n};\n\ninterface ConversationWidgetHostProps {\n widget: ConversationWidgetEntry;\n /** Forwarded into the widget (and as its deprecated alias `fresh`): the widget's controls may be used. */\n interactive: boolean;\n /** Forwarded into the widget: the host message was delivered live right now — the one-shot side-effect gate. */\n justDelivered: boolean;\n /** Id of the host message, forwarded so a widget can identify the canvas it opens. */\n messageId?: string | number;\n /** When true, the widget renders as a lightweight placeholder (cheap scroll). */\n hideWidgets: boolean;\n /** Parsed markdown attributes for this widget instance. */\n conversationWidgetRenderProps: ConversationWidgetRenderProps;\n}\n\n/**\n * Single render path for every widget. Each concern is applied as a sequential gate\n * (innermost → outermost):\n * 1. the widget itself, with `interactive` / `justDelivered`\n * 2. feature-flag gate\n * 3. viewport-windowing (mount near the viewport, placeholder when far — WindowedWidget)\n * 4. block spacing wrapper\n *\n * A block of a JUST-DELIVERED message is also registered with the chat's render-report collector: it\n * counts as `mounted` unless the widget reports otherwise through `useReportWidgetRenderStatus`, and a crash caught by\n * the error boundary reports `failed` (`RENDER_FAILED`). A replayed message reports nothing.\n */\nexport const ConversationWidgetHost = ({\n widget,\n interactive,\n justDelivered,\n messageId,\n hideWidgets,\n conversationWidgetRenderProps,\n}: ConversationWidgetHostProps) => {\n const { component: Component, featureFlag, upsellTrigger } = widget;\n const renderReportCollector = useContext(WidgetRenderReportCollectorContext);\n // The block's offset in the message markdown (react-markdown hands every component its hast node) — its identity and\n // its document order in the render report.\n const sourceOffset = (\n conversationWidgetRenderProps.node as { position?: { start?: { offset?: number } } } | undefined\n )?.position?.start?.offset;\n const isReported = renderReportCollector !== null && justDelivered && messageId !== undefined;\n const renderReporter = useMemo(\n () =>\n isReported && messageId !== undefined\n ? renderReportCollector.reporterForBlock(messageId, widget.name, sourceOffset ?? 0)\n : null,\n [isReported, renderReportCollector, messageId, widget.name, sourceOffset],\n );\n useEffect(() => {\n if (isReported && messageId !== undefined)\n renderReportCollector.registerBlock(messageId, widget.name, sourceOffset ?? 0);\n }, [isReported, renderReportCollector, messageId, widget.name, sourceOffset]);\n\n let node = (\n <Component\n {...conversationWidgetRenderProps}\n fresh={interactive}\n interactive={interactive}\n justDelivered={justDelivered}\n messageId={messageId}\n />\n );\n\n if (featureFlag) {\n node = (\n <ConversationWidgetFeatureGate\n featureFlag={featureFlag}\n UpsellTrigger={upsellTrigger}\n agentSpaceKeyAttribute={readWidgetAgentSpaceKeyAttribute(conversationWidgetRenderProps)}\n >\n {node}\n </ConversationWidgetFeatureGate>\n );\n }\n\n // Viewport-windowing: a widget is mounted only while near the viewport and collapses to a height-preserving\n // placeholder when far away — so a long conversation keeps a constant number of widgets mounted. The INTERACTIVE\n // widget (the live reply, and the newest reply after a reload) is pinned — never unmounted, so its controls stay\n // and its one-shot effects don't re-fire; older widgets start from the cheap index-window guess and reveal/hide as\n // they scroll in and out. The feature gate lives INSIDE, so it only runs once the widget is actually mounted.\n node = (\n // Pinned on delivery as well as on controls: a just-delivered widget that lost its controls (a newer widget of the\n // same type superseded it) must not unmount when scrolled past, or its remount re-fires the one-shot canvas open.\n <WindowedWidget initialRevealed={!hideWidgets} pinned={interactive || justDelivered}>\n {node}\n </WindowedWidget>\n );\n\n // Outermost gate: widget props come from LLM output, so any throw inside the\n // widget (or its gates) must not unmount the whole chat message.\n node = (\n <ConversationWidgetErrorBoundary\n widgetName={widget.name}\n onCrash={() =>\n renderReporter?.report({ status: \"failed\", code: \"RENDER_FAILED\", detail: \"the widget threw while rendering\" })\n }\n >\n <WidgetRenderReportContext.Provider value={renderReporter}>{node}</WidgetRenderReportContext.Provider>\n </ConversationWidgetErrorBoundary>\n );\n\n return <div className={styles.conversationWidgetWrapper}>{node}</div>;\n};\n","import React from \"react\";\nimport styles from \"./ConversationMarkdown.module.scss\";\n\nexport type MarkdownLinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & {\n /** The hast node react-markdown passes to every custom component; not a valid DOM attribute. */\n node?: unknown;\n};\n\n// Render every markdown link as a new-tab anchor with a dashed underline. `node` is dropped before the\n// rest is spread onto <a> so react-markdown's hast node never lands on the DOM element.\nexport const MarkdownLink = ({ node, children, ...anchorProps }: MarkdownLinkProps) => (\n <a {...anchorProps} target=\"_blank\" rel=\"noopener noreferrer\" className={styles.markdownLink}>\n {children}\n </a>\n);\n","import React, { useContext, useMemo } from \"react\";\nimport { type AgentsMarkdownProps, Markdown } from \"../provider/components\";\nimport remarkDirective from \"remark-directive\";\nimport remarkWidgetFencePlugin from \"./remarkWidgetFencePlugin\";\nimport conversationWidgetAstPlugin from \"./conversationWidgetAstPlugin\";\nimport restoreTextDirectivesPlugin from \"./restoreTextDirectivesPlugin\";\nimport { conversationWidgetRegistry, getConversationWidgetRegistryRevision } from \"./conversationWidgetRegistry\";\nimport { ConversationWidgetHost, ConversationWidgetRenderProps } from \"./ConversationWidgetHost\";\nimport { MarkdownLink } from \"./MarkdownLink\";\n\nexport interface ConversationMarkdownProps {\n markdown: string;\n /**\n * Forwarded into every widget instance as `interactive` (and its deprecated alias `fresh`): the widget's controls\n * may be used. True for a live-delivered message and for the newest assistant reply after a reload.\n */\n interactive?: boolean;\n /**\n * Forwarded into every widget instance as `justDelivered`: the message was delivered live right now. The only gate\n * for one-shot side effects (canvas open, draft creation); never true after a reload or on replay.\n */\n justDelivered?: boolean;\n /** Id of the host message, forwarded so a widget can identify the canvas it opens. */\n messageId?: string | number;\n /**\n * When true, widgets are replaced with a lightweight placeholder.\n * Used for old messages to keep the chat scroll cheap.\n */\n hideWidgets?: boolean;\n}\n\n/**\n * Render flags delivered via context so the widget component map can live at module\n * scope. The map must keep stable component identities across renders: react-markdown\n * reconciles by element type, so a per-render `Wrapped` closure makes React unmount and\n * remount every widget on each streaming tick — resetting one-shot refs (duplicate\n * drawer opens / POSTs) and re-triggering hydration.\n */\nconst ConversationWidgetRenderContext = React.createContext<{\n interactive: boolean;\n justDelivered: boolean;\n hideWidgets: boolean;\n messageId?: string | number;\n}>({\n interactive: false,\n justDelivered: false,\n hideWidgets: false,\n});\n\n// Map every widget name to a component that delegates rendering to ConversationWidgetHost,\n// which owns the per-widget concerns (interactive / justDelivered, feature-flag gate, hidden placeholder, block spacing).\n// Built lazily: the registry imports every widget and a widget can import AgentChat, which renders this file.\nconst buildConversationWidgetComponents = () =>\n conversationWidgetRegistry.widgets.reduce<Record<string, React.ComponentType<ConversationWidgetRenderProps>>>(\n (acc, widget) => {\n const Wrapped: React.ComponentType<ConversationWidgetRenderProps> = (innerProps) => {\n const { interactive, justDelivered, hideWidgets, messageId } = useContext(ConversationWidgetRenderContext);\n\n return (\n <ConversationWidgetHost\n widget={widget}\n interactive={interactive}\n justDelivered={justDelivered}\n messageId={messageId}\n hideWidgets={hideWidgets}\n conversationWidgetRenderProps={innerProps}\n />\n );\n };\n Wrapped.displayName = `ConversationWidget(${widget.name})`;\n acc[widget.name] = Wrapped;\n return acc;\n },\n {},\n );\n\nlet markdownComponents: AgentsMarkdownProps[\"components\"] | undefined;\nlet markdownComponentsRevision = -1;\n\n// Rebuilt only when an app registered more widgets since (`registerConversationWidgets`): the identities stay stable.\nconst getMarkdownComponents = (): AgentsMarkdownProps[\"components\"] => {\n if (markdownComponents === undefined || markdownComponentsRevision !== getConversationWidgetRegistryRevision()) {\n markdownComponents = {\n ...buildConversationWidgetComponents(),\n a: MarkdownLink,\n } as AgentsMarkdownProps[\"components\"];\n markdownComponentsRevision = getConversationWidgetRegistryRevision();\n }\n return markdownComponents;\n};\n\n// remarkWidgetFencePlugin rewrites ```widget fenced blocks into the node type remark-directive parses `::Name{}` into,\n// BEFORE conversationWidgetAstPlugin maps them to components — so the model's ```widget egress and the legacy\n// `::Name{}` egress share one render path (ConversationWidgetHost + feature-gate + hydration).\n// restoreTextDirectivesPlugin runs LAST: remark-directive also parses the `:00` inside \"08:00–16:30\" as a text\n// directive (digits are valid names) and swallowed it in the customer chat — text directives are never widgets.\nconst remarkPlugins = [\n remarkDirective,\n remarkWidgetFencePlugin,\n conversationWidgetAstPlugin,\n restoreTextDirectivesPlugin,\n];\n\nexport const ConversationMarkdown = (props: ConversationMarkdownProps) => {\n const { markdown, interactive = false, justDelivered = false, hideWidgets = false, messageId } = props;\n\n const renderContext = useMemo(\n () => ({ interactive, justDelivered, hideWidgets, messageId }),\n [interactive, justDelivered, hideWidgets, messageId],\n );\n\n return (\n <ConversationWidgetRenderContext.Provider value={renderContext}>\n <Markdown remarkPlugins={remarkPlugins} components={getMarkdownComponents()} markdown={markdown} />\n </ConversationWidgetRenderContext.Provider>\n );\n};\n"],"names":["next","styles"],"mappings":"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"}