@athenaintel/react 0.26.2 → 0.26.5

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 (110) hide show
  1. package/README.md +22 -0
  2. package/dist/auth/AthenaAuthProvider.d.ts +1 -1
  3. package/dist/auth/AthenaSSOProvider.d.ts +1 -1
  4. package/dist/chat/StatewireApprovalCard.cjs +68 -9
  5. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  6. package/dist/chat/StatewireApprovalCard.d.ts +0 -31
  7. package/dist/chat/StatewireApprovalCard.js +70 -11
  8. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  9. package/dist/chat/super-grouping/CollapsibleGroup.d.ts +1 -1
  10. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +2 -2
  11. package/dist/chat/super-grouping/ToolTimeline.d.ts +1 -1
  12. package/dist/chat/use-statewire-approval-request.cjs +6 -1
  13. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  14. package/dist/chat/use-statewire-approval-request.d.ts +20 -0
  15. package/dist/chat/use-statewire-approval-request.js +6 -1
  16. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  17. package/dist/chat-ui/header/chat-header.cjs +4 -4
  18. package/dist/chat-ui/header/chat-header.cjs.map +1 -1
  19. package/dist/chat-ui/header/chat-header.d.ts +3 -3
  20. package/dist/chat-ui/header/chat-header.js +1 -1
  21. package/dist/chat-ui/header/chat-header.js.map +1 -1
  22. package/dist/chat-ui/header/conversation-history-panel.d.ts +1 -1
  23. package/dist/chat-ui/index.cjs +8 -7
  24. package/dist/chat-ui/index.cjs.map +1 -1
  25. package/dist/chat-ui/index.d.ts +2 -1
  26. package/dist/chat-ui/index.js +2 -1
  27. package/dist/chat-ui/index.js.map +1 -1
  28. package/dist/chat-ui/markdown-storage.cjs +2 -1
  29. package/dist/chat-ui/markdown-storage.cjs.map +1 -1
  30. package/dist/chat-ui/markdown-storage.d.ts +3 -0
  31. package/dist/chat-ui/markdown-storage.js +2 -1
  32. package/dist/chat-ui/markdown-storage.js.map +1 -1
  33. package/dist/chat-ui/mentions/suggestions/components/mention-icon.d.ts +1 -1
  34. package/dist/chat-ui/mentions/suggestions/components/menu-breadcrumbs.d.ts +1 -1
  35. package/dist/chat-ui/mentions/suggestions/components/menu-item.d.ts +1 -1
  36. package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +1 -1
  37. package/dist/chat-ui/mentions/suggestions/components/menu-skeleton.d.ts +1 -1
  38. package/dist/chat-ui/mentions/suggestions/components/menu-summary.d.ts +1 -1
  39. package/dist/chat-ui/mentions/suggestions/shims.d.ts +1 -1
  40. package/dist/chat-ui/messages/message-components.cjs +13 -59
  41. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  42. package/dist/chat-ui/messages/message-components.d.ts +2 -14
  43. package/dist/chat-ui/messages/message-components.js +2 -47
  44. package/dist/chat-ui/messages/message-components.js.map +1 -1
  45. package/dist/chat-ui/messages/runtime-message.cjs +1 -1
  46. package/dist/chat-ui/messages/runtime-message.cjs.map +1 -1
  47. package/dist/chat-ui/messages/runtime-message.js +1 -1
  48. package/dist/chat-ui/messages/runtime-message.js.map +1 -1
  49. package/dist/chat-ui/messages/thread-chrome.cjs +59 -0
  50. package/dist/chat-ui/messages/thread-chrome.cjs.map +1 -0
  51. package/dist/chat-ui/messages/thread-chrome.d.ts +14 -0
  52. package/dist/chat-ui/messages/thread-chrome.js +59 -0
  53. package/dist/chat-ui/messages/thread-chrome.js.map +1 -0
  54. package/dist/chat-ui/messages/wake-marker.cjs +1 -1
  55. package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
  56. package/dist/chat-ui/messages/wake-marker.js +1 -1
  57. package/dist/chat-ui/messages/wake-marker.js.map +1 -1
  58. package/dist/chat-ui/rich-text/chat-link.d.ts +2 -2
  59. package/dist/chat-ui/rich-text/chat-message-body.d.ts +1 -1
  60. package/dist/chat-ui/rich-text/chat-node-views.d.ts +5 -5
  61. package/dist/chat-ui/rich-text/chat-text-schema.cjs +9 -1
  62. package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -1
  63. package/dist/chat-ui/rich-text/chat-text-schema.d.ts +7 -0
  64. package/dist/chat-ui/rich-text/chat-text-schema.js +9 -1
  65. package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -1
  66. package/dist/chat-ui/thread/chat-composer-dock.d.ts +1 -1
  67. package/dist/chat-ui/thread/chat-thread-shell.cjs +4 -3
  68. package/dist/chat-ui/thread/chat-thread-shell.cjs.map +1 -1
  69. package/dist/chat-ui/thread/chat-thread-shell.d.ts +1 -1
  70. package/dist/chat-ui/thread/chat-thread-shell.js +2 -1
  71. package/dist/chat-ui/thread/chat-thread-shell.js.map +1 -1
  72. package/dist/composer/AttachmentContext.d.ts +1 -1
  73. package/dist/composer/QuoteContext.d.ts +1 -1
  74. package/dist/lib/posthog/before-send.cjs +12 -0
  75. package/dist/lib/posthog/before-send.cjs.map +1 -1
  76. package/dist/lib/posthog/before-send.js +12 -0
  77. package/dist/lib/posthog/before-send.js.map +1 -1
  78. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs +2 -0
  79. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  80. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js +2 -0
  81. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  82. package/dist/packages/agent-runtime/src/messages.cjs +15 -1
  83. package/dist/packages/agent-runtime/src/messages.cjs.map +1 -1
  84. package/dist/packages/agent-runtime/src/messages.js +15 -1
  85. package/dist/packages/agent-runtime/src/messages.js.map +1 -1
  86. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.cjs +22 -0
  87. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
  88. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.js +22 -0
  89. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.js.map +1 -1
  90. package/dist/packages/react/package.json.cjs +1 -1
  91. package/dist/packages/react/package.json.js +1 -1
  92. package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.cjs +114 -0
  93. package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.cjs.map +1 -0
  94. package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.js +114 -0
  95. package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.js.map +1 -0
  96. package/dist/provider/AthenaProvider.d.ts +1 -1
  97. package/dist/provider/PostHogProvider.d.ts +1 -1
  98. package/dist/threads/SessionList.d.ts +1 -1
  99. package/dist/threads/ThreadList.d.ts +1 -1
  100. package/dist/threads/statewire-thread-list.d.ts +1 -1
  101. package/dist/tools/primitives.d.ts +3 -3
  102. package/dist/tools/tool-fallback.d.ts +8 -8
  103. package/dist/ui/button.d.ts +1 -1
  104. package/dist/ui/collapsible.d.ts +3 -3
  105. package/dist/ui/popover.d.ts +3 -3
  106. package/dist/ui/tooltip.d.ts +4 -4
  107. package/dist/voice/use-athena-voice-session.cjs.map +1 -1
  108. package/dist/voice/use-athena-voice-session.d.ts +5 -0
  109. package/dist/voice/use-athena-voice-session.js.map +1 -1
  110. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"use-deep-agent-window-sync.js","sources":["../../../../../agent-runtime/src/use-deep-agent-window-sync.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport { useAuiState } from '@assistant-ui/store';\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport { DEEP_AGENT_INTEREST_PROTOCOL } from './generated/runconfig-contract';\nimport {\n buildToolOutputCommand,\n type DeepAgentInterestRequest,\n type DeepAgentMessageWindow,\n interestsCovered,\n pageInterestRequests,\n readDeepAgentMessageWindow,\n readToolOutputResult,\n readTruncatedToolOutputArtifact,\n} from './message-window';\nimport { hasStatewireThreadExtras } from './thread-extras';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\n\n/**\n * Pages of older history chained per approach to the top. A renderer lowers\n * its near-top level once prepended content has pushed the first message out\n * of its band; this bounds the case where it cannot (no viewport to scroll,\n * a list too short to overflow) so a 2,000-message thread never streams whole.\n */\nexport const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;\n\n/**\n * Pages of older history that add no converted message — every message on\n * them folds into the first loaded turn, such as one agent run's hundreds of\n * tool steps — loaded on top of a request (or an approach's chain) before it\n * stops. Such a page changes nothing the user can see, so it neither answers\n * an ask nor counts against the per-approach chain.\n */\nexport const DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS = 25;\n\n/** The converted thread messages the tool-output half scans (web and native `ThreadMessage` both satisfy it). */\nexport interface DeepAgentWindowSyncMessage {\n readonly id: string;\n readonly content: readonly { readonly type: string; readonly artifact?: unknown }[];\n}\n\n/** One page interest round trip, for the host's telemetry. */\nexport interface DeepAgentHistoryLoadEvent {\n /** The page's ordinal (`1` extends the head). */\n page: number;\n request: DeepAgentInterestRequest;\n durationMs: number;\n}\n\nexport interface UseDeepAgentWindowSyncOptions {\n /**\n * The converted thread messages — read by the host through its platform\n * `useAuiState((s) => s.thread.messages)`, so this hook imports neither\n * `@assistant-ui/react` nor `@assistant-ui/react-native`.\n */\n messages: readonly DeepAgentWindowSyncMessage[];\n /** Messages per page; the thread's window size by default. */\n pageSize?: number;\n /**\n * Full tool outputs fetched back for cut tool messages; the same store the\n * thread converts with (`useDeepAgentThread({ toolOutputs })`). Omitted, the\n * tool-output half is inert (a surface that never shows a cut output whole).\n */\n toolOutputs?: DeepAgentToolOutputStore | undefined;\n /**\n * The renderer's report that the top of the LOADED history is near — a\n * level, not an edge: while it holds and older messages exist, pages load\n * one after another (bounded by `maxChainedLoads` per approach). Omitted for\n * hosts with only a manual affordance (`loadOlder`).\n */\n nearTop?: boolean;\n /** Bumped on every rise of `nearTop` (and every explicit request), so the chain bound is per approach. */\n nearTopEpoch?: number;\n /**\n * Whether a message's content is mounted right now, so lazy fetches (cut\n * tool outputs) target what the user can see rather than the whole loaded\n * history. Omitted: every message counts as mounted (the flat renderers).\n */\n isMessageMounted?: ((messageId: string) => boolean) | undefined;\n maxChainedLoads?: number;\n /** Pages adding no converted message loaded per request before it stops; see {@link DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS}. */\n maxUnseenLoads?: number;\n /** A page interest resolved (telemetry). */\n onHistoryLoad?: ((event: DeepAgentHistoryLoadEvent) => void) | undefined;\n /** A read failed; the sync itself recovers (the pending marks are released). */\n onError?: ((error: unknown, command: 'athena/interest' | 'history/tool_output') => void) | undefined;\n now?: () => number;\n}\n\nexport interface DeepAgentWindowSyncState {\n /** The joined window, or `null` while the head interest has not resolved (both halves are inert). */\n window: DeepAgentMessageWindow | null;\n /** Whether the host holds messages older than the loaded window. */\n hasOlder: boolean;\n /**\n * Whether the next page can be asked for: older messages exist and the\n * host's interest cap has room for them. `hasOlder && !canLoadOlder` is the\n * depth limit (`MAX_INTERESTS × MAX_MESSAGE_WINDOW` messages loaded in one\n * connection) — an edge row says so instead of offering a dead button.\n */\n canLoadOlder: boolean;\n /** A page of older history is in flight. */\n loading: boolean;\n /** Ask for the next page of older history now (an edge row's button, a keypress). A no-op before the head resolved or at the beginning. */\n loadOlder: () => void;\n}\n\nconst everyMessageMounted = (): boolean => true;\nconst defaultNow = (): number => Date.now();\nconst noopSubscribe = () => () => {};\n\n/** The statewire extras of the nearest aui thread; throws on a non-statewire thread like the library's own hooks. */\nconst useStatewireExtras = (): StatewireThread.Extras =>\n useAuiState((s) => {\n if (!hasStatewireThreadExtras(s.thread.extras)) {\n throw new Error('useDeepAgentWindowSync requires a statewire thread');\n }\n return s.thread.extras as StatewireThread.Extras;\n });\n\n/** The joined interest window of the nearest statewire thread. */\nexport function useDeepAgentMessageWindow(): DeepAgentMessageWindow | null {\n const documents = useStatewireExtras().documents;\n const mounted = useSyncExternalStore(\n documents?.subscribe ?? noopSubscribe,\n () => documents?.list(),\n () => documents?.list()\n );\n return useMemo(() => readDeepAgentMessageWindow(mounted), [mounted]);\n}\n\n/**\n * The client half of the interest window, shared by every surface — mounted\n * once per runtime, inside its aui provider.\n *\n * - **Older history.** While the host renderer reports the top of the loaded\n * history near (`nearTop`) and the window says older messages exist, this\n * re-states the interests with one more page (anchored at the window's\n * first message) — the host mounts its documents for this client alone —\n * chaining at most `maxChainedLoads` pages per approach; `loadOlder` asks\n * for one page on demand (an edge row's button). Never two loads in flight.\n * A reconnect whose hello does not carry the interests this mount last\n * stated (the host remembers a client id's view across its attaches; a new\n * host instance does not) re-states them.\n * - **Cut tool outputs.** Tool cards whose output the wire carried cut\n * (`artifact._athena_content_truncated`) get it fetched whole through\n * `history/tool_output` once their message is mounted; the converter puts\n * it back (`toolOutputs`), so the card re-renders complete. An output the\n * host replaced since (the marker's `chars` changed) is fetched again.\n */\n/**\n * Whether an older page put a new converted message ahead of the thread's\n * first one. Older history only ever merges into or lands before the first\n * converted message, so the second one is a stable landmark: it moved down iff\n * the page showed something. A new tail message does not move it. Without a\n * second message (or once it is gone) the converted count decides.\n */\nfunction pageShowedEarlierMessage(\n from: { count: number; secondId: string | undefined },\n messages: readonly DeepAgentWindowSyncMessage[]\n): boolean {\n if (from.secondId !== undefined) {\n const index = messages.findIndex((message) => message.id === from.secondId);\n if (index !== -1) return index > 1;\n }\n return messages.length > from.count;\n}\n\nexport function useDeepAgentWindowSync({\n messages,\n pageSize,\n toolOutputs,\n nearTop = false,\n nearTopEpoch = 0,\n isMessageMounted = everyMessageMounted,\n maxChainedLoads = DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,\n maxUnseenLoads = DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS,\n onHistoryLoad,\n onError,\n now = defaultNow,\n}: UseDeepAgentWindowSyncOptions): DeepAgentWindowSyncState {\n const { sendCommand, invoke, connection } = useStatewireExtras();\n const window = useDeepAgentMessageWindow();\n const [loading, setLoading] = useState(false);\n const [requests, setRequests] = useState(0);\n const servedRequestsRef = useRef(0);\n const inflightRef = useRef(false);\n const chainRef = useRef({ epoch: 0, loads: 0, unseen: 0, requested: false });\n // The converted thread when the in-flight page was stated; `null` once its\n // settle was judged (or it failed).\n const pageFromRef = useRef<{ count: number; secondId: string | undefined } | null>(null);\n const aliveRef = useRef(true);\n // The interests this mount last stated, re-stated on the next connected\n // session (a hello resets the documents) so a reconnect keeps the loaded history.\n const statedRef = useRef<DeepAgentInterestRequest[] | null>(null);\n const restatedConnectionRef = useRef<unknown>(null);\n // Outputs already asked for and answered by this mount — fetched, refused,\n // or failed — by the `chars` they were asked for. The converter re-runs on\n // every wire change, and the store is a bounded LRU: without this memory a\n // refused read would leave on every pass, and once a transcript holds more\n // cut outputs than the store retains, each fetch would evict a still-loaded\n // output and the next pass would fetch it again, forever. An evicted output\n // renders its cut text (the REST display limit) rather than re-entering the\n // loop; a marker whose `chars` moved (the host replaced the output) is asked\n // for again.\n const answeredRef = useRef(new Map<string, number>());\n const onHistoryLoadRef = useRef(onHistoryLoad);\n onHistoryLoadRef.current = onHistoryLoad;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const nowRef = useRef(now);\n nowRef.current = now;\n useEffect(() => {\n aliveRef.current = true;\n return () => {\n aliveRef.current = false;\n };\n }, []);\n\n useEffect(() => {\n if (connection.status !== 'connected' || restatedConnectionRef.current === connection) return;\n // Decided once per connected session, on the hello's interest document.\n if (window === null) return;\n restatedConnectionRef.current = connection;\n const stated = statedRef.current;\n if (stated === null || interestsCovered(window.requests, stated)) return;\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [stated]).catch((error: unknown) => {\n onErrorRef.current?.(error, 'athena/interest');\n });\n }, [connection, invoke, window]);\n\n useEffect(() => {\n if (window === null || inflightRef.current) return;\n const from = pageFromRef.current;\n pageFromRef.current = null;\n const lastPageUnseen =\n from !== null && from.count > 0 && !pageShowedEarlierMessage(from, messages);\n const pageRequests = pageInterestRequests(window, pageSize);\n if (pageRequests === null) return;\n const requested = requests !== servedRequestsRef.current;\n const chain = chainRef.current;\n if (requested) {\n // An explicit ask re-arms the chain for this approach.\n servedRequestsRef.current = requests;\n chainRef.current = { epoch: nearTopEpoch, loads: 1, unseen: 0, requested: true };\n } else if (lastPageUnseen && (chain.requested || (nearTop && chain.epoch === nearTopEpoch))) {\n // The page landed inside the first loaded turn: keep going until one shows.\n if (chain.unseen >= maxUnseenLoads) return;\n chain.unseen += 1;\n } else {\n if (!nearTop) return;\n if (chain.epoch !== nearTopEpoch) {\n chainRef.current = { epoch: nearTopEpoch, loads: 0, unseen: 0, requested: false };\n }\n if (chainRef.current.loads >= maxChainedLoads) return;\n chainRef.current.loads += 1;\n }\n pageFromRef.current = { count: messages.length, secondId: messages[1]?.id };\n const page = window.pages + 1;\n const request = pageRequests[pageRequests.length - 1] as DeepAgentInterestRequest;\n inflightRef.current = true;\n setLoading(true);\n const startedAt = nowRef.current();\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [pageRequests])\n .then(() => {\n statedRef.current = pageRequests;\n onHistoryLoadRef.current?.({\n page,\n request,\n durationMs: Math.max(0, Math.round(nowRef.current() - startedAt)),\n });\n })\n .catch((error: unknown) => {\n pageFromRef.current = null;\n onErrorRef.current?.(error, 'athena/interest');\n })\n .finally(() => {\n inflightRef.current = false;\n if (aliveRef.current) setLoading(false);\n });\n // `loading` re-arms the chain once a page settled after its documents moved the window.\n }, [\n nearTop,\n nearTopEpoch,\n requests,\n window,\n loading,\n messages,\n invoke,\n maxChainedLoads,\n maxUnseenLoads,\n pageSize,\n ]);\n\n useEffect(() => {\n if (window === null || toolOutputs === undefined) return;\n for (const message of messages) {\n if (!isMessageMounted(message.id)) continue;\n for (const part of message.content) {\n if (part.type !== 'tool-call') continue;\n const marker = readTruncatedToolOutputArtifact(part.artifact);\n if (marker === null || toolOutputs.isPending(marker.messageId)) continue;\n // Fetched for this very length already; a different length means the\n // host replaced the output under the same id since.\n if (toolOutputs.entry(marker.messageId)?.chars === marker.chars) continue;\n if (answeredRef.current.get(marker.messageId) === marker.chars) continue;\n const { messageId, chars } = marker;\n toolOutputs.markPending(messageId);\n Promise.resolve(sendCommand(buildToolOutputCommand({ messageId })))\n .then((payload) => {\n answeredRef.current.set(messageId, chars);\n const result = readToolOutputResult(payload);\n if (result === null) {\n toolOutputs.clearPending(messageId);\n return;\n }\n toolOutputs.set(result.messageId, { content: result.content, chars });\n })\n .catch((error: unknown) => {\n answeredRef.current.set(messageId, chars);\n toolOutputs.clearPending(messageId);\n onErrorRef.current?.(error, 'history/tool_output');\n });\n }\n }\n }, [messages, isMessageMounted, window, sendCommand, toolOutputs]);\n\n const loadOlder = useCallback(() => {\n setRequests((count) => count + 1);\n }, []);\n\n const canLoadOlder = useMemo(\n () => window !== null && pageInterestRequests(window, pageSize) !== null,\n [window, pageSize]\n );\n\n return { window, hasOlder: window?.hasOlder ?? false, canLoadOlder, loading, loadOlder };\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"use-deep-agent-window-sync.js","sources":["../../../../../agent-runtime/src/use-deep-agent-window-sync.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport { useAuiState } from '@assistant-ui/store';\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport { DEEP_AGENT_INTEREST_PROTOCOL } from './generated/runconfig-contract';\nimport {\n buildToolOutputCommand,\n type DeepAgentInterestRequest,\n type DeepAgentMessageWindow,\n interestsCovered,\n pageInterestRequests,\n readDeepAgentMessageWindow,\n readToolOutputResult,\n readTruncatedToolOutputArtifact,\n} from './message-window';\nimport { hasStatewireThreadExtras } from './thread-extras';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\n\n/**\n * Pages of older history chained per approach to the top. A renderer lowers\n * its near-top level once prepended content has pushed the first message out\n * of its band; this bounds the case where it cannot (no viewport to scroll,\n * a list too short to overflow) so a 2,000-message thread never streams whole.\n */\nexport const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;\n\n/**\n * Pages of older history that add no converted message — every message on\n * them folds into the first loaded turn, such as one agent run's hundreds of\n * tool steps — loaded on top of a request (or an approach's chain) before it\n * stops. Such a page changes nothing the user can see, so it neither answers\n * an ask nor counts against the per-approach chain.\n */\nexport const DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS = 25;\n\n/** The converted thread messages the tool-output half scans (web and native `ThreadMessage` both satisfy it). */\nexport interface DeepAgentWindowSyncMessage {\n readonly id: string;\n /** The converted role; lets the opening fill tell a turn's prompt from its reply. */\n readonly role?: string;\n readonly content: readonly { readonly type: string; readonly artifact?: unknown }[];\n}\n\n/** One page interest round trip, for the host's telemetry. */\nexport interface DeepAgentHistoryLoadEvent {\n /** The page's ordinal (`1` extends the head). */\n page: number;\n request: DeepAgentInterestRequest;\n durationMs: number;\n}\n\nexport interface UseDeepAgentWindowSyncOptions {\n /**\n * The converted thread messages — read by the host through its platform\n * `useAuiState((s) => s.thread.messages)`, so this hook imports neither\n * `@assistant-ui/react` nor `@assistant-ui/react-native`.\n */\n messages: readonly DeepAgentWindowSyncMessage[];\n /** Messages per page; the thread's window size by default. */\n pageSize?: number;\n /**\n * Full tool outputs fetched back for cut tool messages; the same store the\n * thread converts with (`useDeepAgentThread({ toolOutputs })`). Omitted, the\n * tool-output half is inert (a surface that never shows a cut output whole).\n */\n toolOutputs?: DeepAgentToolOutputStore | undefined;\n /**\n * The renderer's report that the top of the LOADED history is near — a\n * level, not an edge: while it holds and older messages exist, pages load\n * one after another (bounded by `maxChainedLoads` per approach). Omitted for\n * hosts with only a manual affordance (`loadOlder`).\n */\n nearTop?: boolean;\n /** Bumped on every rise of `nearTop` (and every explicit request), so the chain bound is per approach. */\n nearTopEpoch?: number;\n /**\n * Whether a message's content is mounted right now, so lazy fetches (cut\n * tool outputs) target what the user can see rather than the whole loaded\n * history. Omitted: every message counts as mounted (the flat renderers).\n */\n isMessageMounted?: ((messageId: string) => boolean) | undefined;\n maxChainedLoads?: number;\n /** Pages adding no converted message loaded per request before it stops; see {@link DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS}. */\n maxUnseenLoads?: number;\n /** A page interest resolved (telemetry). */\n onHistoryLoad?: ((event: DeepAgentHistoryLoadEvent) => void) | undefined;\n /** A read failed; the sync itself recovers (the pending marks are released). */\n onError?: ((error: unknown, command: 'athena/interest' | 'history/tool_output') => void) | undefined;\n now?: () => number;\n}\n\nexport interface DeepAgentWindowSyncState {\n /** The joined window, or `null` while the head interest has not resolved (both halves are inert). */\n window: DeepAgentMessageWindow | null;\n /** Whether the host holds messages older than the loaded window. */\n hasOlder: boolean;\n /**\n * Whether the next page can be asked for: older messages exist and the\n * host's interest cap has room for them. `hasOlder && !canLoadOlder` is the\n * depth limit (`MAX_INTERESTS × MAX_MESSAGE_WINDOW` messages loaded in one\n * connection) — an edge row says so instead of offering a dead button.\n */\n canLoadOlder: boolean;\n /** A page of older history is in flight. */\n loading: boolean;\n /** Ask for the next page of older history now (an edge row's button, a keypress). A no-op before the head resolved or at the beginning. */\n loadOlder: () => void;\n}\n\nconst everyMessageMounted = (): boolean => true;\nconst defaultNow = (): number => Date.now();\nconst noopSubscribe = () => () => {};\n\n/** The statewire extras of the nearest aui thread; throws on a non-statewire thread like the library's own hooks. */\nconst useStatewireExtras = (): StatewireThread.Extras =>\n useAuiState((s) => {\n if (!hasStatewireThreadExtras(s.thread.extras)) {\n throw new Error('useDeepAgentWindowSync requires a statewire thread');\n }\n return s.thread.extras as StatewireThread.Extras;\n });\n\n/** The joined interest window of the nearest statewire thread. */\nexport function useDeepAgentMessageWindow(): DeepAgentMessageWindow | null {\n const documents = useStatewireExtras().documents;\n const mounted = useSyncExternalStore(\n documents?.subscribe ?? noopSubscribe,\n () => documents?.list(),\n () => documents?.list()\n );\n return useMemo(() => readDeepAgentMessageWindow(mounted), [mounted]);\n}\n\n/**\n * The client half of the interest window, shared by every surface — mounted\n * once per runtime, inside its aui provider.\n *\n * - **Older history.** While the host renderer reports the top of the loaded\n * history near (`nearTop`) and the window says older messages exist, this\n * re-states the interests with one more page (anchored at the window's\n * first message) — the host mounts its documents for this client alone —\n * chaining at most `maxChainedLoads` pages per approach; `loadOlder` asks\n * for one page on demand (an edge row's button). Never two loads in flight.\n * A reconnect whose hello does not carry the interests this mount last\n * stated (the host remembers a client id's view across its attaches; a new\n * host instance does not) re-states them.\n * - **Cut tool outputs.** Tool cards whose output the wire carried cut\n * (`artifact._athena_content_truncated`) get it fetched whole through\n * `history/tool_output` once their message is mounted; the converter puts\n * it back (`toolOutputs`), so the card re-renders complete. An output the\n * host replaced since (the marker's `chars` changed) is fetched again.\n */\n/**\n * Whether an older page put a new converted message ahead of the thread's\n * first one. Older history only ever merges into or lands before the first\n * converted message, so the second one is a stable landmark: it moved down iff\n * the page showed something. A new tail message does not move it. Without a\n * second message (or once it is gone) the converted count decides.\n */\nfunction pageShowedEarlierMessage(\n from: { count: number; secondId: string | undefined },\n messages: readonly DeepAgentWindowSyncMessage[]\n): boolean {\n if (from.secondId !== undefined) {\n const index = messages.findIndex((message) => message.id === from.secondId);\n if (index !== -1) return index > 1;\n }\n return messages.length > from.count;\n}\n\n/**\n * Whether the loaded thread still opens without context: it should open on a\n * prompt and hold at least one earlier turn, so the newest turn shows with the\n * one before it (a turn is a prompt followed by its reply). Queued and live\n * prompts land at the tail with no reply yet, so they never count; prompts\n * alone need nothing. Without roles, a lone converted message stands in for it.\n */\nfunction opensMidTurn(messages: readonly DeepAgentWindowSyncMessage[]): boolean {\n const first = messages[0];\n if (first === undefined) return false;\n if (messages.every((message) => message.role === undefined)) return messages.length < 2;\n if (first.role !== 'user') return true;\n if (messages.every((message) => message.role === 'user')) return false;\n let turns = 0;\n for (let index = 1; index < messages.length; index += 1) {\n if (messages[index - 1]!.role === 'user' && messages[index]!.role !== 'user') turns += 1;\n }\n return turns < 2;\n}\n\nexport function useDeepAgentWindowSync({\n messages,\n pageSize,\n toolOutputs,\n nearTop = false,\n nearTopEpoch = 0,\n isMessageMounted = everyMessageMounted,\n maxChainedLoads = DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,\n maxUnseenLoads = DEEP_AGENT_MAX_UNSEEN_HISTORY_LOADS,\n onHistoryLoad,\n onError,\n now = defaultNow,\n}: UseDeepAgentWindowSyncOptions): DeepAgentWindowSyncState {\n const { sendCommand, invoke, connection } = useStatewireExtras();\n const window = useDeepAgentMessageWindow();\n const [loading, setLoading] = useState(false);\n const [requests, setRequests] = useState(0);\n const servedRequestsRef = useRef(0);\n const inflightRef = useRef(false);\n const chainRef = useRef({ epoch: 0, loads: 0, unseen: 0, requested: false });\n // Pages loaded to show the opening turn's prompt; `null` once it shows, the\n // user took over, or a page failed — never re-armed for this mount.\n const openingFillRef = useRef<number | null>(0);\n // The converted thread when the in-flight page was stated; `null` once its\n // settle was judged (or it failed).\n const pageFromRef = useRef<{ count: number; secondId: string | undefined } | null>(null);\n const aliveRef = useRef(true);\n // The interests this mount last stated, re-stated on the next connected\n // session (a hello resets the documents) so a reconnect keeps the loaded history.\n const statedRef = useRef<DeepAgentInterestRequest[] | null>(null);\n const restatedConnectionRef = useRef<unknown>(null);\n // Outputs already asked for and answered by this mount — fetched, refused,\n // or failed — by the `chars` they were asked for. The converter re-runs on\n // every wire change, and the store is a bounded LRU: without this memory a\n // refused read would leave on every pass, and once a transcript holds more\n // cut outputs than the store retains, each fetch would evict a still-loaded\n // output and the next pass would fetch it again, forever. An evicted output\n // renders its cut text (the REST display limit) rather than re-entering the\n // loop; a marker whose `chars` moved (the host replaced the output) is asked\n // for again.\n const answeredRef = useRef(new Map<string, number>());\n const onHistoryLoadRef = useRef(onHistoryLoad);\n onHistoryLoadRef.current = onHistoryLoad;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const nowRef = useRef(now);\n nowRef.current = now;\n useEffect(() => {\n aliveRef.current = true;\n return () => {\n aliveRef.current = false;\n };\n }, []);\n\n useEffect(() => {\n if (connection.status !== 'connected' || restatedConnectionRef.current === connection) return;\n // Decided once per connected session, on the hello's interest document.\n if (window === null) return;\n restatedConnectionRef.current = connection;\n const stated = statedRef.current;\n if (stated === null || interestsCovered(window.requests, stated)) return;\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [stated]).catch((error: unknown) => {\n onErrorRef.current?.(error, 'athena/interest');\n });\n }, [connection, invoke, window]);\n\n useEffect(() => {\n if (window === null || inflightRef.current) return;\n const from = pageFromRef.current;\n pageFromRef.current = null;\n const lastPageUnseen =\n from !== null && from.count > 0 && !pageShowedEarlierMessage(from, messages);\n const pageRequests = pageInterestRequests(window, pageSize);\n if (pageRequests === null) return;\n const requested = requests !== servedRequestsRef.current;\n const chain = chainRef.current;\n let fillPage = false;\n if (\n openingFillRef.current !== null &&\n (requested || nearTop || (messages.length > 0 && !opensMidTurn(messages)))\n ) {\n openingFillRef.current = null;\n }\n if (requested) {\n // An explicit ask re-arms the chain for this approach.\n servedRequestsRef.current = requests;\n chainRef.current = { epoch: nearTopEpoch, loads: 1, unseen: 0, requested: true };\n } else if (lastPageUnseen && (chain.requested || (nearTop && chain.epoch === nearTopEpoch))) {\n // The page landed inside the first loaded turn: keep going until one shows.\n if (chain.unseen >= maxUnseenLoads) return;\n chain.unseen += 1;\n } else if (openingFillRef.current !== null && opensMidTurn(messages)) {\n if (openingFillRef.current >= maxUnseenLoads) return;\n openingFillRef.current += 1;\n fillPage = true;\n } else {\n if (!nearTop) return;\n if (chain.epoch !== nearTopEpoch) {\n chainRef.current = { epoch: nearTopEpoch, loads: 0, unseen: 0, requested: false };\n }\n if (chainRef.current.loads >= maxChainedLoads) return;\n chainRef.current.loads += 1;\n }\n pageFromRef.current = { count: messages.length, secondId: messages[1]?.id };\n const page = window.pages + 1;\n const request = pageRequests[pageRequests.length - 1] as DeepAgentInterestRequest;\n inflightRef.current = true;\n setLoading(true);\n const startedAt = nowRef.current();\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [pageRequests])\n .then(() => {\n statedRef.current = pageRequests;\n onHistoryLoadRef.current?.({\n page,\n request,\n durationMs: Math.max(0, Math.round(nowRef.current() - startedAt)),\n });\n })\n .catch((error: unknown) => {\n pageFromRef.current = null;\n if (fillPage) openingFillRef.current = null;\n onErrorRef.current?.(error, 'athena/interest');\n })\n .finally(() => {\n inflightRef.current = false;\n if (aliveRef.current) setLoading(false);\n });\n // `loading` re-arms the chain once a page settled after its documents moved the window.\n }, [\n nearTop,\n nearTopEpoch,\n requests,\n window,\n loading,\n messages,\n invoke,\n maxChainedLoads,\n maxUnseenLoads,\n pageSize,\n ]);\n\n useEffect(() => {\n if (window === null || toolOutputs === undefined) return;\n for (const message of messages) {\n if (!isMessageMounted(message.id)) continue;\n for (const part of message.content) {\n if (part.type !== 'tool-call') continue;\n const marker = readTruncatedToolOutputArtifact(part.artifact);\n if (marker === null || toolOutputs.isPending(marker.messageId)) continue;\n // Fetched for this very length already; a different length means the\n // host replaced the output under the same id since.\n if (toolOutputs.entry(marker.messageId)?.chars === marker.chars) continue;\n if (answeredRef.current.get(marker.messageId) === marker.chars) continue;\n const { messageId, chars } = marker;\n toolOutputs.markPending(messageId);\n Promise.resolve(sendCommand(buildToolOutputCommand({ messageId })))\n .then((payload) => {\n answeredRef.current.set(messageId, chars);\n const result = readToolOutputResult(payload);\n if (result === null) {\n toolOutputs.clearPending(messageId);\n return;\n }\n toolOutputs.set(result.messageId, { content: result.content, chars });\n })\n .catch((error: unknown) => {\n answeredRef.current.set(messageId, chars);\n toolOutputs.clearPending(messageId);\n onErrorRef.current?.(error, 'history/tool_output');\n });\n }\n }\n }, [messages, isMessageMounted, window, sendCommand, toolOutputs]);\n\n const loadOlder = useCallback(() => {\n setRequests((count) => count + 1);\n }, []);\n\n const canLoadOlder = useMemo(\n () => window !== null && pageInterestRequests(window, pageSize) !== null,\n [window, pageSize]\n );\n\n return { window, hasOlder: window?.hasOlder ?? false, canLoadOlder, loading, loadOlder };\n}\n"],"names":["_a"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const version = "0.26.2";
3
+ const version = "0.26.5";
4
4
  const packageJson = {
5
5
  version
6
6
  };
@@ -1,4 +1,4 @@
1
- const version = "0.26.2";
1
+ const version = "0.26.5";
2
2
  const packageJson = {
3
3
  version
4
4
  };
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const core = require("@tiptap/core");
4
+ const model = require("@tiptap/pm/model");
5
+ function escapeTableCellPipes(markdown) {
6
+ return markdown.replace(/\|/g, "\\|");
7
+ }
8
+ function markdownHtmlOption(editor) {
9
+ const storage = Reflect.get(editor.storage, "markdown");
10
+ const options = typeof storage === "object" && storage !== null ? Reflect.get(storage, "options") : void 0;
11
+ const html = typeof options === "object" && options !== null ? Reflect.get(options, "html") : void 0;
12
+ if (typeof html !== "boolean") {
13
+ throw new Error("tiptap-markdown is not registered on this editor");
14
+ }
15
+ return html;
16
+ }
17
+ function renderCellInline({
18
+ state,
19
+ cellContent
20
+ }) {
21
+ const { text, write } = state;
22
+ state.text = (content, escapeMarkdown) => {
23
+ const start = state.out.length;
24
+ text.call(state, content, escapeMarkdown);
25
+ state.out = state.out.slice(0, start) + escapeTableCellPipes(state.out.slice(start));
26
+ };
27
+ state.write = (content) => {
28
+ write.call(state, content === void 0 ? content : escapeTableCellPipes(content));
29
+ };
30
+ try {
31
+ state.renderInline(cellContent);
32
+ } finally {
33
+ state.text = text;
34
+ state.write = write;
35
+ }
36
+ }
37
+ function hasSpan(cell) {
38
+ return cell.attrs.colspan > 1 || cell.attrs.rowspan > 1;
39
+ }
40
+ function isMarkdownSerializable(table) {
41
+ const [firstRow, ...bodyRows] = table.children;
42
+ const headerCells = (firstRow == null ? void 0 : firstRow.children) ?? [];
43
+ if (headerCells.some(
44
+ (cell) => cell.type.name !== "tableHeader" || hasSpan(cell) || cell.childCount > 1
45
+ )) {
46
+ return false;
47
+ }
48
+ return !bodyRows.some(
49
+ (row) => row.children.some(
50
+ (cell) => cell.type.name === "tableHeader" || hasSpan(cell) || cell.childCount > 1
51
+ )
52
+ );
53
+ }
54
+ function formatHtmlBlock(html) {
55
+ const body = new window.DOMParser().parseFromString(`<body>${html}</body>`, "text/html").body;
56
+ const element = body.firstElementChild;
57
+ if (!element) return html;
58
+ element.innerHTML = element.innerHTML.trim() ? `
59
+ ${element.innerHTML}
60
+ ` : "\n";
61
+ return element.outerHTML;
62
+ }
63
+ function serializeTableAsHtml({
64
+ editor,
65
+ state,
66
+ node,
67
+ parent
68
+ }) {
69
+ if (markdownHtmlOption(editor)) {
70
+ const { schema } = node.type;
71
+ const html = core.getHTMLFromFragment(model.Fragment.from(node), schema);
72
+ const isTopLevel = parent instanceof model.Fragment || parent.type.name === schema.topNodeType.name;
73
+ state.write(isTopLevel ? formatHtmlBlock(html) : html);
74
+ } else {
75
+ console.warn(`Tiptap Markdown: "${node.type.name}" node is only available in html mode`);
76
+ state.write(`[${node.type.name}]`);
77
+ }
78
+ state.closeBlock(node);
79
+ }
80
+ function serializeMarkdownTable(state, node, parent) {
81
+ if (!isMarkdownSerializable(node)) {
82
+ serializeTableAsHtml({ editor: this.editor, state, node, parent });
83
+ return;
84
+ }
85
+ state.inTable = true;
86
+ node.forEach((row, _rowOffset, rowIndex) => {
87
+ state.write("| ");
88
+ row.forEach((cell, _cellOffset, cellIndex) => {
89
+ if (cellIndex) {
90
+ state.write(" | ");
91
+ }
92
+ const cellContent = cell.firstChild;
93
+ if (cellContent == null ? void 0 : cellContent.textContent.trim()) {
94
+ renderCellInline({ state, cellContent });
95
+ }
96
+ });
97
+ state.write(" |");
98
+ state.ensureNewLine();
99
+ if (!rowIndex) {
100
+ const delimiterRow = Array.from({ length: row.childCount }, () => "---").join(" | ");
101
+ state.write(`| ${delimiterRow} |`);
102
+ state.ensureNewLine();
103
+ }
104
+ });
105
+ state.closeBlock(node);
106
+ state.inTable = false;
107
+ }
108
+ function markdownTableStorage() {
109
+ return { markdown: { serialize: serializeMarkdownTable } };
110
+ }
111
+ exports.escapeTableCellPipes = escapeTableCellPipes;
112
+ exports.markdownTableStorage = markdownTableStorage;
113
+ exports.serializeMarkdownTable = serializeMarkdownTable;
114
+ //# sourceMappingURL=markdown-table-serializer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-table-serializer.cjs","sources":["../../../../../tiptap-markdown-table/src/markdown-table-serializer.ts"],"sourcesContent":["/**\n * The table writer every Tiptap editor that writes Markdown through\n * tiptap-markdown shares: Olympus's docs `TableNode` and Skill editor, and the\n * `@athenaintel/react` chat composer's `ChatTableExtension`. A table node takes\n * it through {@link markdownTableStorage}.\n */\nimport { type Editor, getHTMLFromFragment } from \"@tiptap/core\";\nimport { Fragment, type Node as ProseMirrorNode } from \"@tiptap/pm/model\";\n\n/**\n * A table cell's markdown with each `|` escaped, so none of them ends the cell.\n * GFM ends a cell at every unescaped pipe, inside a code span or a link target\n * too; markdown-it drops the backslash of each `\\|` as it splits the row, so the\n * cell (and any code span in it) reads back with its literal pipe. The AOP\n * converter's markdown read escapes cells the same way\n * (`agora/converter-olympus/src/utils/turndown-helpers.ts`).\n */\nexport function escapeTableCellPipes(markdown: string): string {\n return markdown.replace(/\\|/g, \"\\\\|\");\n}\n\n/**\n * What the table serializer uses of tiptap-markdown's serializer state:\n * prosemirror-markdown's `MarkdownSerializerState` plus tiptap-markdown's\n * `inTable` flag, which makes a hard break inside a cell write `<br>`.\n */\ninterface MarkdownTableSerializerState {\n out: string;\n inTable: boolean;\n write(content?: string): void;\n text(text: string, escapeMarkdown?: boolean): void;\n ensureNewLine(): void;\n closeBlock(node: ProseMirrorNode): void;\n renderInline(parent: ProseMirrorNode, fromBlockStart?: boolean): void;\n}\n\n/** The `this` tiptap-markdown binds a node's `serialize` to. */\ninterface MarkdownSpecContext {\n editor: Editor;\n}\n\n/**\n * tiptap-markdown's `html` option, from the storage it keeps in\n * `editor.storage.markdown`. Tiptap 3 types `editor.storage` as an interface\n * each extension augments, and tiptap-markdown's own typings declare only\n * `getMarkdown()`, so the option is read through a guard rather than by\n * augmenting `@tiptap/core` for every editor that imports this module. Throws\n * when tiptap-markdown is not registered on the editor.\n */\nfunction markdownHtmlOption(editor: Editor): boolean {\n const storage: unknown = Reflect.get(editor.storage, \"markdown\");\n const options: unknown =\n typeof storage === \"object\" && storage !== null ? Reflect.get(storage, \"options\") : undefined;\n const html: unknown =\n typeof options === \"object\" && options !== null ? Reflect.get(options, \"html\") : undefined;\n if (typeof html !== \"boolean\") {\n throw new Error(\"tiptap-markdown is not registered on this editor\");\n }\n return html;\n}\n\n/**\n * Renders a cell's inline content with every `|` it writes escaped. Everything\n * a cell's inline content writes goes through the state's `text` (text, code\n * spans, mark delimiters, link targets) or `write` (inline nodes such as\n * mentions, images and inline HTML), so both are wrapped for the cell and\n * restored after it. Escaping as the output is written, not afterwards, keeps\n * the output offsets tiptap-markdown records to move emphasis delimiters in\n * step with the output.\n */\nfunction renderCellInline({\n state,\n cellContent,\n}: {\n state: MarkdownTableSerializerState;\n cellContent: ProseMirrorNode;\n}): void {\n const { text, write } = state;\n state.text = (content, escapeMarkdown) => {\n const start = state.out.length;\n text.call(state, content, escapeMarkdown);\n state.out = state.out.slice(0, start) + escapeTableCellPipes(state.out.slice(start));\n };\n state.write = (content) => {\n write.call(state, content === undefined ? content : escapeTableCellPipes(content));\n };\n try {\n state.renderInline(cellContent);\n } finally {\n state.text = text;\n state.write = write;\n }\n}\n\nfunction hasSpan(cell: ProseMirrorNode): boolean {\n return cell.attrs.colspan > 1 || cell.attrs.rowspan > 1;\n}\n\n/**\n * A GFM pipe table holds one header row of single-paragraph header cells over\n * body rows of single-paragraph data cells, with no merged cells. Any other\n * table is written as HTML.\n */\nfunction isMarkdownSerializable(table: ProseMirrorNode): boolean {\n const [firstRow, ...bodyRows] = table.children;\n const headerCells = firstRow?.children ?? [];\n if (\n headerCells.some(\n (cell) => cell.type.name !== \"tableHeader\" || hasSpan(cell) || cell.childCount > 1,\n )\n ) {\n return false;\n }\n return !bodyRows.some((row) =>\n row.children.some(\n (cell) => cell.type.name === \"tableHeader\" || hasSpan(cell) || cell.childCount > 1,\n ),\n );\n}\n\n/** An HTML block as CommonMark reads one: the element's content on lines of its own. */\nfunction formatHtmlBlock(html: string): string {\n const body = new window.DOMParser().parseFromString(`<body>${html}</body>`, \"text/html\").body;\n const element = body.firstElementChild;\n if (!element) return html;\n element.innerHTML = element.innerHTML.trim() ? `\\n${element.innerHTML}\\n` : \"\\n\";\n return element.outerHTML;\n}\n\nfunction serializeTableAsHtml({\n editor,\n state,\n node,\n parent,\n}: {\n editor: Editor;\n state: MarkdownTableSerializerState;\n node: ProseMirrorNode;\n parent: ProseMirrorNode | Fragment;\n}): void {\n if (markdownHtmlOption(editor)) {\n const { schema } = node.type;\n const html = getHTMLFromFragment(Fragment.from(node), schema);\n const isTopLevel = parent instanceof Fragment || parent.type.name === schema.topNodeType.name;\n state.write(isTopLevel ? formatHtmlBlock(html) : html);\n } else {\n console.warn(`Tiptap Markdown: \"${node.type.name}\" node is only available in html mode`);\n state.write(`[${node.type.name}]`);\n }\n state.closeBlock(node);\n}\n\n/**\n * tiptap-markdown 0.9.0's table serializer, except that a `|` inside a cell is\n * written as `\\|` (see {@link escapeTableCellPipes}). The library writes it\n * bare — it escapes only `<` / `>` in text, and prosemirror-markdown only\n * `` `*\\~[]_ `` — so a cell holding `a | b` or `` `x|y` `` read back as extra\n * columns and markdown-it dropped every cell past the header's width. A table\n * that is not a GFM pipe table is still written as HTML, and everything else is\n * written exactly as the library writes it.\n */\nexport function serializeMarkdownTable(\n this: MarkdownSpecContext,\n state: MarkdownTableSerializerState,\n node: ProseMirrorNode,\n parent: ProseMirrorNode | Fragment,\n): void {\n if (!isMarkdownSerializable(node)) {\n serializeTableAsHtml({ editor: this.editor, state, node, parent });\n return;\n }\n state.inTable = true;\n node.forEach((row, _rowOffset, rowIndex) => {\n state.write(\"| \");\n row.forEach((cell, _cellOffset, cellIndex) => {\n if (cellIndex) {\n state.write(\" | \");\n }\n const cellContent = cell.firstChild;\n if (cellContent?.textContent.trim()) {\n renderCellInline({ state, cellContent });\n }\n });\n state.write(\" |\");\n state.ensureNewLine();\n if (!rowIndex) {\n const delimiterRow = Array.from({ length: row.childCount }, () => \"---\").join(\" | \");\n state.write(`| ${delimiterRow} |`);\n state.ensureNewLine();\n }\n });\n state.closeBlock(node);\n state.inTable = false;\n}\n\n/**\n * The storage that makes tiptap-markdown serialize a table node with\n * {@link serializeMarkdownTable}: tiptap-markdown reads a node's markdown spec\n * from `storage.markdown`, over its own spec for the node's name.\n */\nexport function markdownTableStorage(): {\n markdown: { serialize: typeof serializeMarkdownTable };\n} {\n return { markdown: { serialize: serializeMarkdownTable } };\n}\n"],"names":["getHTMLFromFragment","Fragment"],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ import { getHTMLFromFragment } from "@tiptap/core";
2
+ import { Fragment } from "@tiptap/pm/model";
3
+ function escapeTableCellPipes(markdown) {
4
+ return markdown.replace(/\|/g, "\\|");
5
+ }
6
+ function markdownHtmlOption(editor) {
7
+ const storage = Reflect.get(editor.storage, "markdown");
8
+ const options = typeof storage === "object" && storage !== null ? Reflect.get(storage, "options") : void 0;
9
+ const html = typeof options === "object" && options !== null ? Reflect.get(options, "html") : void 0;
10
+ if (typeof html !== "boolean") {
11
+ throw new Error("tiptap-markdown is not registered on this editor");
12
+ }
13
+ return html;
14
+ }
15
+ function renderCellInline({
16
+ state,
17
+ cellContent
18
+ }) {
19
+ const { text, write } = state;
20
+ state.text = (content, escapeMarkdown) => {
21
+ const start = state.out.length;
22
+ text.call(state, content, escapeMarkdown);
23
+ state.out = state.out.slice(0, start) + escapeTableCellPipes(state.out.slice(start));
24
+ };
25
+ state.write = (content) => {
26
+ write.call(state, content === void 0 ? content : escapeTableCellPipes(content));
27
+ };
28
+ try {
29
+ state.renderInline(cellContent);
30
+ } finally {
31
+ state.text = text;
32
+ state.write = write;
33
+ }
34
+ }
35
+ function hasSpan(cell) {
36
+ return cell.attrs.colspan > 1 || cell.attrs.rowspan > 1;
37
+ }
38
+ function isMarkdownSerializable(table) {
39
+ const [firstRow, ...bodyRows] = table.children;
40
+ const headerCells = (firstRow == null ? void 0 : firstRow.children) ?? [];
41
+ if (headerCells.some(
42
+ (cell) => cell.type.name !== "tableHeader" || hasSpan(cell) || cell.childCount > 1
43
+ )) {
44
+ return false;
45
+ }
46
+ return !bodyRows.some(
47
+ (row) => row.children.some(
48
+ (cell) => cell.type.name === "tableHeader" || hasSpan(cell) || cell.childCount > 1
49
+ )
50
+ );
51
+ }
52
+ function formatHtmlBlock(html) {
53
+ const body = new window.DOMParser().parseFromString(`<body>${html}</body>`, "text/html").body;
54
+ const element = body.firstElementChild;
55
+ if (!element) return html;
56
+ element.innerHTML = element.innerHTML.trim() ? `
57
+ ${element.innerHTML}
58
+ ` : "\n";
59
+ return element.outerHTML;
60
+ }
61
+ function serializeTableAsHtml({
62
+ editor,
63
+ state,
64
+ node,
65
+ parent
66
+ }) {
67
+ if (markdownHtmlOption(editor)) {
68
+ const { schema } = node.type;
69
+ const html = getHTMLFromFragment(Fragment.from(node), schema);
70
+ const isTopLevel = parent instanceof Fragment || parent.type.name === schema.topNodeType.name;
71
+ state.write(isTopLevel ? formatHtmlBlock(html) : html);
72
+ } else {
73
+ console.warn(`Tiptap Markdown: "${node.type.name}" node is only available in html mode`);
74
+ state.write(`[${node.type.name}]`);
75
+ }
76
+ state.closeBlock(node);
77
+ }
78
+ function serializeMarkdownTable(state, node, parent) {
79
+ if (!isMarkdownSerializable(node)) {
80
+ serializeTableAsHtml({ editor: this.editor, state, node, parent });
81
+ return;
82
+ }
83
+ state.inTable = true;
84
+ node.forEach((row, _rowOffset, rowIndex) => {
85
+ state.write("| ");
86
+ row.forEach((cell, _cellOffset, cellIndex) => {
87
+ if (cellIndex) {
88
+ state.write(" | ");
89
+ }
90
+ const cellContent = cell.firstChild;
91
+ if (cellContent == null ? void 0 : cellContent.textContent.trim()) {
92
+ renderCellInline({ state, cellContent });
93
+ }
94
+ });
95
+ state.write(" |");
96
+ state.ensureNewLine();
97
+ if (!rowIndex) {
98
+ const delimiterRow = Array.from({ length: row.childCount }, () => "---").join(" | ");
99
+ state.write(`| ${delimiterRow} |`);
100
+ state.ensureNewLine();
101
+ }
102
+ });
103
+ state.closeBlock(node);
104
+ state.inTable = false;
105
+ }
106
+ function markdownTableStorage() {
107
+ return { markdown: { serialize: serializeMarkdownTable } };
108
+ }
109
+ export {
110
+ escapeTableCellPipes,
111
+ markdownTableStorage,
112
+ serializeMarkdownTable
113
+ };
114
+ //# sourceMappingURL=markdown-table-serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-table-serializer.js","sources":["../../../../../tiptap-markdown-table/src/markdown-table-serializer.ts"],"sourcesContent":["/**\n * The table writer every Tiptap editor that writes Markdown through\n * tiptap-markdown shares: Olympus's docs `TableNode` and Skill editor, and the\n * `@athenaintel/react` chat composer's `ChatTableExtension`. A table node takes\n * it through {@link markdownTableStorage}.\n */\nimport { type Editor, getHTMLFromFragment } from \"@tiptap/core\";\nimport { Fragment, type Node as ProseMirrorNode } from \"@tiptap/pm/model\";\n\n/**\n * A table cell's markdown with each `|` escaped, so none of them ends the cell.\n * GFM ends a cell at every unescaped pipe, inside a code span or a link target\n * too; markdown-it drops the backslash of each `\\|` as it splits the row, so the\n * cell (and any code span in it) reads back with its literal pipe. The AOP\n * converter's markdown read escapes cells the same way\n * (`agora/converter-olympus/src/utils/turndown-helpers.ts`).\n */\nexport function escapeTableCellPipes(markdown: string): string {\n return markdown.replace(/\\|/g, \"\\\\|\");\n}\n\n/**\n * What the table serializer uses of tiptap-markdown's serializer state:\n * prosemirror-markdown's `MarkdownSerializerState` plus tiptap-markdown's\n * `inTable` flag, which makes a hard break inside a cell write `<br>`.\n */\ninterface MarkdownTableSerializerState {\n out: string;\n inTable: boolean;\n write(content?: string): void;\n text(text: string, escapeMarkdown?: boolean): void;\n ensureNewLine(): void;\n closeBlock(node: ProseMirrorNode): void;\n renderInline(parent: ProseMirrorNode, fromBlockStart?: boolean): void;\n}\n\n/** The `this` tiptap-markdown binds a node's `serialize` to. */\ninterface MarkdownSpecContext {\n editor: Editor;\n}\n\n/**\n * tiptap-markdown's `html` option, from the storage it keeps in\n * `editor.storage.markdown`. Tiptap 3 types `editor.storage` as an interface\n * each extension augments, and tiptap-markdown's own typings declare only\n * `getMarkdown()`, so the option is read through a guard rather than by\n * augmenting `@tiptap/core` for every editor that imports this module. Throws\n * when tiptap-markdown is not registered on the editor.\n */\nfunction markdownHtmlOption(editor: Editor): boolean {\n const storage: unknown = Reflect.get(editor.storage, \"markdown\");\n const options: unknown =\n typeof storage === \"object\" && storage !== null ? Reflect.get(storage, \"options\") : undefined;\n const html: unknown =\n typeof options === \"object\" && options !== null ? Reflect.get(options, \"html\") : undefined;\n if (typeof html !== \"boolean\") {\n throw new Error(\"tiptap-markdown is not registered on this editor\");\n }\n return html;\n}\n\n/**\n * Renders a cell's inline content with every `|` it writes escaped. Everything\n * a cell's inline content writes goes through the state's `text` (text, code\n * spans, mark delimiters, link targets) or `write` (inline nodes such as\n * mentions, images and inline HTML), so both are wrapped for the cell and\n * restored after it. Escaping as the output is written, not afterwards, keeps\n * the output offsets tiptap-markdown records to move emphasis delimiters in\n * step with the output.\n */\nfunction renderCellInline({\n state,\n cellContent,\n}: {\n state: MarkdownTableSerializerState;\n cellContent: ProseMirrorNode;\n}): void {\n const { text, write } = state;\n state.text = (content, escapeMarkdown) => {\n const start = state.out.length;\n text.call(state, content, escapeMarkdown);\n state.out = state.out.slice(0, start) + escapeTableCellPipes(state.out.slice(start));\n };\n state.write = (content) => {\n write.call(state, content === undefined ? content : escapeTableCellPipes(content));\n };\n try {\n state.renderInline(cellContent);\n } finally {\n state.text = text;\n state.write = write;\n }\n}\n\nfunction hasSpan(cell: ProseMirrorNode): boolean {\n return cell.attrs.colspan > 1 || cell.attrs.rowspan > 1;\n}\n\n/**\n * A GFM pipe table holds one header row of single-paragraph header cells over\n * body rows of single-paragraph data cells, with no merged cells. Any other\n * table is written as HTML.\n */\nfunction isMarkdownSerializable(table: ProseMirrorNode): boolean {\n const [firstRow, ...bodyRows] = table.children;\n const headerCells = firstRow?.children ?? [];\n if (\n headerCells.some(\n (cell) => cell.type.name !== \"tableHeader\" || hasSpan(cell) || cell.childCount > 1,\n )\n ) {\n return false;\n }\n return !bodyRows.some((row) =>\n row.children.some(\n (cell) => cell.type.name === \"tableHeader\" || hasSpan(cell) || cell.childCount > 1,\n ),\n );\n}\n\n/** An HTML block as CommonMark reads one: the element's content on lines of its own. */\nfunction formatHtmlBlock(html: string): string {\n const body = new window.DOMParser().parseFromString(`<body>${html}</body>`, \"text/html\").body;\n const element = body.firstElementChild;\n if (!element) return html;\n element.innerHTML = element.innerHTML.trim() ? `\\n${element.innerHTML}\\n` : \"\\n\";\n return element.outerHTML;\n}\n\nfunction serializeTableAsHtml({\n editor,\n state,\n node,\n parent,\n}: {\n editor: Editor;\n state: MarkdownTableSerializerState;\n node: ProseMirrorNode;\n parent: ProseMirrorNode | Fragment;\n}): void {\n if (markdownHtmlOption(editor)) {\n const { schema } = node.type;\n const html = getHTMLFromFragment(Fragment.from(node), schema);\n const isTopLevel = parent instanceof Fragment || parent.type.name === schema.topNodeType.name;\n state.write(isTopLevel ? formatHtmlBlock(html) : html);\n } else {\n console.warn(`Tiptap Markdown: \"${node.type.name}\" node is only available in html mode`);\n state.write(`[${node.type.name}]`);\n }\n state.closeBlock(node);\n}\n\n/**\n * tiptap-markdown 0.9.0's table serializer, except that a `|` inside a cell is\n * written as `\\|` (see {@link escapeTableCellPipes}). The library writes it\n * bare — it escapes only `<` / `>` in text, and prosemirror-markdown only\n * `` `*\\~[]_ `` — so a cell holding `a | b` or `` `x|y` `` read back as extra\n * columns and markdown-it dropped every cell past the header's width. A table\n * that is not a GFM pipe table is still written as HTML, and everything else is\n * written exactly as the library writes it.\n */\nexport function serializeMarkdownTable(\n this: MarkdownSpecContext,\n state: MarkdownTableSerializerState,\n node: ProseMirrorNode,\n parent: ProseMirrorNode | Fragment,\n): void {\n if (!isMarkdownSerializable(node)) {\n serializeTableAsHtml({ editor: this.editor, state, node, parent });\n return;\n }\n state.inTable = true;\n node.forEach((row, _rowOffset, rowIndex) => {\n state.write(\"| \");\n row.forEach((cell, _cellOffset, cellIndex) => {\n if (cellIndex) {\n state.write(\" | \");\n }\n const cellContent = cell.firstChild;\n if (cellContent?.textContent.trim()) {\n renderCellInline({ state, cellContent });\n }\n });\n state.write(\" |\");\n state.ensureNewLine();\n if (!rowIndex) {\n const delimiterRow = Array.from({ length: row.childCount }, () => \"---\").join(\" | \");\n state.write(`| ${delimiterRow} |`);\n state.ensureNewLine();\n }\n });\n state.closeBlock(node);\n state.inTable = false;\n}\n\n/**\n * The storage that makes tiptap-markdown serialize a table node with\n * {@link serializeMarkdownTable}: tiptap-markdown reads a node's markdown spec\n * from `storage.markdown`, over its own spec for the node's name.\n */\nexport function markdownTableStorage(): {\n markdown: { serialize: typeof serializeMarkdownTable };\n} {\n return { markdown: { serialize: serializeMarkdownTable } };\n}\n"],"names":[],"mappings":"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"}
@@ -128,4 +128,4 @@ export interface AthenaProviderProps {
128
128
  * error handling, so integrations never fail silently. */
129
129
  onError?: (error: AthenaSdkError, event: AthenaDiagnosticEvent) => void;
130
130
  }
131
- export declare function AthenaProvider({ children, config, apiKey, token: tokenProp, agent, channel, model, tools, frontendTools, disableAutoOpen, apiUrl, backendUrl, appUrl, environment, statewireSyncUrl, getToken, extraRunConfig, workbench, knowledgeBase, systemPrompt, appId, threadId: threadIdProp, enableThreadList, threadListIncludePullRequests, theme, linkClicks, citationLinks, posthog: posthogProp, debug, onDiagnostic, onError, }: AthenaProviderProps): import("react/jsx-runtime").JSX.Element | null;
131
+ export declare function AthenaProvider({ children, config, apiKey, token: tokenProp, agent, channel, model, tools, frontendTools, disableAutoOpen, apiUrl, backendUrl, appUrl, environment, statewireSyncUrl, getToken, extraRunConfig, workbench, knowledgeBase, systemPrompt, appId, threadId: threadIdProp, enableThreadList, threadListIncludePullRequests, theme, linkClicks, citationLinks, posthog: posthogProp, debug, onDiagnostic, onError, }: AthenaProviderProps): import("react").JSX.Element | null;
@@ -11,4 +11,4 @@ export declare function getPostHogInstance<TClient = unknown>(): TClient | null;
11
11
  export declare function PostHogProvider({ children, config, }: {
12
12
  children: ReactNode;
13
13
  config?: PostHogConfig;
14
- }): import("react/jsx-runtime").JSX.Element;
14
+ }): import("react").JSX.Element;
@@ -57,4 +57,4 @@ export declare const SessionListSkeleton: FC<{
57
57
  * state appears only after a settled empty answer, and a background refresh
58
58
  * never blanks the rows it already has.
59
59
  */
60
- export declare function SessionList({ className, grouped, showSearch, showPinToggle, showRename, showArchive, prefetchOnHover, }: SessionListProps): import("react/jsx-runtime").JSX.Element | null;
60
+ export declare function SessionList({ className, grouped, showSearch, showPinToggle, showRename, showArchive, prefetchOnHover, }: SessionListProps): import("react").JSX.Element | null;
@@ -6,4 +6,4 @@ export interface ThreadListProps {
6
6
  * `<AthenaProvider enableThreadList>` provides and renders nothing outside
7
7
  * that mode — a standalone provider hosts exactly one thread.
8
8
  */
9
- export declare function ThreadList({ className }: ThreadListProps): import("react/jsx-runtime").JSX.Element | null;
9
+ export declare function ThreadList({ className }: ThreadListProps): import("react").JSX.Element | null;
@@ -191,7 +191,7 @@ export declare function AthenaStatewireThreadListProvider({ backendUrl, syncUrl,
191
191
  includePullRequests?: boolean;
192
192
  snapshotCache?: DeepAgentThreadSnapshotCache;
193
193
  children: ReactNode;
194
- }): import("react/jsx-runtime").JSX.Element;
194
+ }): import("react").JSX.Element;
195
195
  /** How long after a thread's first message the title poll starts (exported for tests). */
196
196
  export declare const TITLE_POLL_DELAY_MS = 5000;
197
197
  /**
@@ -32,7 +32,7 @@ export interface ToolCardProps {
32
32
  * `ToolFallback` shell), so a dedicated UI and a generic fallback share one
33
33
  * anatomy there; with no provider it is the boxed card below, unchanged.
34
34
  */
35
- export declare function ToolCard(props: ToolCardProps): import("react/jsx-runtime").JSX.Element;
35
+ export declare function ToolCard(props: ToolCardProps): import("react").JSX.Element;
36
36
  /** Copies `{ tool_name, arguments, result }` as JSON — the tool spec a support ticket needs. */
37
37
  export declare function CopyToolSpecButton({ toolName, args, argsText, result, className, }: {
38
38
  toolName: string;
@@ -40,9 +40,9 @@ export declare function CopyToolSpecButton({ toolName, args, argsText, result, c
40
40
  argsText?: string;
41
41
  result?: unknown;
42
42
  className?: string;
43
- }): import("react/jsx-runtime").JSX.Element;
43
+ }): import("react").JSX.Element;
44
44
  export declare function ExpandableSection({ label, children, defaultOpen, }: {
45
45
  label?: string;
46
46
  children: ReactNode;
47
47
  defaultOpen?: boolean;
48
- }): import("react/jsx-runtime").JSX.Element;
48
+ }): import("react").JSX.Element;
@@ -62,7 +62,7 @@ export type ToolFallbackRootProps = Omit<React.ComponentProps<typeof Collapsible
62
62
  defaultOpen?: boolean;
63
63
  appearance?: ToolAppearance;
64
64
  };
65
- declare function ToolFallbackRoot({ className, open: controlledOpen, onOpenChange: controlledOnOpenChange, defaultOpen, appearance: appearanceProp, children, ...props }: ToolFallbackRootProps): import("react/jsx-runtime").JSX.Element;
65
+ declare function ToolFallbackRoot({ className, open: controlledOpen, onOpenChange: controlledOnOpenChange, defaultOpen, appearance: appearanceProp, children, ...props }: ToolFallbackRootProps): import("react").JSX.Element;
66
66
  export interface ToolFallbackTriggerProps extends Omit<React.ComponentProps<typeof CollapsibleTrigger>, "children"> {
67
67
  toolName: string;
68
68
  argsText?: string;
@@ -80,18 +80,18 @@ export interface ToolFallbackTriggerProps extends Omit<React.ComponentProps<type
80
80
  /** A short count or state chip after the target ("8 results"). */
81
81
  badge?: string;
82
82
  }
83
- declare function ToolFallbackTrigger({ toolName, argsText, result, status, isError, classification: givenClassification, displayName, activeLabel, icon, appearance: appearanceProp, secondary: secondaryProp, badge, className, ...props }: ToolFallbackTriggerProps): import("react/jsx-runtime").JSX.Element;
83
+ declare function ToolFallbackTrigger({ toolName, argsText, result, status, isError, classification: givenClassification, displayName, activeLabel, icon, appearance: appearanceProp, secondary: secondaryProp, badge, className, ...props }: ToolFallbackTriggerProps): import("react").JSX.Element;
84
84
  declare function ToolFallbackContent({ className, children, appearance: appearanceProp, ...props }: React.ComponentProps<typeof CollapsibleContent> & {
85
85
  appearance?: ToolAppearance;
86
- }): import("react/jsx-runtime").JSX.Element;
86
+ }): import("react").JSX.Element;
87
87
  declare function ToolFallbackArgs({ argsText, hideInternalIdArgs, className, ...props }: React.ComponentProps<"div"> & {
88
88
  argsText?: string;
89
89
  hideInternalIdArgs?: boolean;
90
- }): import("react/jsx-runtime").JSX.Element | null;
90
+ }): import("react").JSX.Element | null;
91
91
  declare function ToolFallbackResult({ result, classification, className, ...props }: React.ComponentProps<"div"> & {
92
92
  result?: unknown;
93
93
  classification?: ToolResultClassification;
94
- }): import("react/jsx-runtime").JSX.Element | null;
94
+ }): import("react").JSX.Element | null;
95
95
  /**
96
96
  * The failure a status-incomplete call carries, for the expanded body. The
97
97
  * always-visible failure line is {@link ToolFallbackNotice}; this repeats the
@@ -99,7 +99,7 @@ declare function ToolFallbackResult({ result, classification, className, ...prop
99
99
  */
100
100
  declare function ToolFallbackError({ status, className, ...props }: React.ComponentProps<"div"> & {
101
101
  status?: ToolCallMessagePartStatus;
102
- }): import("react/jsx-runtime").JSX.Element | null;
102
+ }): import("react").JSX.Element | null;
103
103
  /**
104
104
  * The always-visible line under the header for a failed or paused call — the
105
105
  * failure's code and message, or the runtime's pause notice — so a reader
@@ -108,7 +108,7 @@ declare function ToolFallbackError({ status, className, ...props }: React.Compon
108
108
  declare function ToolFallbackNotice({ classification, appearance: appearanceProp, className, ...props }: React.ComponentProps<"div"> & {
109
109
  classification: ToolResultClassification;
110
110
  appearance?: ToolAppearance;
111
- }): import("react/jsx-runtime").JSX.Element | null;
111
+ }): import("react").JSX.Element | null;
112
112
  /**
113
113
  * Sets the tool-card anatomy for every tool call rendered below it — generic
114
114
  * fallbacks, dedicated tool UIs built on `ToolCard`, nested PTC sub-calls.
@@ -118,7 +118,7 @@ declare function ToolFallbackNotice({ classification, appearance: appearanceProp
118
118
  export declare function ToolFallbackAppearanceProvider({ appearance, children, }: {
119
119
  appearance: ToolAppearance;
120
120
  children?: ReactNode;
121
- }): import("react/jsx-runtime").JSX.Element;
121
+ }): import("react").JSX.Element;
122
122
  declare const ToolFallback: ToolCallMessagePartComponent & ((props: ToolFallbackProps) => ReactNode) & {
123
123
  Root: typeof ToolFallbackRoot;
124
124
  Trigger: typeof ToolFallbackTrigger;
@@ -6,5 +6,5 @@ declare const buttonVariants: (props?: ({
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
8
8
  asChild?: boolean;
9
- }): import("react/jsx-runtime").JSX.Element;
9
+ }): React.JSX.Element;
10
10
  export { Button, buttonVariants };
@@ -1,5 +1,5 @@
1
1
  import { Collapsible as CollapsiblePrimitive } from "radix-ui";
2
- declare function Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>): import("react/jsx-runtime").JSX.Element;
3
- declare function CollapsibleTrigger({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>): import("react/jsx-runtime").JSX.Element;
4
- declare function CollapsibleContent({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>): import("react/jsx-runtime").JSX.Element;
2
+ declare function Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>): import("react").JSX.Element;
3
+ declare function CollapsibleTrigger({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>): import("react").JSX.Element;
4
+ declare function CollapsibleContent({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>): import("react").JSX.Element;
5
5
  export { Collapsible, CollapsibleTrigger, CollapsibleContent };
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { Popover as PopoverPrimitive } from "radix-ui";
3
- declare function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
4
- declare function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
5
- declare function PopoverContent({ className, style, align, sideOffset, collisionPadding, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
3
+ declare function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>): React.JSX.Element;
4
+ declare function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>): React.JSX.Element;
5
+ declare function PopoverContent({ className, style, align, sideOffset, collisionPadding, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>): React.JSX.Element;
6
6
  export { Popover, PopoverTrigger, PopoverContent };
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { Tooltip as TooltipPrimitive } from "radix-ui";
3
- declare function TooltipProvider({ delayDuration, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>): import("react/jsx-runtime").JSX.Element;
4
- declare function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
5
- declare function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
6
- declare function TooltipContent({ className, sideOffset, children, ...props }: React.ComponentProps<typeof TooltipPrimitive.Content>): import("react/jsx-runtime").JSX.Element;
3
+ declare function TooltipProvider({ delayDuration, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>): React.JSX.Element;
4
+ declare function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>): React.JSX.Element;
5
+ declare function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): React.JSX.Element;
6
+ declare function TooltipContent({ className, sideOffset, children, ...props }: React.ComponentProps<typeof TooltipPrimitive.Content>): React.JSX.Element;
7
7
  export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };