Render streamed assistant responses as Markdown

This commit is contained in:
yuxuanhui
2026-09-08 14:36:05 +08:00
parent aef8e1d310
commit 80cb7d2b80
7 changed files with 363 additions and 4 deletions
+122
View File
@@ -20,6 +20,9 @@ importers:
ai:
specifier: 6.0.277
version: 6.0.277(zod@4.5.4)
markstream-react:
specifier: 2.0.8
version: 2.0.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
react:
specifier: 19.2.8
version: 19.2.8
@@ -728,6 +731,10 @@ packages:
electron-to-chromium@1.5.422:
resolution: {integrity: sha512-UvA/32XqrLDdZSn7Jllo1AYNcWji/G0d5M0GTViE7KoGBiMunw3a34Sb2KO4ZZyrSEhqsxFoVhWWJshdyfKqJA==}
entities@8.1.0:
resolution: {integrity: sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==}
engines: {node: '>=20.19.0'}
esast-util-from-estree@2.0.0:
resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==}
@@ -916,6 +923,9 @@ packages:
resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
engines: {node: '>= 12.0.0'}
linkify-it@6.1.0:
resolution: {integrity: sha512-wJ/TwpSDTLepCrQoYWYIExIKg5Zchex2Nn5yk2mFnB+6PtdkHtyLx742md9csRjjOnGkKIS/RrbY7l8D6gT9Vw==}
linkifyjs@4.3.3:
resolution: {integrity: sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==}
@@ -939,9 +949,56 @@ packages:
resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==}
engines: {node: '>=16'}
markdown-it-container@4.0.0:
resolution: {integrity: sha512-HaNccxUH0l7BNGYbFbjmGpf5aLHAMTinqRZQAEQbMr2cdD3z91Q6kIo1oUn1CQndkT03jat6ckrdRYuwwqLlQw==}
markdown-it-footnote@4.0.0:
resolution: {integrity: sha512-WYJ7urf+khJYl3DqofQpYfEYkZKbmXmwxQV8c8mO/hGIhgZ1wOe7R4HLFNwqx7TjILbnC98fuyeSsin19JdFcQ==}
markdown-it-ins@4.0.0:
resolution: {integrity: sha512-sWbjK2DprrkINE4oYDhHdCijGT+MIDhEupjSHLXe5UXeVr5qmVxs/nTUVtgi0Oh/qtF+QKV0tNWDhQBEPxiMew==}
markdown-it-mark@4.0.0:
resolution: {integrity: sha512-YLhzaOsU9THO/cal0lUjfMjrqSMPjjyjChYM7oyj4DnyaXEzA8gnW6cVJeyCrCVeyesrY2PlEdUYJSPFYL4Nkg==}
markdown-it-sup@2.0.0:
resolution: {integrity: sha512-5VgmdKlkBd8sgXuoDoxMpiU+BiEt3I49GItBzzw7Mxq9CxvnhE/k09HFli09zgfFDRixDQDfDxi0mgBCXtaTvA==}
markdown-it-task-checkbox@1.0.6:
resolution: {integrity: sha512-7pxkHuvqTOu3iwVGmDPeYjQg+AIS9VQxzyLP9JCg9lBjgPAJXGEkChK6A2iFuj3tS0GV3HG2u5AMNhcQqwxpJw==}
markdown-it-ts@1.1.2:
resolution: {integrity: sha512-17qO3LQLK+JXom5Zt6Z9l7OGWWv9eYquTxdj3xIPGe1OBHdYXrzNYA3xCgCyIj1uItv4jkqbQf6FkaqifKkySw==}
engines: {node: '>=20.19'}
markdown-table@3.0.4:
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
markstream-core@2.0.8:
resolution: {integrity: sha512-3VLe2fMDhoe0SnH5OXsmdXfT6vrsY8/WetNE02xR8AuTaP7ixH2tBl9dHTsLgiLMp/z8D+TB0xVP/tkLzkmNlA==}
markstream-react@2.0.8:
resolution: {integrity: sha512-LRWCOkzvl4T4d1IWBAG3buJBnazNX1qmkND9ns66RGdF3un194CTXS9A/Qc0kZT7NvIcJvCsCiLoDJ42J1UAOw==}
peerDependencies:
'@antv/infographic': ^0.2.3
'@terrastruct/d2': '>=0.1.33'
katex: '>=0.16.22'
mermaid: '>=11'
react: '>=18'
react-dom: '>=18'
stream-diffs: '>=0.0.2'
peerDependenciesMeta:
'@antv/infographic':
optional: true
'@terrastruct/d2':
optional: true
katex:
optional: true
mermaid:
optional: true
stream-diffs:
optional: true
mdast-util-find-and-replace@3.0.2:
resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
@@ -990,6 +1047,9 @@ packages:
mdast-util-to-string@4.0.0:
resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
mdurl@2.1.0:
resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==}
memoize-one@5.2.1:
resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==}
@@ -1195,6 +1255,10 @@ packages:
prosemirror-view@1.42.3:
resolution: {integrity: sha512-oTN7EtH+CpwxU9NrwEYWd0UZ4JUx7l048l5A2Xppm4p/60isZYLnth9QVQmC3VRIvdrIWCxwZSd+Uz791G31/w==}
punycode.js@2.3.1:
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
engines: {node: '>=6'}
react-dom@19.2.8:
resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==}
peerDependencies:
@@ -1291,6 +1355,9 @@ packages:
space-separated-tokens@2.0.2:
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
stream-markdown-parser@1.2.14:
resolution: {integrity: sha512-7nZR7ZUM8uPmXGMZPcP3wPtb40Ce8NUJy6XDGmengRENxE824VD6o6dbPvosUVE07mxG58LgdL+VU7BeOSEvAQ==}
stringify-entities@4.0.4:
resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
@@ -1327,6 +1394,9 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
uc.micro@3.0.0:
resolution: {integrity: sha512-U3PppEkleoTnIfi8BozMx3yju3qc/L6SwqWo2Sw+54PX+PX0q9I+r1Um5HCmqD7n9VDX5/v3vQH/AjA6deDdtw==}
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
@@ -2173,6 +2243,8 @@ snapshots:
electron-to-chromium@1.5.422: {}
entities@8.1.0: {}
esast-util-from-estree@2.0.0:
dependencies:
'@types/estree-jsx': 1.0.5
@@ -2360,6 +2432,10 @@ snapshots:
lightningcss-win32-arm64-msvc: 1.33.0
lightningcss-win32-x64-msvc: 1.33.0
linkify-it@6.1.0:
dependencies:
uc.micro: 3.0.0
linkifyjs@4.3.3: {}
lodash@4.18.1: {}
@@ -2378,8 +2454,38 @@ snapshots:
markdown-extensions@2.0.0: {}
markdown-it-container@4.0.0: {}
markdown-it-footnote@4.0.0: {}
markdown-it-ins@4.0.0: {}
markdown-it-mark@4.0.0: {}
markdown-it-sup@2.0.0: {}
markdown-it-task-checkbox@1.0.6: {}
markdown-it-ts@1.1.2:
dependencies:
entities: 8.1.0
linkify-it: 6.1.0
mdurl: 2.1.0
punycode.js: 2.3.1
markdown-table@3.0.4: {}
markstream-core@2.0.8: {}
markstream-react@2.0.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8):
dependencies:
'@floating-ui/dom': 1.8.0
clsx: 2.1.1
markstream-core: 2.0.8
react: 19.2.8
react-dom: 19.2.8(react@19.2.8)
stream-markdown-parser: 1.2.14
mdast-util-find-and-replace@3.0.2:
dependencies:
'@types/mdast': 4.0.4
@@ -2543,6 +2649,8 @@ snapshots:
dependencies:
'@types/mdast': 4.0.4
mdurl@2.1.0: {}
memoize-one@5.2.1: {}
micromark-core-commonmark@2.0.3:
@@ -2931,6 +3039,8 @@ snapshots:
prosemirror-state: 1.4.4
prosemirror-transform: 1.12.1
punycode.js@2.3.1: {}
react-dom@19.2.8(react@19.2.8):
dependencies:
react: 19.2.8
@@ -3078,6 +3188,16 @@ snapshots:
space-separated-tokens@2.0.2: {}
stream-markdown-parser@1.2.14:
dependencies:
markdown-it-container: 4.0.0
markdown-it-footnote: 4.0.0
markdown-it-ins: 4.0.0
markdown-it-mark: 4.0.0
markdown-it-sup: 2.0.0
markdown-it-task-checkbox: 1.0.6
markdown-it-ts: 1.1.2
stringify-entities@4.0.4:
dependencies:
character-entities-html4: 2.1.0
@@ -3112,6 +3232,8 @@ snapshots:
typescript@5.9.3: {}
uc.micro@3.0.0: {}
undici-types@6.21.0: {}
undici@6.28.1: {}