Browse Source

feat: 增加app会话AI,引入agent-ui

lizhaocai 2 days ago
parent
commit
2fabe1dca2
100 changed files with 22614 additions and 243 deletions
  1. 7 0
      App.vue
  2. 246 0
      components/agent-ui/chatFile/index.vue
  3. 80 0
      components/agent-ui/collapse/index.vue
  4. 63 0
      components/agent-ui/collapsibleCard/index.vue
  5. 428 0
      components/agent-ui/feedback/index.vue
  6. 1821 0
      components/agent-ui/index.vue
  7. 47 0
      components/agent-ui/markdownPreview/index.vue
  8. 98 0
      components/agent-ui/markdownPreview/towxml/audio-player/Audio.js
  9. 320 0
      components/agent-ui/markdownPreview/towxml/audio-player/audio-player.vue
  10. 288 0
      components/agent-ui/markdownPreview/towxml/config.js
  11. 274 0
      components/agent-ui/markdownPreview/towxml/decode.vue
  12. 127 0
      components/agent-ui/markdownPreview/towxml/img/img.vue
  13. 18 0
      components/agent-ui/markdownPreview/towxml/index.js
  14. 987 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/highlight.js
  15. 22 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/index.js
  16. 107 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/bash.js
  17. 237 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/c-like.js
  18. 20 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/c.js
  19. 138 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/css.js
  20. 126 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/dart.js
  21. 68 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/go.js
  22. 67 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/htmlbars.js
  23. 122 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/java.js
  24. 287 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/javascript.js
  25. 56 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/json.js
  26. 201 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/less.js
  27. 34 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/python-repl.js
  28. 159 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/python.js
  29. 112 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/scss.js
  30. 23 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/shell.js
  31. 201 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/typescript.js
  32. 164 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/languages/xml.js
  33. 99 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/style/github.css
  34. 71 0
      components/agent-ui/markdownPreview/towxml/parse/highlight/style/monokai.css
  35. 113 0
      components/agent-ui/markdownPreview/towxml/parse/index.js
  36. 64 0
      components/agent-ui/markdownPreview/towxml/parse/markdown/index.js
  37. 6632 0
      components/agent-ui/markdownPreview/towxml/parse/markdown/markdown.js
  38. 143 0
      components/agent-ui/markdownPreview/towxml/parse/markdown/plugins/ins.js
  39. 143 0
      components/agent-ui/markdownPreview/towxml/parse/markdown/plugins/mark.js
  40. 104 0
      components/agent-ui/markdownPreview/towxml/parse/markdown/plugins/sub.js
  41. 104 0
      components/agent-ui/markdownPreview/towxml/parse/markdown/plugins/sup.js
  42. 499 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/Parser.js
  43. 806 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/Tokenizer.js
  44. 66 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/domelementtype/index.js
  45. 145 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/domhandler/index.js
  46. 484 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/domhandler/node.js
  47. 203 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/entities/decode.js
  48. 63 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/entities/decode_codepoint.js
  49. 80 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/entities/encode.js
  50. 115 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/entities/escape.js
  51. 12 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/entities/generated/decode-data-html.js
  52. 12 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/entities/generated/decode-data-xml.js
  53. 265 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/entities/generated/encode-html.js
  54. 271 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/entities/index.js
  55. 8 0
      components/agent-ui/markdownPreview/towxml/parse/parse2/index.js
  56. 405 0
      components/agent-ui/markdownPreview/towxml/style/main.css
  57. 72 0
      components/agent-ui/markdownPreview/towxml/style/theme/dark.css
  58. 60 0
      components/agent-ui/markdownPreview/towxml/style/theme/light.css
  59. 52 0
      components/agent-ui/markdownPreview/towxml/table/table.vue
  60. 46 0
      components/agent-ui/markdownPreview/towxml/towxml.vue
  61. 16 0
      components/agent-ui/markdownPreview/utils.js
  62. 120 0
      components/agent-ui/tools.js
  63. 383 0
      components/agent-ui/wd-markdown/index.vue
  64. 854 0
      components/agent-ui/wd-markdown/utils/highlight.min.js
  65. 119 0
      components/agent-ui/wd-markdown/utils/hljs_css.min.js
  66. 331 0
      components/agent-ui/wd-markdown/utils/hljs_javascript.min.js
  67. 2328 0
      components/agent-ui/wd-markdown/utils/markdown-it.min.js
  68. 32 0
      components/agent-ui/wd-markdown/utils/plugin.js
  69. 3 1
      main.js
  70. 10 0
      pages.json
  71. 0 240
      pages/discovery/discovery.vue
  72. 100 0
      pages/index/aichat.vue
  73. 177 2
      pages/index/index.vue
  74. 2 0
      static/components/agent-ui/imgs/arrow.svg
  75. 2 0
      static/components/agent-ui/imgs/camera.svg
  76. 2 0
      static/components/agent-ui/imgs/clear.svg
  77. BIN
      static/components/agent-ui/imgs/close-filled.png
  78. 2 0
      static/components/agent-ui/imgs/close.svg
  79. 2 0
      static/components/agent-ui/imgs/copy.svg
  80. 1 0
      static/components/agent-ui/imgs/excel.svg
  81. 2 0
      static/components/agent-ui/imgs/file.svg
  82. 1 0
      static/components/agent-ui/imgs/image.svg
  83. 2 0
      static/components/agent-ui/imgs/internet.svg
  84. 2 0
      static/components/agent-ui/imgs/internetUse.svg
  85. 12 0
      static/components/agent-ui/imgs/loading.svg
  86. 1 0
      static/components/agent-ui/imgs/pdf.svg
  87. 2 0
      static/components/agent-ui/imgs/search.svg
  88. 2 0
      static/components/agent-ui/imgs/send.svg
  89. 2 0
      static/components/agent-ui/imgs/set.svg
  90. 2 0
      static/components/agent-ui/imgs/share.svg
  91. 2 0
      static/components/agent-ui/imgs/star-highlight.svg
  92. 2 0
      static/components/agent-ui/imgs/star.svg
  93. 2 0
      static/components/agent-ui/imgs/stop.svg
  94. 2 0
      static/components/agent-ui/imgs/system-sum.svg
  95. 2 0
      static/components/agent-ui/imgs/thumb-down.svg
  96. 2 0
      static/components/agent-ui/imgs/thumb-up.svg
  97. 2 0
      static/components/agent-ui/imgs/toBottom.svg
  98. 2 0
      static/components/agent-ui/imgs/uploadImg.svg
  99. 1 0
      static/components/agent-ui/imgs/word.svg
  100. 0 0
      static/components/agent-ui/markdownPreview/towxml/audio-player/loading.svg

+ 7 - 0
App.vue

@@ -5,6 +5,13 @@
   
 	export default {
 		onLaunch: function() {
+			if (!wx.cloud) {
+			    console.error('请使用 2.2.3 或以上的基础库以使用云能力');
+			} else {
+			    wx.cloud.init({
+			        env: 'cloud1-6g83nk504b196aa9'
+			    });
+			}
 			uni.getSystemInfo({
 			  success: function(e) {
 			    // #ifndef H5

+ 246 - 0
components/agent-ui/chatFile/index.vue

@@ -0,0 +1,246 @@
+<template>
+    <!-- components/agent-ui-new/chatFIle/chatFile.wxml -->
+    <!-- <text>components/agent-ui-new/chatFIle/chatFile.wxml</text> -->
+    <view class="chat_file">
+        <view class="chat_file__content">
+            <image class="chat_file__icon" :src="iconPath" />
+            <view class="chat_file__info">
+                <view class="chat_file__name">{{ fileData.fileName }}</view>
+                <view class="chat_file__size">
+                    {{ formatSize }}
+                    <image v-if="!fileData.fileId" style="width: 20px; height: 20px" src="/static/components/agent-ui/imgs/loading.svg" mode="" />
+                </view>
+            </view>
+        </view>
+        <image
+            v-if="'enableDel'"
+            @tap="removeFileFromParents"
+            style="width: 15px; height: 15px; position: absolute; top: 0px; right: 0px"
+            src="/static/components/agent-ui/imgs/close-filled.png"
+            mode="aspectFill"
+        />
+    </view>
+</template>
+
+<script>
+// components/agent-ui-new/chatFIle/chatFile.js
+export default {
+    data() {
+        return {
+            formatSize: '',
+            iconPath: '/static/components/agent-ui/imgs/file.svg'
+        };
+    },
+
+    mounted() {
+        // 处理小程序 attached 生命周期
+        this.attached();
+    },
+
+    watch: {
+        'fileData.fileId': function (fileId) {
+            if (!fileId) {
+                this.setData({
+                    formatSize: '解析中'
+                });
+            } else {
+                this.setData({
+                    formatSize: this.transformSize(this.fileData.fileSize)
+                });
+            }
+        }
+    },
+
+    /**
+     * 组件的属性列表
+     */
+    props: {
+        enableDel: {
+            type: Boolean,
+            default: true
+        },
+        fileData: {
+            type: Object,
+            default: () => ({
+                tempId: '',
+                rawType: '',
+                fileName: '',
+                tempPath: '',
+                fileSize: 0,
+                fileUrl: '',
+                fileId: ''
+            })
+        }
+    },
+
+    /**
+     * 组件的方法列表,
+     */
+    methods: {
+        attached: function () {
+            // const formatSize = this.transformSize(this.data.fileSize)
+            const { fileName, tempPath, fileId } = this.fileData;
+            const type = this.getFileType(fileName);
+            console.log('type', type);
+            if (fileId) {
+                this.setData({
+                    formatSize: this.transformSize(this.fileData.fileSize),
+                    iconPath: '/static/components/agent-ui/imgs/' + type + '.svg'
+                });
+                return;
+            }
+            this.setData({
+                formatSize: '解析中',
+                iconPath: '/static/components/agent-ui/imgs/' + type + '.svg'
+            });
+			
+			// 上传云存储获取 fileId
+			  wx.cloud.uploadFile({
+			    cloudPath: fileName, // 云上文件路径
+			    filePath: tempPath, // 本地文件路径
+			    success: res => {
+			        console.log('上传成功,fileID为:', res.fileID);
+			        // 此时你可以使用res.fileID进行后续操作
+			        // this.setData({
+			        //   fileData: {
+			        //     ...this.data.fileData,
+			        //     fileId: res.fileID
+			        //   }
+			        // })
+			        this.triggerEvent('changeChild', {tempId: this.data.fileData.tempId, fileId: res.fileID})
+			    },
+			    fail: err => {
+			        console.error('上传失败:', err);
+			    }
+			});
+
+            // 上传云存储获取 fileId
+            // uniCloud.uploadFile({
+            //     cloudPath: fileName,
+
+            //     // 云上文件路径
+            //     filePath: tempPath,
+
+            //     // 本地文件路径
+            //     success: (res) => {
+            //         console.log('上传成功,fileID为:', res.fileID);
+            //         // 此时你可以使用res.fileID进行后续操作
+            //         // this.setData({
+            //         //   fileData: {
+            //         //     ...this.data.fileData,
+            //         //     fileId: res.fileID
+            //         //   }
+            //         // })
+            //         this.$emit('changeChild', {
+            //             detail: {
+            //                 tempId: this.fileData.tempId,
+            //                 fileId: res.fileID
+            //             }
+            //         });
+            //     },
+
+            //     fail: (err) => {
+            //         console.error('上传失败:', err);
+            //     }
+            // });
+        },
+
+        // 提取文件后缀
+        getFileType: function (fileName) {
+            let index = fileName.lastIndexOf('.');
+            const fileExt = fileName.substring(index + 1);
+            if (fileExt === 'docx' || fileExt === 'doc') {
+                return 'word';
+            }
+            if (fileExt === 'xlsx' || fileExt === 'xls') {
+                return 'excel';
+            }
+            if (fileExt === 'png' || fileExt === 'jpg' || fileExt === 'jpeg' || fileExt === 'svg') {
+                return 'image';
+            }
+            if (fileExt === 'pdf') {
+                return 'pdf';
+            }
+            return 'file';
+        },
+
+        // getFileIcon: function (fileName) {
+        //   const type = this.getFileType(fileName)
+        //   console.log('type', type)
+        //   if(type === 'pdf') {
+        //     return 'pdf.png'
+        //   }
+
+        //   return 'image.png'
+        // },
+        // 转换文件大小(原始单位为B)
+        transformSize: function (size) {
+            if (size < 1024) {
+                return size + 'B';
+            } else if (size < 1048576) {
+                return (size / 1024).toFixed(2) + 'KB';
+            } else {
+                return (size / 1024 / 1024).toFixed(2) + 'MB';
+            }
+        },
+
+        removeFileFromParents: function () {
+            console.log('remove', this.fileData);
+            this.$emit('removeChild', {
+                detail: {
+                    tempId: this.fileData.tempId
+                }
+            });
+        }
+    },
+
+    created: function () {}
+};
+</script>
+<style>
+/* components/agent-ui-new/chatFIle/chatFile.wxss */
+.chat_file {
+    padding: 24rpx;
+    background: #ffffff;
+    border-radius: 12rpx;
+    box-shadow: 0 1px 8px rgba(0, 0, 0, 0.253);
+    margin: 16rpx 5rpx;
+    width: 130px;
+    position: relative;
+}
+
+.chat_file:active {
+    background: #f9f9f9;
+}
+
+.chat_file__content {
+    display: flex;
+    align-items: center;
+    gap: 24rpx;
+}
+
+.chat_file__icon {
+    width: 80rpx;
+    height: 80rpx;
+    flex-shrink: 0;
+}
+
+.chat_file__info {
+    flex: 1;
+    min-width: 0;
+}
+
+.chat_file__name {
+    font-size: 28rpx;
+    color: #333333;
+    margin-bottom: 8rpx;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.chat_file__size {
+    font-size: 24rpx;
+    color: #999999;
+}
+</style>

+ 80 - 0
components/agent-ui/collapse/index.vue

@@ -0,0 +1,80 @@
+<template>
+    <!-- components/agent-ui/collapsibleCard/index.wxml -->
+    <view class="collapse" :style="collapsedStatus && showBgColor ? 'background-color: #f5f5f5;' : ''">
+        <view class="collapse-header" @tap="changeCollapsedStatus">
+            <slot name="title"></slot>
+            <image
+                src="/static/components/agent-ui/imgs/arrow.svg"
+                mode="aspectFill"
+                :style="'width: 16px;height: 16px;transform: rotate(' + (collapsedStatus ? 0 : 180) + 'deg);'"
+            />
+        </view>
+        <block v-if="collapsedStatus">
+            <slot name="content"></slot>
+        </block>
+    </view>
+</template>
+
+<script>
+// components/agent-ui/collapsibleCard/index.js
+export default {
+    data() {
+        return {
+            collapsedStatus: false
+        };
+    },
+    /**
+     * 组件的属性列表
+     */
+    props: {
+        initStatus: {
+            type: Boolean,
+            default: false
+        },
+        showBgColor: {
+            type: Boolean,
+            default: false
+        }
+    },
+    mounted() {
+        // 处理小程序 attached 生命周期
+        this.attached();
+    },
+    /**
+     * 组件的方法列表
+     */
+    methods: {
+        attached() {
+            this.setData({
+                collapsedStatus: this.initStatus
+            });
+        },
+
+        changeCollapsedStatus: function () {
+            this.setData({
+                collapsedStatus: !this.collapsedStatus
+            });
+        }
+    },
+    options: {
+        multipleSlots: true
+    },
+    created: function () {}
+};
+</script>
+<style>
+/* components/agent-ui/collapsibleCard/index.wxss */
+.collapse {
+    border-radius: 8px;
+    margin-bottom: 12px;
+}
+.collapse-header {
+    display: inline-flex;
+    align-items: center;
+    gap: 8px;
+    background-color: #f5f5f5;
+    justify-content: space-between;
+    padding: 18rpx 26rpx;
+    border-radius: 8px;
+}
+</style>

+ 63 - 0
components/agent-ui/collapsibleCard/index.vue

@@ -0,0 +1,63 @@
+<template>
+    <!-- components/agent-ui/collapsibleCard/index.wxml -->
+    <view>
+        <view @tap="changeCollapsedStatus" style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px">
+            <slot name="title"></slot>
+            <image
+                src="/static/components/agent-ui/imgs/arrow.svg"
+                mode="aspectFill"
+                :style="'width: 16px;height: 16px;transform: rotate(' + (collapsedStatus ? 0 : 180) + 'deg);'"
+            />
+        </view>
+        <block v-if="collapsedStatus">
+            <slot name="content"></slot>
+        </block>
+    </view>
+</template>
+
+<script>
+// components/agent-ui/collapsibleCard/index.js
+export default {
+    data() {
+        return {
+            collapsedStatus: false
+        };
+    },
+    /**
+     * 组件的属性列表
+     */
+    props: {
+        initStatus: {
+            type: Boolean,
+            default: false
+        }
+    },
+    mounted() {
+        // 处理小程序 attached 生命周期
+        this.attached();
+    },
+    /**
+     * 组件的方法列表
+     */
+    methods: {
+        attached() {
+            this.setData({
+                collapsedStatus: this.initStatus
+            });
+        },
+
+        changeCollapsedStatus: function () {
+            this.setData({
+                collapsedStatus: !this.collapsedStatus
+            });
+        }
+    },
+    options: {
+        multipleSlots: true
+    },
+    created: function () {}
+};
+</script>
+<style>
+/* components/agent-ui/collapsibleCard/index.wxss */
+</style>

+ 428 - 0
components/agent-ui/feedback/index.vue

@@ -0,0 +1,428 @@
+<template>
+    <view class="feedback-modal" v-if="isShowFeedback">
+        <view class="feedback">
+            <view class="feedback-header">感谢您的宝贵反馈,我们会不断改进服务</view>
+            <view class="feedback-body">
+                <view class="item-box">
+                    <view class="item-title">评分</view>
+                    <view style="display: flex; gap: 14rpx">
+                        <block v-for="(item, index) in [1, 2, 3, 4, 5]" :key="index">
+                            <image
+                                :src="item <= score ? '/static/components/agent-ui/imgs/star-highlight.svg' : '/static/components/agent-ui/imgs/star.svg'"
+                                mode="aspectFill"
+                                class="star"
+                                @touchend="onChangeScore"
+                                :data-score="item"
+                            />
+                        </block>
+                    </view>
+                </view>
+                <view class="item-box">
+                    <view class="item-title">回答内容</view>
+                    <view>
+                        <block v-for="(item, index) in feedbackType === 'upvote' ? upVote : downVote" :key="index">
+                            <view :class="item.selected ? 'vote-item-highlight' : 'vote-item-normal'" @tap="onSelect" :data-item="item">{{ item.value }}</view>
+                        </block>
+                    </view>
+                </view>
+                <view class="item-box">
+                    <view class="item-title">反馈建议</view>
+                    <view>
+                        <textarea :value="message" class="feedback-textarea" maxlength="140" @input="inputChange" />
+                    </view>
+                </view>
+            </view>
+            <view class="feedback-footer">
+                <view class="btn-cancel" @tap="closeShowFeedback">取消</view>
+                <view class="btn-submit" @tap="submitFeedback">提交反馈</view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+// pages/components/feedback/index.js
+export default {
+    data() {
+        return {
+            upVote: [
+                {
+                    selected: false,
+                    value: '准确有效'
+                },
+                {
+                    selected: false,
+                    value: '回答全面'
+                },
+                {
+                    selected: false,
+                    value: '立场正确'
+                },
+                {
+                    selected: false,
+                    value: '格式规范'
+                },
+                {
+                    selected: false,
+                    value: '专业性强'
+                },
+                {
+                    selected: false,
+                    value: '富有创意'
+                },
+                {
+                    selected: false,
+                    value: '表达清晰'
+                },
+                {
+                    selected: false,
+                    value: '值得信赖'
+                },
+                {
+                    selected: false,
+                    value: '高效'
+                },
+                {
+                    selected: false,
+                    value: '满意'
+                }
+            ],
+            downVote: [
+                {
+                    selected: false,
+                    value: '理解错误'
+                },
+                {
+                    selected: false,
+                    value: '未识别问题'
+                },
+                {
+                    selected: false,
+                    value: '事实错误'
+                },
+                {
+                    selected: false,
+                    value: '推理错误'
+                },
+                {
+                    selected: false,
+                    value: '内容不完整'
+                },
+                {
+                    selected: false,
+                    value: '不专业'
+                },
+                {
+                    selected: false,
+                    value: '违法有害'
+                },
+                {
+                    selected: false,
+                    value: '格式错误'
+                },
+                {
+                    selected: false,
+                    value: '乱码'
+                },
+                {
+                    selected: false,
+                    value: '内容重复'
+                }
+            ],
+            score: 5,
+            message: ''
+        };
+    },
+
+    /**
+     * 组件的属性列表
+     */
+    props: {
+        isShowFeedback: {
+            type: Boolean,
+            default: false
+        },
+        feedbackRecordId: {
+            type: String,
+            default: ''
+        },
+        feedbackType: {
+            type: String,
+            default: ''
+        },
+        botId: {
+            type: String,
+            default: ''
+        },
+        input: {
+            type: String,
+            default: ''
+        },
+        aiAnswer: {
+            type: String,
+            default: ''
+        }
+    },
+
+    watch: {
+        feedbackType: function (value) {
+            this.setData({
+                score: value === 'upvote' ? 5 : 1
+            });
+        }
+    },
+
+    /**
+     * 组件的方法列表
+     */
+    methods: {
+        reset: function () {
+            this.setData({
+                upVote: [
+                    {
+                        selected: false,
+                        value: '准确有效'
+                    },
+                    {
+                        selected: false,
+                        value: '回答全面'
+                    },
+                    {
+                        selected: false,
+                        value: '立场正确'
+                    },
+                    {
+                        selected: false,
+                        value: '格式规范'
+                    },
+                    {
+                        selected: false,
+                        value: '专业性强'
+                    },
+                    {
+                        selected: false,
+                        value: '富有创意'
+                    },
+                    {
+                        selected: false,
+                        value: '表达清晰'
+                    },
+                    {
+                        selected: false,
+                        value: '值得信赖'
+                    },
+                    {
+                        selected: false,
+                        value: '高效'
+                    },
+                    {
+                        selected: false,
+                        value: '满意'
+                    }
+                ],
+                downVote: [
+                    {
+                        selected: false,
+                        value: '理解错误'
+                    },
+                    {
+                        selected: false,
+                        value: '未识别问题'
+                    },
+                    {
+                        selected: false,
+                        value: '事实错误'
+                    },
+                    {
+                        selected: false,
+                        value: '推理错误'
+                    },
+                    {
+                        selected: false,
+                        value: '内容不完整'
+                    },
+                    {
+                        selected: false,
+                        value: '不专业'
+                    },
+                    {
+                        selected: false,
+                        value: '违法有害'
+                    },
+                    {
+                        selected: false,
+                        value: '格式错误'
+                    },
+                    {
+                        selected: false,
+                        value: '乱码'
+                    },
+                    {
+                        selected: false,
+                        value: '内容重复'
+                    }
+                ],
+                score: 5,
+                message: ''
+            });
+        },
+        onChangeScore: function (e) {
+            const { score } = e.currentTarget.dataset;
+            this.setData({
+                score
+            });
+        },
+        onSelect: function (e) {
+            const { item } = e.currentTarget.dataset;
+            const newArr = [...(this.feedbackType === 'upvote' ? this.upVote : this.downVote)];
+            const [selectedItem] = newArr.filter((i) => i.value === item.value);
+            selectedItem.selected = !selectedItem.selected;
+            if (this.feedbackType === 'upvote') {
+                this.setData({
+                    upVote: newArr
+                });
+            } else {
+                this.setData({
+                    downVote: newArr
+                });
+            }
+        },
+        inputChange: function (e) {
+            const value = e.detail.value;
+            this.setData({
+                message: value
+            });
+        },
+        closeShowFeedback: function () {
+            this.$emit('close');
+        },
+        submitFeedback: async function () {
+            const res = await wx.cloud.extend.AI.bot.sendFeedback({
+                userFeedback: {
+                    botId: this.botId,
+                    recordId: this.feedbackRecordId,
+                    comment: this.message,
+                    rating: this.score,
+                    tags:
+                        this.feedbackType === 'upvote'
+                            ? this.upVote.filter((item) => item.selected).map((item) => item.value)
+                            : this.downVote.filter((item) => item.selected).map((item) => item.value),
+                    aiAnswer: this.aiAnswer,
+                    input: this.input,
+                    type: this.feedbackType === 'upvote' ? 'upvote' : 'downvote'
+                },
+                botId: this.botId
+            });
+            if (res.status === 'success') {
+                uni.showToast({
+                    title: '感谢反馈',
+                    icon: 'success'
+                });
+            } else {
+                uni.showToast({
+                    title: '反馈失败',
+                    icon: 'fail'
+                });
+            }
+            this.reset();
+            // console.log(res)
+            this.$emit('close');
+        }
+    },
+
+    created: function () {}
+};
+</script>
+<style>
+/* pages/components/feedback/index.wxss */
+.feedback-modal {
+    position: fixed;
+    top: 0px;
+    left: 0px;
+    width: 750rpx;
+    height: 100%;
+    background-color: rgba(0, 0, 0, 0.7);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.feedback {
+    width: 520rpx;
+    max-height: 70%;
+    overflow-y: auto;
+    background-color: #fff;
+    border-radius: 24rpx;
+    padding: 40rpx;
+}
+.feedback-header {
+    font-weight: 500;
+    font-size: 32rpx;
+    text-align: justify;
+}
+.feedback-body {
+    font-size: 28rpx;
+}
+.item-box {
+    padding: 28rpx 0px;
+}
+.item-title {
+    font-size: 28rpx;
+    padding-bottom: 28rpx;
+}
+.star {
+    width: 40rpx;
+    height: 40rpx;
+}
+.vote-item-normal {
+    display: inline-block;
+    background-color: rgba(243, 243, 243, 1);
+    height: 48rpx;
+    line-height: 48rpx;
+    border-radius: 24rpx;
+    padding: 4rpx 24rpx;
+    margin-right: 16rpx;
+    margin-bottom: 16rpx;
+}
+.vote-item-highlight {
+    display: inline-block;
+    background-color: rgba(0, 82, 217, 0.1);
+    height: 48rpx;
+    line-height: 48rpx;
+    border-radius: 24rpx;
+    padding: 4rpx 24rpx;
+    margin-right: 16rpx;
+    margin-bottom: 16rpx;
+    color: rgb(0, 82, 217);
+}
+.feedback-textarea {
+    width: 100%;
+    height: 150rpx;
+    border-radius: 16rpx;
+    border: 1px solid #ccc;
+    box-sizing: border-box;
+    padding: 16rpx;
+}
+.feedback-footer {
+    font-size: 28rpx;
+    display: flex;
+    justify-content: flex-end;
+    gap: 24rpx;
+}
+.btn-cancel {
+    box-sizing: border-box;
+    background-color: #fff;
+    border: 1px solid #eee;
+    padding: 6rpx 24rpx;
+    border-radius: 6rpx;
+    line-height: 48rpx;
+}
+.btn-submit {
+    box-sizing: border-box;
+    padding: 6rpx 24rpx;
+    border-radius: 6rpx;
+    color: #fff;
+    background-color: #0052d9;
+    line-height: 48rpx;
+}
+</style>

File diff suppressed because it is too large
+ 1821 - 0
components/agent-ui/index.vue


+ 47 - 0
components/agent-ui/markdownPreview/index.vue

@@ -0,0 +1,47 @@
+<template>
+    <view>
+        <!-- components/agent-ui/markdownPreview/index.wxml -->
+        <towxml :nodes="text"></towxml>
+    </view>
+</template>
+
+<script>
+import towxml from '@/components/agent-ui/markdownPreview/towxml/towxml';
+// components/agent-ui/markdownPreview/index.js
+import { markdownToWxml } from './utils';
+export default {
+    components: {
+        towxml
+    },
+    data() {
+        return {
+            text: {}
+        };
+    },
+    /**
+     * 组件的属性列表
+     */
+    props: {
+        markdown: {
+            type: String,
+            default: ''
+        }
+    },
+    watch: {
+        markdown: function (value) {
+            const wxml = markdownToWxml(value);
+            this.setData({
+                text: wxml
+            });
+        }
+    },
+    /**
+     * 组件的方法列表
+     */
+    methods: {},
+    created: function () {}
+};
+</script>
+<style>
+/* components/agent-ui/markdownPreview/index.wxss */
+</style>

+ 98 - 0
components/agent-ui/markdownPreview/towxml/audio-player/Audio.js

@@ -0,0 +1,98 @@
+const fillIn = (val) => `${val < 10 ? '0' : ''}${val}`;
+const formatTime = (_time) => {
+    let time = Math.round(_time);
+    let second = Math.round(time % 60);
+    let minute = Math.floor((time / 60) % 60);
+    let hour = Math.floor(time / 60 / 60);
+    return `${fillIn(hour)}:${fillIn(minute)}:${fillIn(second)}`;
+};
+class Audio {
+    constructor(obj) {
+        const _ts = this;
+        const option = (_ts.option = obj.attrs);
+        _ts.loop = option.loop === 'true';
+        _ts.autoplay = option.autoplay === 'true';
+        _ts.create();
+        _ts.index = 0;
+    }
+    create() {
+        const _ts = this;
+        const option = _ts.option;
+        let audio = (_ts.audio = uni.createInnerAudioContext());
+        audio.src = option.src;
+
+        // 说明可以播放了
+        audio.onCanplay(function () {
+            if (_ts.autoplay && !_ts.index) {
+                _ts.play();
+            }
+            if (!_ts.autoplay && !_ts.index) {
+                _ts.eventCanplay();
+            }
+        });
+
+        // 更新时间
+        audio.onTimeUpdate(function () {
+            //_ts.status = 'update';
+            _ts.duration = audio.duration;
+            _ts.currentTime = audio.currentTime;
+
+            // 定义播放结束
+            if (_ts.duration - _ts.currentTime < 0.5) {
+                _ts.index++;
+                if (_ts.loop) {
+                    audio.stop();
+                } else {
+                    _ts.stop();
+                }
+                audio.seek(0);
+            }
+            _ts.eventTimeUpdate(formatTime(_ts.duration), formatTime(_ts.currentTime));
+        });
+
+        //
+        audio.onSeeked(function () {
+            if (_ts.loop) {
+                _ts.play();
+            }
+        });
+    }
+    // 播放
+    play() {
+        const _ts = this;
+        _ts.status = 'play';
+        _ts.audio.play();
+        _ts.eventPlay();
+    }
+    // 暂停
+    pause() {
+        const _ts = this;
+        _ts.status = 'pause';
+        _ts.audio.pause();
+        _ts.eventPause();
+    }
+    // 停止
+    stop() {
+        const _ts = this;
+        _ts.status = 'stop';
+        _ts.audio.stop();
+        _ts.eventStop();
+    }
+    // 销毁
+    destroy() {
+        const _ts = this;
+        _ts.stop();
+        _ts.audio.destroy();
+    }
+    eventCanplay() {}
+    eventTimeUpdate() {}
+    eventEnded() {}
+    eventError() {}
+    eventPause() {}
+    eventPlay() {}
+    eventSeeked() {}
+    eventSeeking() {}
+    eventStop() {}
+    eventWaiting() {}
+}
+module.exports = Audio;

+ 320 - 0
components/agent-ui/markdownPreview/towxml/audio-player/audio-player.vue

@@ -0,0 +1,320 @@
+<template>
+    <view :class="'h2w__audio ' + (tips.state || 'h2w__audio--loading')" @tap="playAndPause">
+        <view class="h2w__audioIcon"></view>
+        <view class="h2w__audioCover">
+            <image class="h2w__audioLoading" src="/static/components/agent-ui/markdownPreview/towxml/audio-player/loading.svg"></image>
+            <image class="h2w__audioCoverImg" :src="data.attrs.poster"></image>
+        </view>
+        <view class="h2w__audioInfo">
+            <view class="h2w__audioTips">{{ tips.text || 'Error' }}</view>
+            <view class="h2w__audioSchedule" :style="'width:' + time.schedule + ';'"></view>
+            <view class="h2w__audioTitle">{{ data.attrs.name }}</view>
+            <view class="h2w__audioAuthor">{{ data.attrs.author }}</view>
+            <view class="h2w__audioTime">{{ time.currentTime || '00:00:00' }} / {{ time.duration || '00:00:00' }}</view>
+        </view>
+    </view>
+</template>
+
+<script>
+const Audio = require('./Audio');
+export default {
+    data() {
+        return {
+            tips: {
+                state: '',
+                text: '--'
+            },
+            time: {
+                currentTime: '00:00:00',
+                duration: '00:00:00',
+                schedule: '0%'
+            }
+        };
+    },
+    options: {
+        styleIsolation: 'shared'
+    },
+    props: {
+        data: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    mounted() {
+        // 处理小程序 attached 生命周期
+        this.attached();
+    },
+    moved: function () {
+        _ts.audio.stop();
+        _ts.audio.destroy();
+    },
+    destroyed: () => {
+        _ts.audio.stop();
+        _ts.audio.destroy();
+    },
+    methods: {
+        // 页面生命周期
+        attached: function () {
+            const that = this;
+            const audio = (that.audio = new Audio(this.data));
+            audio.eventPlay = function () {
+                that.setData({
+                    tips: {
+                        state: 'h2w__audio--play',
+                        text: 'Playing'
+                    }
+                });
+            };
+            audio.eventCanplay = function () {
+                that.setData({
+                    tips: {
+                        state: 'h2w__audio--readyed',
+                        text: 'Readyed'
+                    }
+                });
+            };
+            audio.eventTimeUpdate = function (duration, currentTime) {
+                that.setData({
+                    time: {
+                        currentTime: currentTime,
+                        duration: duration,
+                        schedule: (Math.round(that.audio.currentTime) / Math.round(that.audio.duration)) * 100 + '%'
+                    }
+                });
+            };
+            audio.eventPause = function () {
+                that.setData({
+                    tips: {
+                        state: 'h2w__audio--pause',
+                        text: 'Pause'
+                    }
+                });
+            };
+            audio.eventStop = function () {
+                that.setData({
+                    tips: {
+                        state: 'h2w__audio--end',
+                        text: 'End'
+                    }
+                });
+            };
+
+            // // 更新播放状态
+            // _ts.audio.onTimeUpdate = function(duration,currentTime){
+            //  _ts.setData({
+            //    playerData:{
+            //      state:'h2w__audio--play',
+            //      tips:'Playing',
+            //      currentTime:currentTime,
+            //      duration:duration,
+            //      schedule:_ts.audio.currentTime / _ts.audio.duration * 100 + '%'
+            //    }
+            //  });
+            // };
+
+            // _ts.audio.onPause = function(){
+            //  _ts.setData({playerData:{state:'h2w__audio--pause',tips:'Pause'}});
+            // };
+
+            // _ts.audio.onCanplay = function(){
+            //  _ts.setData({playerData:{state:'h2w__audio--readyed',tips:'Readyed'}});
+            // };
+
+            // _ts.audio.onError = function(){
+            //  _ts.setData({playerData:{state:'h2w__audio--error',tips:'Error'}});
+            // };
+
+            // _ts.audio.onEnded = ()=>{
+            //  _ts.setData({playerData:{state:'h2w__audio--end',tips:'End'}});
+            // };
+        },
+
+        playAndPause: function () {
+            const that = this;
+            const audio = that.audio; // console.log(audio);
+            audio.isTouch = true;
+            if (audio.status === 'update' || audio.status === 'play') {
+                // console.log('pause');
+                audio.pause();
+            } else {
+                // console.log('play');
+                audio.play();
+            }
+        }
+    },
+    created: function () {}
+};
+</script>
+<style>
+/*音频播放器样式*/
+.h2w__audio {
+    height: 136rpx;
+    margin: 16rpx 0;
+    background: #f1f1f1;
+    position: relative;
+}
+
+.h2w__audio--error .h2w__audioIcon,
+.h2w__audio--loading .h2w__audioIcon {
+    display: none;
+}
+
+.h2w__audio--readyed .h2w__audioLoading,
+.h2w__audio--end .h2w__audioLoading,
+.h2w__audio--play .h2w__audioIcon,
+.h2w__audio--pause .h2w__audioLoading,
+.h2w__audio--play .h2w__audioLoading {
+    display: none;
+}
+
+.h2w__audio--play .h2w__audioCover image {
+    opacity: 1;
+}
+
+.h2w__audio--readyed .h2w__audioTips,
+.h2w__audio--end .h2w__audioTips,
+.h2w__audio--stop .h2w__audioTips,
+.h2w__audio--pause .h2w__audioTips,
+.h2w__audio--play .h2w__audioTips {
+    opacity: 0.4;
+}
+
+.h2w__audio--error {
+    background: red;
+}
+
+/* .h2w__audio--end .h2w__audio__icon {width:20rpx; height:20rpx; background:white; border:0; left:24rpx; top:24rpx; border-radius:2rpx;} */
+.h2w__audioCover {
+    width: 136rpx;
+    height: 136rpx;
+    background: black;
+    float: left;
+    position: relative;
+}
+
+.h2w__audioCover image {
+    width: 100%;
+    height: 100%;
+    opacity: 0.6;
+    margin: 0;
+    transition: all 0.5s cubic-bezier(0.075, 0.82, 0.165, 1);
+}
+
+.h2w__audioCover .h2w__audioLoading {
+    width: 80rpx;
+    height: 80rpx;
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    margin: -40rpx 0 0 -40rpx;
+    z-index: 1;
+    opacity: 1;
+}
+
+.h2w__audioInfo {
+    padding-left: 20rpx;
+    padding-top: 16rpx;
+    position: absolute;
+    left: 136rpx;
+    right: 0;
+}
+
+.h2w__audioSchedule {
+    position: absolute;
+    left: 0;
+    top: 0;
+    background: rgba(0, 255, 0, 0.1);
+    height: 136rpx;
+    width: 0;
+}
+
+.h2w__audioTips {
+    position: absolute;
+    right: 0;
+    top: 0;
+    height: 32rpx;
+    line-height: 32rpx;
+    padding: 10rpx 20rpx;
+    font-size: 20rpx;
+}
+
+.h2w__audio--error .h2w__audioTips {
+    color: red;
+}
+
+.h2w__audioTitle {
+    display: block;
+    font-size: 24rpx;
+    height: 40rpx;
+    line-height: 40rpx;
+    font-weight: bold;
+}
+
+.h2w__audioAuthor {
+    display: block;
+    font-size: 20rpx;
+    height: 32rpx;
+    line-height: 32rpx;
+}
+
+.h2w__audioTime {
+    display: block;
+    font-size: 20rpx;
+    height: 32rpx;
+    line-height: 32rpx;
+}
+
+.h2w__audioIcon {
+    width: 0;
+    height: 0;
+    position: absolute;
+    left: 60rpx;
+    top: 48rpx;
+    border-width: 20rpx 0 20rpx 20rpx;
+    border-style: solid;
+    border-color: transparent transparent transparent #fff;
+    z-index: 1;
+}
+
+/* 深色主题 */
+.h2w-dark .h2w__audio {
+    background: #1f1f1f;
+}
+
+.h2w-dark .h2w__audio--error {
+    background: rgba(255, 0, 0, 0.1);
+}
+
+.h2w-dark .h2w__audioCover {
+    background: black;
+}
+
+.h2w-dark .h2w__audioSchedule {
+    background: rgba(0, 255, 0, 0.2);
+}
+
+.h2w-dark .h2w__audioIcon {
+    border-color: transparent transparent transparent #fff;
+}
+
+/* 浅色主题 */
+.h2w-light .h2w__audio {
+    background: #f1f1f1;
+}
+
+.h2w-light .h2w__audio--error {
+    background: rgba(255, 0, 0, 0.1);
+}
+
+.h2w-light .h2w__audioCover {
+    background: black;
+}
+
+.h2w-light .h2w__audioSchedule {
+    background: rgba(0, 255, 0, 0.1);
+}
+
+.h2w-light .h2w__audioIcon {
+    border-color: transparent transparent transparent #fff;
+}
+</style>

+ 288 - 0
components/agent-ui/markdownPreview/towxml/config.js

@@ -0,0 +1,288 @@
+module.exports = {
+    // LaTex公式、yuml解析服务架设参见 https://github.com/sbfkcel/markdown-server
+
+    // 数学公式解析API
+    // latex:{
+    //     api:'http://towxml.vvadd.com/?tex'
+    // },
+
+    // yuml图解析APPI
+    // yuml:{
+    //     api:'http://towxml.vvadd.com/?yuml'
+    // },
+
+    // markdown解析配置,保留需要的选项即可
+    markdown: [
+        'sub',
+        // 下标支持
+        'sup',
+        // 上标支持
+        'ins',
+        // 文本删除线支持
+        'mark' // 文本高亮支持
+        // 'emoji',                    // emoji表情支持
+        // 'todo'                      // todo支持
+    ],
+
+    // 代码高亮配置,保留需要的选项即可(尽量越少越好,不要随意调整顺序。部分高亮有顺序依赖)
+    highlight: [
+        'c-like',
+        'c',
+        'bash',
+        'css',
+        'dart',
+        'go',
+        'java',
+        'javascript',
+        'json',
+        'less',
+        'scss',
+        'shell',
+        'xml',
+        'htmlbars',
+        // "nginx",
+        // "php",
+        'python',
+        'python-repl',
+        'typescript'
+
+        // 'csharp',
+        // 'http',
+        // 'swift',
+        // 'yaml',
+        // 'markdown',
+        // 'powershell',
+        // 'ruby',
+        // 'makefile',
+        // 'lua',
+        // 'stylus',
+        // 'basic',
+        // '1c',
+        // 'abnf',
+        // 'accesslog',
+        // 'actionscript',
+        // 'ada',
+        // 'angelscript',
+        // 'apache',
+        // 'applescript',
+        // 'arcade',
+        // 'cpp',
+        // 'arduino',
+        // 'armasm',
+        // 'asciidoc',
+        // 'aspectj',
+        // 'autohotkey',
+        // 'autoit',
+        // 'avrasm',
+        // 'awk',
+        // 'axapta',
+        // 'bnf',
+        // 'brainfuck',
+        // 'cal',
+        // 'capnproto',
+        // 'ceylon',
+        // 'clean',
+        // 'clojure-repl',
+        // 'clojure',
+        // 'cmake',
+        // 'coffeescript',
+        // 'coq',
+        // 'cos',
+        // 'crmsh',
+        // 'crystal',
+        // 'csp',
+        // 'd',
+        // 'delphi',
+        // 'diff',
+        // 'django',
+        // 'dns',
+        // 'dockerfile',
+        // 'dos',
+        // 'dsconfig',
+        // 'dts',
+        // 'dust',
+        // 'ebnf',
+        // 'elixir',
+        // 'elm',
+        // 'erb',
+        // 'erlang-repl',
+        // 'erlang',
+        // 'excel',
+        // 'fix',
+        // 'flix',
+        // 'fortran',
+        // 'fsharp',
+        // 'gams',
+        // 'gauss',
+        // 'gcode',
+        // 'gherkin',
+        // 'glsl',
+        // 'gml',
+        // 'golo',
+        // 'gradle',
+        // 'groovy',
+        // 'haml',
+        // 'handlebars',
+        // 'haskell',
+        // 'haxe',
+        // 'hsp',
+        // 'hy',
+        // 'inform7',
+        // 'ini',
+        // 'irpf90',
+        // 'isbl',
+        // 'jboss-cli',
+        // 'julia-repl',
+        // 'julia',
+        // 'kotlin',
+        // 'lasso',
+        // 'latex',
+        // 'ldif',
+        // 'leaf',
+        // 'lisp',
+        // 'livecodeserver',
+        // 'livescript',
+        // 'llvm',
+        // 'lsl',
+        // 'mathematica',
+        // 'matlab',
+        // 'maxima',
+        // 'mel',
+        // 'mercury',
+        // 'mipsasm',
+        // 'mizar',
+        // 'mojolicious',
+        // 'monkey',
+        // 'moonscript',
+        // 'n1ql',
+        // 'nim',
+        // 'nix',
+        // 'nsis',
+        // 'objectivec',
+        // 'ocaml',
+        // 'openscad',
+        // 'oxygene',
+        // 'parser3',
+        // 'perl',
+        // 'pf',
+        // 'pgsql',
+        // 'php-template',
+        // 'plaintext',
+        // 'pony',
+        // 'processing',
+        // 'profile',
+        // 'prolog',
+        // 'properties',
+        // 'protobuf',
+        // 'puppet',
+        // 'purebasic',
+        // 'q',
+        // 'qml',
+        // 'r',
+        // 'reasonml',
+        // 'rib',
+        // 'roboconf',
+        // 'routeros',
+        // 'rsl',
+        // 'ruleslanguage',
+        // 'rust',
+        // 'sas',
+        // 'scala',
+        // 'scheme',
+        // 'scilab',
+        // 'smali',
+        // 'smalltalk',
+        // 'sml',
+        // 'sqf',
+        // 'sql',
+        // 'stan',
+        // 'stata',
+        // 'step21',
+        // 'subunit',
+        // 'taggerscript',
+        // 'tap',
+        // 'tcl',
+        // 'thrift',
+        // 'tp',
+        // 'twig',
+        // 'vala',
+        // 'vbnet',
+        // 'vbscript-html',
+        // 'vbscript',
+        // 'verilog',
+        // 'vhdl',
+        // 'vim',
+        // 'x86asm',
+        // 'xl',
+        // 'xquery',
+        // 'zephir'
+    ],
+
+    // wxml原生标签,该系列标签将不会被转换
+    wxml: [
+        'view',
+        'video',
+        'text',
+        'image',
+        'navigator',
+        'swiper',
+        'swiper-item',
+        'block',
+        'form',
+        'input',
+        'textarea',
+        'button',
+        'checkbox-group',
+        'checkbox',
+        'radio-group',
+        'radio',
+        'rich-text'
+
+        // 可以解析的标签(html或markdown中会很少使用)
+        // 'canvas',
+        // 'map',
+        // 'slider',
+        // 'scroll-view',
+        // 'movable-area',
+        // 'movable-view',
+        // 'progress',
+        // 'label',
+        // 'switch',
+        // 'picker',
+        // 'picker-view',
+        // 'switch',
+        // 'contact-button'
+    ],
+
+    // 自定义组件
+    components: [
+        'audio-player',
+        // 音频组件,建议保留,由于小程序原生audio存在诸多问题,towxml解决了原生音频播放器的相关问题
+        // "echarts", // echarts图表支持
+        // "latex", // 数学公式支持
+        'table',
+        // 表格支持
+        // "todogroup", // todo支持
+        // "yuml", // yuml图表支持
+        'img' // 图片解析组件
+    ],
+
+    // 保留原本的元素属性(建议不要变动)
+    attrs: ['class', 'data', 'id', 'style'],
+    // 事件绑定方式(catch或bind),catch 会阻止事件向上冒泡。更多请参考:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
+    bindType: 'catch',
+    // 需要激活的事件
+    events: [
+        // 'touchstart',
+        // 'touchmove',
+        // 'touchcancel',
+        // 'touchend',
+        'tap' // 用于元素的点击事件
+        // "change", // 用于todoList的change事件
+    ],
+
+    // 图片倍数
+    dpr: 1,
+    // 代码块显示行号
+    showLineNumber: true
+};

+ 274 - 0
components/agent-ui/markdownPreview/towxml/decode.vue

@@ -0,0 +1,274 @@
+<template>
+    <view>
+        <block v-for="(item, i) in nodes.children" :key="i">
+            <block v-if="item.tag === undefined">{{ item.text }}</block>
+
+            <block v-if="item.tag === 'view'">
+                <block v-if="item.rely">
+                    <view :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun">
+                        <decode v-if="item.children" :nodes="item" />
+                    </view>
+                </block>
+                <block v-else>
+                    <view class="h2w__viewParent">
+                        <view :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun">
+                            <decode v-if="item.children" :nodes="item" />
+                        </view>
+                    </view>
+                </block>
+            </block>
+
+            <block v-if="item.tag === 'video'">
+                <view class="h2w__videoParent">
+                    <video
+                        :data-data="item"
+                        :class="item.attrs.class"
+                        :data="item.attrs.data"
+                        :id="item.attrs.id"
+                        :style="item.attrs.style"
+                        @tap.stop.prevent="tapFun"
+                        :poster="item.attrs.poster"
+                        :src="item.attrs.src"
+                    >
+                        <decode v-if="item.children" :nodes="item" />
+                    </video>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'text'">
+                <view class="h2w__textParent">
+                    <text :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun">
+                        <decode v-if="item.children" :nodes="item" />
+                    </text>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'image'">
+                <view class="h2w__imageParent">
+                    <image
+                        :data-data="item"
+                        :class="item.attrs.class"
+                        :data="item.attrs.data"
+                        :id="item.attrs.id"
+                        :style="item.attrs.style"
+                        @tap.stop.prevent="tapFun"
+                        :src="item.attrs.src"
+                        :mode="item.attrs.mode ? item.attrs.mode : 'widthFix'"
+                        :lazy-load="item.attr['lazy-load']"
+                    >
+                        <decode v-if="item.children" :nodes="item" />
+                    </image>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'navigator'">
+                <view class="h2w__navigatorParent">
+                    <navigator
+                        :data-data="item"
+                        :class="item.attrs.class"
+                        :data="item.attrs.data"
+                        :id="item.attrs.id"
+                        :style="item.attrs.style"
+                        @tap.stop.prevent="tapFun"
+                        :url="item.attrs.href"
+                    >
+                        <decode v-if="item.children" :nodes="item" />
+                    </navigator>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'swiper'">
+                <view class="h2w__swiperParent">
+                    <swiper :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun">
+                        <decode v-if="item.children" :nodes="item" />
+                    </swiper>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'swiper-item'">
+                <view class="h2w__swiper-itemParent">
+                    <swiper-item :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun">
+                        <decode v-if="item.children" :nodes="item" />
+                    </swiper-item>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'block'">
+                <view class="h2w__blockParent">
+                    <block
+                        :data-data="item"
+                        :class="item.attrs.class"
+                        :data="item.attrs.data"
+                        :id="item.attrs.id"
+                        :style="item.attrs.style"
+                        @tap.native.stop.prevent="tapFun($event, { data: item, tagId: item.attrs.id })"
+                    >
+                        <decode v-if="item.children" :nodes="item" />
+                    </block>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'form'">
+                <view class="h2w__formParent">
+                    <form :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun">
+                        <decode v-if="item.children" :nodes="item" />
+                    </form>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'input'">
+                <view class="h2w__inputParent">
+                    <input :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun" />
+                    <decode v-if="item.children" :nodes="item" />
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'textarea'">
+                <view class="h2w__textareaParent">
+                    <textarea :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun">
+<decode v-if="item.children" :nodes="item"/></textarea
+                    >
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'button'">
+                <view class="h2w__buttonParent">
+                    <button :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun">
+                        <decode v-if="item.children" :nodes="item" />
+                    </button>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'checkbox-group'">
+                <view class="h2w__checkbox-groupParent">
+                    <checkbox-group
+                        :data-data="item"
+                        :class="item.attrs.class"
+                        :data="item.attrs.data"
+                        :id="item.attrs.id"
+                        :style="item.attrs.style"
+                        @tap.stop.prevent="tapFun"
+                        @change="parseEventDynamicCode($event, item.attrs.bindchange)"
+                    >
+                        <decode v-if="item.children" :nodes="item" />
+                    </checkbox-group>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'checkbox'">
+                <view class="h2w__checkboxParent">
+                    <checkbox
+                        :data-data="item"
+                        :class="item.attrs.class"
+                        :data="item.attrs.data"
+                        :id="item.attrs.id"
+                        :style="item.attrs.style"
+                        @tap.stop.prevent="tapFun"
+                        :checked="item.attrs.checked"
+                        :value="item.attrs.value"
+                    >
+                        <decode v-if="item.children" :nodes="item" />
+                    </checkbox>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'radio-group'">
+                <view class="h2w__radio-groupParent">
+                    <radio-group :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :id="item.attrs.id" :style="item.attrs.style" @tap.stop.prevent="tapFun">
+                        <decode v-if="item.children" :nodes="item" />
+                    </radio-group>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'radio'">
+                <view class="h2w__radioParent">
+                    <radio
+                        :data-data="item"
+                        :class="item.attrs.class"
+                        :data="item.attrs.data"
+                        :id="item.attrs.id"
+                        :style="item.attrs.style"
+                        @tap.stop.prevent="tapFun"
+                        :checked="item.attrs.checked"
+                    >
+                        <decode v-if="item.children" :nodes="item" />
+                    </radio>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'rich-text'">
+                <view class="h2w__rich-textParent">
+                    <rich-text :data-data="item" :class="item.attrs.class" :data="item.attrs.data" :style="item.attrs.style" @tap.stop.prevent="tapFun" :nodes="item.children">
+                        <decode v-if="item.children" :nodes="item" />
+                    </rich-text>
+                </view>
+            </block>
+
+            <block v-if="item.tag === 'audio-player'">
+                <audio-player :data="item" :data-data="item" @tap.native.stop.prevent="tapFun($event, { data: item })" />
+            </block>
+
+            <block v-if="item.tag === 'table'">
+                <table :data="item" :data-data="item" @tap.native.stop.prevent="tapFun($event, { data: item })" />
+            </block>
+
+            <block v-if="item.tag === 'img'"><img :data="item" :data-data="item" @tap.native.stop.prevent="tapFun($event, { data: item })" /></block>
+        </block>
+    </view>
+</template>
+
+<script>
+import decode from '@/components/agent-ui/markdownPreview/towxml/decode';
+import audioPlayer from '@/components/agent-ui/markdownPreview/towxml/audio-player/audio-player';
+import table from '@/components/agent-ui/markdownPreview/towxml/table/table';
+import img from '@/components/agent-ui/markdownPreview/towxml/img/img';
+const config = require('./config');
+export default {
+    components: {
+        decode,
+        audioPlayer,
+        table,
+        img
+    },
+    data() {
+        return {
+            i: '',
+            undefined: ''
+        };
+    },
+    options: {
+        styleIsolation: 'apply-shared'
+    },
+    props: {
+        nodes: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    mounted() {
+        // 处理小程序 attached 生命周期
+        this.attached();
+    },
+    methods: {
+        attached: function () {
+            const that = this;
+            config.events.forEach((item) => {
+                that['_' + item] = function (...arg) {
+                    if (global._events && typeof global._events[item] === 'function') {
+                        global._events[item](...arg);
+                    }
+                };
+            });
+        },
+
+        tapFun(e, _dataset) {
+            /* ---处理dataset begin--- */
+            this.handleDataset(e, _dataset);
+            /* ---处理dataset end--- */
+            console.log('占位:函数 _tap 未声明');
+        }
+    },
+    created: function () {}
+};
+</script>
+<style></style>

+ 127 - 0
components/agent-ui/markdownPreview/towxml/img/img.vue

@@ -0,0 +1,127 @@
+<template>
+    <view>
+        <image
+            :class="attrs.class"
+            :lazy-load="true"
+            :mode="attrs.mode || 'widthFix'"
+            :src="attrs.src"
+            :style="attrs.style + ' width:' + size.w + 'px;height:' + size.h + 'px;'"
+            @load="load"
+        ></image>
+    </view>
+</template>
+
+<script>
+const config = require('../config');
+export default {
+    data() {
+        return {
+            attr: {
+                src: '',
+                class: '',
+                style: ''
+            },
+
+            size: {
+                w: 0,
+                h: 0
+            },
+
+            styleObj: {},
+
+            attrs: {
+                class: '',
+                mode: '',
+                src: '',
+                style: ''
+            }
+        };
+    },
+    options: {
+        styleIsolation: 'shared'
+    },
+    props: {
+        data: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    mounted() {
+        // 处理小程序 attached 生命周期
+        this.attached();
+    },
+    methods: {
+        attached: function () {
+            const that = this;
+            let dataAttr = this.data.attrs;
+
+            // 将图片大小处理到对象中
+            if (dataAttr.width) {
+                that.size.w = +dataAttr.width / config.dpr;
+            }
+            if (dataAttr.height) {
+                that.size.h = +dataAttr.height / config.dpr;
+            }
+
+            // 将样式合并到样式对象中
+            if (dataAttr.style) {
+                let re = /;\s{0,}/gi;
+                dataAttr.style = dataAttr.style.replace(re, ';');
+                dataAttr.style.split(';').forEach((item) => {
+                    let itemArr = item.split(':');
+                    if (/^(width|height)$/i.test(itemArr[0])) {
+                        let num = parseInt(itemArr[1]) || 0;
+                        let key = ''; // itemArr[1] = num / config.dpr + itemArr[1].replace(num,'');
+                        switch (itemArr[0].toLocaleLowerCase()) {
+                            case 'width':
+                                key = 'w';
+                                break;
+                            case 'height':
+                                key = 'h';
+                                break;
+                        }
+                        that.size[key] = num / config.dpr;
+                    } else {
+                        that.styleObj[itemArr[0]] = itemArr[1];
+                    }
+                });
+            }
+
+            // 设置公式图片
+            that.setData({
+                attrs: {
+                    src: dataAttr.src,
+                    class: dataAttr.class,
+                    style: that.setStyle(that.styleObj)
+                },
+
+                size: that.size
+            });
+        },
+
+        // 设置图片样式
+        setStyle: function (o) {
+            let str = ``;
+            for (let key in o) {
+                str += `${key}:${o[key]};`;
+            }
+            return str;
+        },
+
+        // 图片加载完成设置图片大小
+        load: function (e) {
+            const that = this;
+            if (!that.size.w || !that.size.h) {
+                that.setData({
+                    size: {
+                        w: e.detail.width / config.dpr,
+                        h: e.detail.height / config.dpr
+                    }
+                });
+            }
+        }
+    },
+    created: function () {}
+};
+</script>
+<style></style>

+ 18 - 0
components/agent-ui/markdownPreview/towxml/index.js

@@ -0,0 +1,18 @@
+const md = require('./parse/markdown/index');
+const parse = require('./parse/index');
+module.exports = (str, type, option) => {
+    option = option || {};
+    let result;
+    switch (type) {
+        case 'markdown':
+            result = parse(md(str), option);
+            break;
+        case 'html':
+            result = parse(str, option);
+            break;
+        default:
+            throw new Error('Invalid type, only markdown and html are supported');
+            break;
+    }
+    return result;
+};

+ 987 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/highlight.js

@@ -0,0 +1,987 @@
+'use strict';
+function deepFreeze(e) {
+    Object.freeze(e);
+    var n = 'function' == typeof e;
+    Object.getOwnPropertyNames(e).forEach(function (t) {
+        !e.hasOwnProperty(t) ||
+            null === e[t] ||
+            ('object' != typeof e[t] && 'function' != typeof e[t]) ||
+            (n && ('caller' === t || 'callee' === t || 'arguments' === t)) ||
+            Object.isFrozen(e[t]) ||
+            deepFreeze(e[t]);
+    });
+    return e;
+}
+function escapeHTML(e) {
+    return e.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+}
+function inherit(e) {
+    var n;
+    var t = {};
+    var r = Array.prototype.slice.call(arguments, 1);
+    for (n in e) {
+        t[n] = e[n];
+    }
+    r.forEach(function (e) {
+        for (n in e) {
+            t[n] = e[n];
+        }
+    });
+    return t;
+}
+function tag(e) {
+    return e.nodeName.toLowerCase();
+}
+function nodeStream(e) {
+    var n = [];
+    (function e(t, r) {
+        for (var a = t.firstChild; a; a = a.nextSibling) {
+            if (3 === a.nodeType) {
+                r += a.nodeValue.length;
+            } else {
+                if (1 === a.nodeType) {
+                    n.push({
+                        event: 'start',
+                        offset: r,
+                        node: a
+                    });
+                    r = e(a, r);
+                    tag(a).match(/br|hr|img|input/) ||
+                        n.push({
+                            event: 'stop',
+                            offset: r,
+                            node: a
+                        });
+                }
+            }
+        }
+        return r;
+    })(e, 0);
+    return n;
+}
+function mergeStreams(e, n, t) {
+    var r = 0;
+    var a = '';
+    var i = [];
+    function s() {
+        return e.length && n.length ? (e[0].offset !== n[0].offset ? (e[0].offset < n[0].offset ? e : n) : 'start' === n[0].event ? e : n) : e.length ? e : n;
+    }
+    function o(e) {
+        a +=
+            '<' +
+            tag(e) +
+            [].map
+                .call(e.attributes, function (e) {
+                    return ' ' + e.nodeName + '="' + escapeHTML(e.value).replace(/"/g, '&quot;') + '"';
+                })
+                .join('') +
+            '>';
+    }
+    function l(e) {
+        a += '</' + tag(e) + '>';
+    }
+    function c(e) {
+        ('start' === e.event ? o : l)(e.node);
+    }
+    for (; e.length || n.length; ) {
+        var u = s();
+        a += escapeHTML(t.substring(r, u[0].offset));
+        r = u[0].offset;
+        if (u === e) {
+            i.reverse().forEach(l);
+            do {
+                c(u.splice(0, 1)[0]);
+                u = s();
+            } while (u === e && u.length && u[0].offset === r);
+            i.reverse().forEach(o);
+        } else {
+            'start' === u[0].event ? i.push(u[0].node) : i.pop();
+            c(u.splice(0, 1)[0]);
+        }
+    }
+    return a + escapeHTML(t.substr(r));
+}
+var utils = Object.freeze({
+    __proto__: null,
+    escapeHTML: escapeHTML,
+    inherit: inherit,
+    nodeStream: nodeStream,
+    mergeStreams: mergeStreams
+});
+const SPAN_CLOSE = '</span>';
+const emitsWrappingTags = (e) => !!e.kind;
+class HTMLRenderer {
+    constructor(e, n) {
+        this.buffer = '';
+        this.classPrefix = n.classPrefix;
+        e.walk(this);
+    }
+    addText(e) {
+        this.buffer += escapeHTML(e);
+    }
+    openNode(e) {
+        if (!emitsWrappingTags(e)) {
+            return;
+        }
+        let n = e.kind;
+        e.sublanguage || (n = `${this.classPrefix}${n}`);
+        this.span(n);
+    }
+    closeNode(e) {
+        if (emitsWrappingTags(e)) {
+            this.buffer += SPAN_CLOSE;
+        }
+    }
+    span(e) {
+        this.buffer += `<span class="${e}">`;
+    }
+    value() {
+        return this.buffer;
+    }
+}
+class TokenTree {
+    constructor() {
+        this.rootNode = {
+            children: []
+        };
+        this.stack = [this.rootNode];
+    }
+    get top() {
+        return this.stack[this.stack.length - 1];
+    }
+    get root() {
+        return this.rootNode;
+    }
+    add(e) {
+        this.top.children.push(e);
+    }
+    openNode(e) {
+        let n = {
+            kind: e,
+            children: []
+        };
+        this.add(n);
+        this.stack.push(n);
+    }
+    closeNode() {
+        if (this.stack.length > 1) {
+            return this.stack.pop();
+        }
+    }
+    closeAllNodes() {
+        for (; this.closeNode(); ) {}
+    }
+    toJSON() {
+        return JSON.stringify(this.rootNode, null, 4);
+    }
+    walk(e) {
+        return this.constructor._walk(e, this.rootNode);
+    }
+    static _walk(e, n) {
+        'string' == typeof n ? e.addText(n) : n.children && (e.openNode(n), n.children.forEach((n) => this._walk(e, n)), e.closeNode(n));
+        return e;
+    }
+    static _collapse(e) {
+        if (e.children) {
+            e.children.every((e) => 'string' == typeof e)
+                ? ((e.text = e.children.join('')), delete e.children)
+                : e.children.forEach((e) => {
+                      if ('string' != typeof e) {
+                          TokenTree._collapse(e);
+                      }
+                  });
+        }
+    }
+}
+class TokenTreeEmitter extends TokenTree {
+    constructor(e) {
+        super();
+        this.options = e;
+    }
+    addKeyword(e, n) {
+        if ('' !== e) {
+            this.openNode(n);
+            this.addText(e);
+            this.closeNode();
+        }
+    }
+    addText(e) {
+        if ('' !== e) {
+            this.add(e);
+        }
+    }
+    addSublanguage(e, n) {
+        let t = e.root;
+        t.kind = n;
+        t.sublanguage = true;
+        this.add(t);
+    }
+    toHTML() {
+        return new HTMLRenderer(this, this.options).value();
+    }
+    finalize() {}
+}
+function escape(e) {
+    return new RegExp(e.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'm');
+}
+function source(e) {
+    return (e && e.source) || e;
+}
+function countMatchGroups(e) {
+    return new RegExp(e.toString() + '|').exec('').length - 1;
+}
+function startsWith(e, n) {
+    var t = e && e.exec(n);
+    return t && 0 === t.index;
+}
+function join(e, n) {
+    for (var t = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./, r = 0, a = '', i = 0; i < e.length; i++) {
+        var s = (r += 1);
+        var o = source(e[i]);
+        for (i > 0 && (a += n), a += '('; o.length > 0; ) {
+            var l = t.exec(o);
+            if (null == l) {
+                a += o;
+                break;
+            }
+            a += o.substring(0, l.index);
+            o = o.substring(l.index + l[0].length);
+            '\\' == l[0][0] && l[1] ? (a += '\\' + String(Number(l[1]) + s)) : ((a += l[0]), '(' == l[0] && r++);
+        }
+        a += ')';
+    }
+    return a;
+}
+const IDENT_RE = '[a-zA-Z]\\w*';
+const NUMBER_RE = '\\b\\d+(\\.\\d+)?';
+const C_NUMBER_RE = '(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)';
+const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';
+const BACKSLASH_ESCAPE = {
+    begin: '\\\\[\\s\\S]',
+    relevance: 0
+};
+const APOS_STRING_MODE = {
+    className: 'string',
+    begin: "'",
+    end: "'",
+    illegal: '\\n',
+    contains: [BACKSLASH_ESCAPE]
+};
+const QUOTE_STRING_MODE = {
+    className: 'string',
+    begin: '"',
+    end: '"',
+    illegal: '\\n',
+    contains: [BACKSLASH_ESCAPE]
+};
+const PHRASAL_WORDS_MODE = {
+    begin: /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/
+};
+const COMMENT = function (e, n, t) {
+    var r = inherit(
+        {
+            className: 'comment',
+            begin: e,
+            end: n,
+            contains: []
+        },
+        t || {}
+    );
+    r.contains.push(PHRASAL_WORDS_MODE);
+    r.contains.push({
+        className: 'doctag',
+        begin: '(?:TODO|FIXME|NOTE|BUG|XXX):',
+        relevance: 0
+    });
+    return r;
+};
+const C_LINE_COMMENT_MODE = COMMENT('//', '$');
+const C_BLOCK_COMMENT_MODE = COMMENT('/\\*', '\\*/');
+const HASH_COMMENT_MODE = COMMENT('#', '$');
+const NUMBER_MODE = {
+    className: 'number',
+    begin: NUMBER_RE,
+    relevance: 0
+};
+const C_NUMBER_MODE = {
+    className: 'number',
+    begin: C_NUMBER_RE,
+    relevance: 0
+};
+const BINARY_NUMBER_MODE = {
+    className: 'number',
+    begin: '\\b(0b[01]+)',
+    relevance: 0
+};
+const CSS_NUMBER_MODE = {
+    className: 'number',
+    begin: NUMBER_RE + '(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?',
+    relevance: 0
+};
+const REGEXP_MODE = {
+    begin: /(?=\/[^\/\n]*\/)/,
+    contains: [
+        {
+            className: 'regexp',
+            begin: /\//,
+            end: /\/[gimuy]*/,
+            illegal: /\n/,
+            contains: [
+                BACKSLASH_ESCAPE,
+                {
+                    begin: /\[/,
+                    end: /\]/,
+                    relevance: 0,
+                    contains: [BACKSLASH_ESCAPE]
+                }
+            ]
+        }
+    ]
+};
+const TITLE_MODE = {
+    className: 'title',
+    begin: IDENT_RE,
+    relevance: 0
+};
+const UNDERSCORE_TITLE_MODE = {
+    className: 'title',
+    begin: '[a-zA-Z_]\\w*',
+    relevance: 0
+};
+const METHOD_GUARD = {
+    begin: '\\.\\s*[a-zA-Z_]\\w*',
+    relevance: 0
+};
+var MODES = Object.freeze({
+    __proto__: null,
+    IDENT_RE: IDENT_RE,
+    UNDERSCORE_IDENT_RE: '[a-zA-Z_]\\w*',
+    NUMBER_RE: NUMBER_RE,
+    C_NUMBER_RE: C_NUMBER_RE,
+    BINARY_NUMBER_RE: '\\b(0b[01]+)',
+    RE_STARTERS_RE: RE_STARTERS_RE,
+    BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,
+    APOS_STRING_MODE: APOS_STRING_MODE,
+    QUOTE_STRING_MODE: QUOTE_STRING_MODE,
+    PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,
+    COMMENT: COMMENT,
+    C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,
+    C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,
+    HASH_COMMENT_MODE: HASH_COMMENT_MODE,
+    NUMBER_MODE: NUMBER_MODE,
+    C_NUMBER_MODE: C_NUMBER_MODE,
+    BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,
+    CSS_NUMBER_MODE: CSS_NUMBER_MODE,
+    REGEXP_MODE: REGEXP_MODE,
+    TITLE_MODE: TITLE_MODE,
+    UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE,
+    METHOD_GUARD: METHOD_GUARD
+});
+var COMMON_KEYWORDS = 'of and for in not or if then'.split(' ');
+function compileLanguage(e) {
+    function n(n, t) {
+        return new RegExp(source(n), 'm' + (e.case_insensitive ? 'i' : '') + (t ? 'g' : ''));
+    }
+    class t {
+        constructor() {
+            this.matchIndexes = {};
+            this.regexes = [];
+            this.matchAt = 1;
+            this.position = 0;
+        }
+        addRule(e, n) {
+            n.position = this.position++;
+            this.matchIndexes[this.matchAt] = n;
+            this.regexes.push([n, e]);
+            this.matchAt += countMatchGroups(e) + 1;
+        }
+        compile() {
+            if (0 === this.regexes.length) {
+                this.exec = () => null;
+            }
+            let e = this.regexes.map((e) => e[1]);
+            this.matcherRe = n(join(e, '|'), true);
+            this.lastIndex = 0;
+        }
+        exec(e) {
+            this.matcherRe.lastIndex = this.lastIndex;
+            let n = this.matcherRe.exec(e);
+            if (!n) {
+                return null;
+            }
+            let t = n.findIndex((e, n) => n > 0 && void 0 != e);
+            let r = this.matchIndexes[t];
+            return Object.assign(n, r);
+        }
+    }
+    class r {
+        constructor() {
+            this.rules = [];
+            this.multiRegexes = [];
+            this.count = 0;
+            this.lastIndex = 0;
+            this.regexIndex = 0;
+        }
+        getMatcher(e) {
+            if (this.multiRegexes[e]) {
+                return this.multiRegexes[e];
+            }
+            let n = new t();
+            this.rules.slice(e).forEach(([e, t]) => n.addRule(e, t));
+            n.compile();
+            this.multiRegexes[e] = n;
+            return n;
+        }
+        considerAll() {
+            this.regexIndex = 0;
+        }
+        addRule(e, n) {
+            this.rules.push([e, n]);
+            if ('begin' === n.type) {
+                this.count++;
+            }
+        }
+        exec(e) {
+            let n = this.getMatcher(this.regexIndex);
+            n.lastIndex = this.lastIndex;
+            let t = n.exec(e);
+            if (t) {
+                this.regexIndex += t.position + 1;
+                if (this.regexIndex === this.count) {
+                    this.regexIndex = 0;
+                }
+            }
+            return t;
+        }
+    }
+    function a(e) {
+        let n = e.input[e.index - 1];
+        let t = e.input[e.index + e[0].length];
+        if ('.' === n || '.' === t) {
+            return {
+                ignoreMatch: true
+            };
+        }
+    }
+    if (e.contains && e.contains.includes('self')) {
+        throw new Error('ERR: contains `self` is not supported at the top-level of a language.  See documentation.');
+    }
+    !(function t(i, s) {
+        i.compiled ||
+            ((i.compiled = true),
+            (i.__onBegin = null),
+            (i.keywords = i.keywords || i.beginKeywords),
+            i.keywords && (i.keywords = compileKeywords(i.keywords, e.case_insensitive)),
+            (i.lexemesRe = n(i.lexemes || /\w+/, true)),
+            s &&
+                (i.beginKeywords && ((i.begin = '\\b(' + i.beginKeywords.split(' ').join('|') + ')(?=\\b|\\s)'), (i.__onBegin = a)),
+                i.begin || (i.begin = /\B|\b/),
+                (i.beginRe = n(i.begin)),
+                i.endSameAsBegin && (i.end = i.begin),
+                i.end || i.endsWithParent || (i.end = /\B|\b/),
+                i.end && (i.endRe = n(i.end)),
+                (i.terminator_end = source(i.end) || ''),
+                i.endsWithParent && s.terminator_end && (i.terminator_end += (i.end ? '|' : '') + s.terminator_end)),
+            i.illegal && (i.illegalRe = n(i.illegal)),
+            null == i.relevance && (i.relevance = 1),
+            i.contains || (i.contains = []),
+            (i.contains = [].concat(
+                ...i.contains.map(function (e) {
+                    return expand_or_clone_mode('self' === e ? i : e);
+                })
+            )),
+            i.contains.forEach(function (e) {
+                t(e, i);
+            }),
+            i.starts && t(i.starts, s),
+            (i.matcher = (function (e) {
+                let n = new r();
+                e.contains.forEach((e) =>
+                    n.addRule(e.begin, {
+                        rule: e,
+                        type: 'begin'
+                    })
+                );
+                if (e.terminator_end) {
+                    n.addRule(e.terminator_end, {
+                        type: 'end'
+                    });
+                }
+                if (e.illegal) {
+                    n.addRule(e.illegal, {
+                        type: 'illegal'
+                    });
+                }
+                return n;
+            })(i)));
+    })(e);
+}
+function dependencyOnParent(e) {
+    return !!e && (e.endsWithParent || dependencyOnParent(e.starts));
+}
+function expand_or_clone_mode(e) {
+    if (e.variants && !e.cached_variants) {
+        e.cached_variants = e.variants.map(function (n) {
+            return inherit(
+                e,
+                {
+                    variants: null
+                },
+                n
+            );
+        });
+    }
+    return e.cached_variants
+        ? e.cached_variants
+        : dependencyOnParent(e)
+        ? inherit(e, {
+              starts: e.starts ? inherit(e.starts) : null
+          })
+        : Object.isFrozen(e)
+        ? inherit(e)
+        : e;
+}
+function compileKeywords(e, n) {
+    var t = {};
+    'string' == typeof e
+        ? r('keyword', e)
+        : Object.keys(e).forEach(function (n) {
+              r(n, e[n]);
+          });
+    return t;
+    function r(e, r) {
+        if (n) {
+            r = r.toLowerCase();
+        }
+        r.split(' ').forEach(function (n) {
+            var r = n.split('|');
+            t[r[0]] = [e, scoreForKeyword(r[0], r[1])];
+        });
+    }
+}
+function scoreForKeyword(e, n) {
+    return n ? Number(n) : commonKeyword(e) ? 0 : 1;
+}
+function commonKeyword(e) {
+    return COMMON_KEYWORDS.includes(e.toLowerCase());
+}
+var version = '10.0.0-beta.0';
+const escape$1 = escapeHTML;
+const inherit$1 = inherit;
+const { nodeStream: nodeStream$1, mergeStreams: mergeStreams$1 } = utils;
+const HLJS = function (e) {
+    var n = [];
+    var t = {};
+    var r = {};
+    var a = [];
+    var i = true;
+    var s = /((^(<[^>]+>|\t|)+|(?:\n)))/gm;
+    var o = "Could not find the language '{}', did you forget to load/include a language module?";
+    var l = {
+        noHighlightRe: /^(no-?highlight)$/i,
+        languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i,
+        classPrefix: 'hljs-',
+        tabReplace: null,
+        useBR: false,
+        languages: void 0,
+        __emitter: TokenTreeEmitter
+    };
+    function c(e) {
+        return l.noHighlightRe.test(e);
+    }
+    function u(e, n, t, r) {
+        var a = {
+            code: n,
+            language: e
+        };
+        R('before:highlight', a);
+        var i = a.result ? a.result : d(a.language, a.code, t, r);
+        i.code = a.code;
+        R('after:highlight', i);
+        return i;
+    }
+    function d(e, n, r, a) {
+        var s = n;
+        function c(e, n) {
+            var t = R.case_insensitive ? n[0].toLowerCase() : n[0];
+            return e.keywords.hasOwnProperty(t) && e.keywords[t];
+        }
+        function u() {
+            null != b.subLanguage
+                ? (function () {
+                      if ('' !== S) {
+                          var e = 'string' == typeof b.subLanguage;
+                          if (!e || t[b.subLanguage]) {
+                              var n = e ? d(b.subLanguage, S, true, v[b.subLanguage]) : g(S, b.subLanguage.length ? b.subLanguage : void 0);
+                              if (b.relevance > 0) {
+                                  T += n.relevance;
+                              }
+                              if (e) {
+                                  v[b.subLanguage] = n.top;
+                              }
+                              N.addSublanguage(n.emitter, n.language);
+                          } else {
+                              N.addText(S);
+                          }
+                      }
+                  })()
+                : (function () {
+                      var e;
+                      var n;
+                      var t;
+                      var r;
+                      if (b.keywords) {
+                          for (n = 0, b.lexemesRe.lastIndex = 0, t = b.lexemesRe.exec(S), r = ''; t; ) {
+                              r += S.substring(n, t.index);
+                              var a = null;
+                              (e = c(b, t)) ? (N.addText(r), (r = ''), (T += e[1]), (a = e[0]), N.addKeyword(t[0], a)) : (r += t[0]);
+                              n = b.lexemesRe.lastIndex;
+                              t = b.lexemesRe.exec(S);
+                          }
+                          r += S.substr(n);
+                          N.addText(r);
+                      } else {
+                          N.addText(S);
+                      }
+                  })();
+            S = '';
+        }
+        function h(e) {
+            if (e.className) {
+                N.openNode(e.className);
+            }
+            b = Object.create(e, {
+                parent: {
+                    value: b
+                }
+            });
+        }
+        function f(e) {
+            var n = e[0];
+            var t = e.rule;
+            if (t.__onBegin) {
+                if ((t.__onBegin(e) || {}).ignoreMatch) {
+                    return (function (e) {
+                        return 0 === b.matcher.regexIndex ? ((S += e[0]), 1) : ((w = true), 0);
+                    })(n);
+                }
+            }
+            if (t && t.endSameAsBegin) {
+                t.endRe = escape(n);
+            }
+            t.skip ? (S += n) : (t.excludeBegin && (S += n), u(), t.returnBegin || t.excludeBegin || (S = n));
+            h(t);
+            return t.returnBegin ? 0 : n.length;
+        }
+        function E(e) {
+            var n = e[0];
+            var t = s.substr(e.index);
+            var r = (function e(n, t) {
+                if (startsWith(n.endRe, t)) {
+                    for (; n.endsParent && n.parent; ) {
+                        n = n.parent;
+                    }
+                    return n;
+                }
+                if (n.endsWithParent) {
+                    return e(n.parent, t);
+                }
+            })(b, t);
+            if (r) {
+                var a = b;
+                a.skip ? (S += n) : (a.returnEnd || a.excludeEnd || (S += n), u(), a.excludeEnd && (S = n));
+                do {
+                    if (b.className) {
+                        N.closeNode();
+                    }
+                    b.skip || b.subLanguage || (T += b.relevance);
+                    b = b.parent;
+                } while (b !== r.parent);
+                if (r.starts) {
+                    if (r.endSameAsBegin) {
+                        r.starts.endRe = r.endRe;
+                    }
+                    h(r.starts);
+                }
+                return a.returnEnd ? 0 : n.length;
+            }
+        }
+        var _ = {};
+        function m(n, t) {
+            var a;
+            var o = t && t[0];
+            S += n;
+            if (null == o) {
+                u();
+                return 0;
+            }
+            if ('begin' == _.type && 'end' == t.type && _.index == t.index && '' === o) {
+                S += s.slice(t.index, t.index + 1);
+                if (!i) {
+                    throw (((a = new Error('0 width match regex')).languageName = e), (a.badRule = _.rule), a);
+                }
+                return 1;
+            }
+            _ = t;
+            if ('begin' === t.type) {
+                return f(t);
+            }
+            if ('illegal' === t.type && !r) {
+                throw (((a = new Error('Illegal lexeme "' + o + '" for mode "' + (b.className || '<unnamed>') + '"')).mode = b), a);
+            }
+            if ('end' === t.type) {
+                var l = E(t);
+                if (void 0 != l) {
+                    return l;
+                }
+            }
+            S += o;
+            return o.length;
+        }
+        var R = p(e);
+        if (!R) {
+            throw (console.error(o.replace('{}', e)), new Error('Unknown language: "' + e + '"'));
+        }
+        compileLanguage(R);
+        var M;
+        var b = a || R;
+        var v = {};
+        var N = new l.__emitter(l);
+        !(function () {
+            for (var e = [], n = b; n !== R; n = n.parent) {
+                if (n.className) {
+                    e.unshift(n.className);
+                }
+            }
+            e.forEach((e) => N.openNode(e));
+        })();
+        var O;
+        var x;
+        var S = '';
+        var T = 0;
+        var D = 0;
+        try {
+            var w = false;
+            for (b.matcher.considerAll(); w ? (w = false) : ((b.matcher.lastIndex = D), b.matcher.considerAll()), (O = b.matcher.exec(s)); ) {
+                x = m(s.substring(D, O.index), O);
+                D = O.index + x;
+            }
+            m(s.substr(D));
+            N.closeAllNodes();
+            N.finalize();
+            M = N.toHTML();
+            return {
+                relevance: T,
+                value: M,
+                language: e,
+                illegal: false,
+                emitter: N,
+                top: b
+            };
+        } catch (n) {
+            console.log('CatchClause', n);
+            console.log('CatchClause', n);
+            if (n.message && n.message.includes('Illegal')) {
+                return {
+                    illegal: true,
+                    illegalBy: {
+                        msg: n.message,
+                        context: s.slice(D - 100, D + 100),
+                        mode: n.mode
+                    },
+                    sofar: M,
+                    relevance: 0,
+                    value: escape$1(s),
+                    emitter: N
+                };
+            }
+            if (i) {
+                return {
+                    relevance: 0,
+                    value: escape$1(s),
+                    emitter: N,
+                    language: e,
+                    top: b,
+                    errorRaised: n
+                };
+            }
+            throw n;
+        }
+    }
+    function g(e, n) {
+        n = n || l.languages || Object.keys(t);
+        var r = {
+            relevance: 0,
+            emitter: new l.__emitter(l),
+            value: escape$1(e)
+        };
+        var a = r;
+        n.filter(p)
+            .filter(m)
+            .forEach(function (n) {
+                var t = d(n, e, false);
+                t.language = n;
+                if (t.relevance > a.relevance) {
+                    a = t;
+                }
+                if (t.relevance > r.relevance) {
+                    a = r;
+                    r = t;
+                }
+            });
+        if (a.language) {
+            r.second_best = a;
+        }
+        return r;
+    }
+    function h(e) {
+        return l.tabReplace || l.useBR
+            ? e.replace(s, function (e, n) {
+                  return l.useBR && '\n' === e ? '<br>' : l.tabReplace ? n.replace(/\t/g, l.tabReplace) : '';
+              })
+            : e;
+    }
+    function f(e) {
+        var n;
+        var t;
+        var a;
+        var i;
+        var s;
+        var d = (function (e) {
+            var n;
+            var t = e.className + ' ';
+            t += e.parentNode ? e.parentNode.className : '';
+            if ((n = l.languageDetectRe.exec(t))) {
+                var r = p(n[1]);
+                r || (console.warn(o.replace('{}', n[1])), console.warn('Falling back to no-highlight mode for this block.', e));
+                return r ? n[1] : 'no-highlight';
+            }
+            return t.split(/\s+/).find((e) => c(e) || p(e));
+        })(e);
+        c(d) ||
+            (R('before:highlightBlock', {
+                block: e,
+                language: d
+            }),
+            l.useBR ? ((n = document.createElement('div')).innerHTML = e.innerHTML.replace(/\n/g, '').replace(/<br[ \/]*>/g, '\n')) : (n = e),
+            (s = n.textContent),
+            (a = d ? u(d, s, true) : g(s)),
+            (t = nodeStream$1(n)).length && (((i = document.createElement('div')).innerHTML = a.value), (a.value = mergeStreams$1(t, nodeStream$1(i), s))),
+            (a.value = h(a.value)),
+            R('after:highlightBlock', {
+                block: e,
+                result: a
+            }),
+            (e.innerHTML = a.value),
+            (e.className = (function (e, n, t) {
+                var a = n ? r[n] : t;
+                var i = [e.trim()];
+                e.match(/\bhljs\b/) || i.push('hljs');
+                e.includes(a) || i.push(a);
+                return i.join(' ').trim();
+            })(e.className, d, a.language)),
+            (e.result = {
+                language: a.language,
+                re: a.relevance
+            }),
+            a.second_best &&
+                (e.second_best = {
+                    language: a.second_best.language,
+                    re: a.second_best.relevance
+                }));
+    }
+    function E() {
+        if (!E.called) {
+            E.called = true;
+            var e = document.querySelectorAll('pre code');
+            n.forEach.call(e, f);
+        }
+    }
+    var _ = {
+        disableAutodetect: true
+    };
+    function p(e) {
+        e = (e || '').toLowerCase();
+        return t[e] || t[r[e]];
+    }
+    function m(e) {
+        var n = p(e);
+        return n && !n.disableAutodetect;
+    }
+    function R(e, n) {
+        var t = e;
+        a.forEach(function (e) {
+            if (e[t]) {
+                e[t](n);
+            }
+        });
+    }
+    Object.assign(e, {
+        highlight: u,
+        highlightAuto: g,
+        fixMarkup: h,
+        highlightBlock: f,
+        configure: function (e) {
+            l = inherit$1(l, e);
+        },
+        initHighlighting: E,
+        initHighlightingOnLoad: function () {
+            window.addEventListener('DOMContentLoaded', E, false);
+        },
+        registerLanguage: function (n, a) {
+            var s;
+            try {
+                s = a(e);
+            } catch (e) {
+                console.log('CatchClause', e);
+                console.log('CatchClause', e);
+                console.error("Language definition for '{}' could not be registered.".replace('{}', n));
+                if (!i) {
+                    throw e;
+                }
+                console.error(e);
+                s = _;
+            }
+            s.name || (s.name = n);
+            t[n] = s;
+            s.rawDefinition = a.bind(null, e);
+            if (s.aliases) {
+                s.aliases.forEach(function (e) {
+                    r[e] = n;
+                });
+            }
+        },
+        listLanguages: function () {
+            return Object.keys(t);
+        },
+        getLanguage: p,
+        requireLanguage: function (e) {
+            var n = p(e);
+            if (n) {
+                return n;
+            }
+            throw new Error("The '{}' language is required, but not loaded.".replace('{}', e));
+        },
+        autoDetection: m,
+        inherit: inherit$1,
+        addPlugin: function (e, n) {
+            a.push(e);
+        }
+    });
+    e.debugMode = function () {
+        i = false;
+    };
+    e.safeMode = function () {
+        i = true;
+    };
+    e.versionString = version;
+    for (const e in MODES) {
+        if ('object' == typeof MODES[e]) {
+            deepFreeze(MODES[e]);
+        }
+    }
+    Object.assign(e, MODES);
+    return e;
+};
+var highlight = HLJS({});
+module.exports = highlight;

+ 22 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/index.js

@@ -0,0 +1,22 @@
+const config = require('../../config');
+const hljs = require('./highlight'); // config.highlight.forEach(item => {
+//     hljs.registerLanguage(item, require(`./languages/${item}`).default);
+// });
+hljs.registerLanguage('c-like', require('./languages/c-like').default);
+hljs.registerLanguage('c', require('./languages/c').default);
+hljs.registerLanguage('bash', require('./languages/bash').default);
+hljs.registerLanguage('css', require('./languages/css').default);
+hljs.registerLanguage('dart', require('./languages/dart').default);
+hljs.registerLanguage('go', require('./languages/go').default);
+hljs.registerLanguage('java', require('./languages/java').default);
+hljs.registerLanguage('javascript', require('./languages/javascript').default);
+hljs.registerLanguage('json', require('./languages/json').default);
+hljs.registerLanguage('less', require('./languages/less').default);
+hljs.registerLanguage('scss', require('./languages/scss').default);
+hljs.registerLanguage('shell', require('./languages/shell').default);
+hljs.registerLanguage('xml', require('./languages/xml').default);
+hljs.registerLanguage('htmlbars', require('./languages/htmlbars').default);
+hljs.registerLanguage('python', require('./languages/python').default);
+hljs.registerLanguage('python-repl', require('./languages/python-repl').default);
+hljs.registerLanguage('typescript', require('./languages/typescript').default);
+module.exports = hljs;

+ 107 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/bash.js

@@ -0,0 +1,107 @@
+/*
+Language: Bash
+Author: vah <vahtenberg@gmail.com>
+Contributrors: Benjamin Pannell <contact@sierrasoftworks.com>
+Website: https://www.gnu.org/software/bash/
+Category: common
+*/
+
+export default function (hljs) {
+    const VAR = {};
+    const BRACED_VAR = {
+        begin: /\$\{/,
+        end: /\}/,
+        contains: [
+            {
+                begin: /:-/,
+                contains: [VAR]
+            } // default values
+        ]
+    };
+
+    Object.assign(VAR, {
+        className: 'variable',
+        variants: [
+            {
+                begin: /\$[\w\d#@][\w\d_]*/
+            },
+            BRACED_VAR
+        ]
+    });
+    const SUBST = {
+        className: 'subst',
+        begin: /\$\(/,
+        end: /\)/,
+        contains: [hljs.BACKSLASH_ESCAPE]
+    };
+    const QUOTE_STRING = {
+        className: 'string',
+        begin: /"/,
+        end: /"/,
+        contains: [hljs.BACKSLASH_ESCAPE, VAR, SUBST]
+    };
+    SUBST.contains.push(QUOTE_STRING);
+    const ESCAPED_QUOTE = {
+        className: '',
+        begin: /\\"/
+    };
+    const APOS_STRING = {
+        className: 'string',
+        begin: /'/,
+        end: /'/
+    };
+    const ARITHMETIC = {
+        begin: /\$\(\(/,
+        end: /\)\)/,
+        contains: [
+            {
+                begin: /\d+#[0-9a-f]+/,
+                className: 'number'
+            },
+            hljs.NUMBER_MODE,
+            VAR
+        ]
+    };
+    const SHEBANG = {
+        className: 'meta',
+        begin: /^#![^\n]+sh\s*$/,
+        relevance: 10
+    };
+    const FUNCTION = {
+        className: 'function',
+        begin: /\w[\w\d_]*\s*\(\s*\)\s*\{/,
+        returnBegin: true,
+        contains: [
+            hljs.inherit(hljs.TITLE_MODE, {
+                begin: /\w[\w\d_]*/
+            })
+        ],
+        relevance: 0
+    };
+    return {
+        name: 'Bash',
+        aliases: ['sh', 'zsh'],
+        lexemes: /\b-?[a-z\._]+\b/,
+        keywords: {
+            keyword: 'if then else elif fi for while in do done case esac function',
+            literal: 'true false',
+            built_in:
+                // Shell built-ins
+                // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html
+                'break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf ' +
+                'read readarray source type typeset ulimit unalias ' +
+                // Shell modifiers
+                'set shopt ' +
+                // Zsh built-ins
+                'autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles ' +
+                'compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate ' +
+                'fc fg float functions getcap getln history integer jobs kill limit log noglob popd print ' +
+                'pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit ' +
+                'unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof ' +
+                'zpty zregexparse zsocket zstyle ztcp',
+            _: '-ne -eq -lt -gt -f -d -e -s -l -a' // relevance booster
+        },
+
+        contains: [SHEBANG, FUNCTION, ARITHMETIC, hljs.HASH_COMMENT_MODE, QUOTE_STRING, ESCAPED_QUOTE, APOS_STRING, VAR]
+    };
+}

+ 237 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/c-like.js

@@ -0,0 +1,237 @@
+/*
+Language: C-like foundation grammar for C/C++ grammars
+Author: Ivan Sagalaev <maniac@softwaremaniacs.org>
+Contributors: Evgeny Stepanischev <imbolk@gmail.com>, Zaven Muradyan <megalivoithos@gmail.com>, Roel Deckers <admin@codingcat.nl>, Sam Wu <samsam2310@gmail.com>, Jordi Petit <jordi.petit@gmail.com>, Pieter Vantorre <pietervantorre@gmail.com>, Google Inc. (David Benjamin) <davidben@google.com>
+Category: common, system
+*/
+/* In the future the intention is to split out the C/C++ grammars distinctly
+since they are separate languages.  They will likely share a common foundation
+though, and this file sets the groundwork for that - so that we get the breaking
+change in v10 and don't have to change the requirements again later.
+
+See: https://github.com/highlightjs/highlight.js/issues/2146
+*/
+export default function (hljs) {
+    function optional(s) {
+        return '(?:' + s + ')?';
+    }
+    var DECLTYPE_AUTO_RE = 'decltype\\(auto\\)';
+    var NAMESPACE_RE = '[a-zA-Z_]\\w*::';
+    var TEMPLATE_ARGUMENT_RE = '<.*?>';
+    var FUNCTION_TYPE_RE = '(' + DECLTYPE_AUTO_RE + '|' + optional(NAMESPACE_RE) + '[a-zA-Z_]\\w*' + optional(TEMPLATE_ARGUMENT_RE) + ')';
+    var CPP_PRIMITIVE_TYPES = {
+        className: 'keyword',
+        begin: '\\b[a-z\\d_]*_t\\b'
+    };
+
+    // https://en.cppreference.com/w/cpp/language/escape
+    // \\ \x \xFF \u2837 \u00323747 \374
+    var CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)';
+    var STRINGS = {
+        className: 'string',
+        variants: [
+            {
+                begin: '(u8?|U|L)?"',
+                end: '"',
+                illegal: '\\n',
+                contains: [hljs.BACKSLASH_ESCAPE]
+            },
+            {
+                begin: "(u8?|U|L)?'(" + CHARACTER_ESCAPES + '|.)',
+                end: "'",
+                illegal: '.'
+            },
+            {
+                begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\((?:.|\n)*?\)\1"/
+            }
+        ]
+    };
+    var NUMBERS = {
+        className: 'number',
+        variants: [
+            {
+                begin: "\\b(0b[01']+)"
+            },
+            {
+                begin: "(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"
+            },
+            {
+                begin: "(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
+            }
+        ],
+        relevance: 0
+    };
+    var PREPROCESSOR = {
+        className: 'meta',
+        begin: /#\s*[a-z]+\b/,
+        end: /$/,
+        keywords: {
+            'meta-keyword': 'if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include'
+        },
+        contains: [
+            {
+                begin: /\\\n/,
+                relevance: 0
+            },
+            hljs.inherit(STRINGS, {
+                className: 'meta-string'
+            }),
+            {
+                className: 'meta-string',
+                begin: /<.*?>/,
+                end: /$/,
+                illegal: '\\n'
+            },
+            hljs.C_LINE_COMMENT_MODE,
+            hljs.C_BLOCK_COMMENT_MODE
+        ]
+    };
+    var TITLE_MODE = {
+        className: 'title',
+        begin: optional(NAMESPACE_RE) + hljs.IDENT_RE,
+        relevance: 0
+    };
+    var FUNCTION_TITLE = optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\(';
+    var CPP_KEYWORDS = {
+        keyword:
+            'int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend ' +
+            'do goto auto void enum else break extern using asm case typeid wchar_t ' +
+            'short reinterpret_cast|10 default double register explicit signed typename try this ' +
+            'switch continue inline delete alignas alignof constexpr consteval constinit decltype ' +
+            'concept co_await co_return co_yield requires ' +
+            'noexcept static_assert thread_local restrict final override ' +
+            'atomic_bool atomic_char atomic_schar ' +
+            'atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong ' +
+            'atomic_ullong new throw return ' +
+            'and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq',
+        built_in:
+            'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort terminate abs acos ' +
+            'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp ' +
+            'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper ' +
+            'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow ' +
+            'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp ' +
+            'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan ' +
+            'vfprintf vprintf vsprintf endl initializer_list unique_ptr _Bool complex _Complex imaginary _Imaginary',
+        literal: 'true false nullptr NULL'
+    };
+    var EXPRESSION_CONTAINS = [CPP_PRIMITIVE_TYPES, hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE, NUMBERS, STRINGS];
+    var EXPRESSION_CONTEXT = {
+        // This mode covers expression context where we can't expect a function
+        // definition and shouldn't highlight anything that looks like one:
+        // `return some()`, `else if()`, `(x*sum(1, 2))`
+        variants: [
+            {
+                begin: /=/,
+                end: /;/
+            },
+            {
+                begin: /\(/,
+                end: /\)/
+            },
+            {
+                beginKeywords: 'new throw return else',
+                end: /;/
+            }
+        ],
+        keywords: CPP_KEYWORDS,
+        contains: EXPRESSION_CONTAINS.concat([
+            {
+                begin: /\(/,
+                end: /\)/,
+                keywords: CPP_KEYWORDS,
+                contains: EXPRESSION_CONTAINS.concat(['self']),
+                relevance: 0
+            }
+        ]),
+        relevance: 0
+    };
+    var FUNCTION_DECLARATION = {
+        className: 'function',
+        begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
+        returnBegin: true,
+        end: /[{;=]/,
+        excludeEnd: true,
+        keywords: CPP_KEYWORDS,
+        illegal: /[^\w\s\*&:<>]/,
+        contains: [
+            {
+                // to prevent it from being confused as the function title
+                begin: DECLTYPE_AUTO_RE,
+                keywords: CPP_KEYWORDS,
+                relevance: 0
+            },
+            {
+                begin: FUNCTION_TITLE,
+                returnBegin: true,
+                contains: [TITLE_MODE],
+                relevance: 0
+            },
+            {
+                className: 'params',
+                begin: /\(/,
+                end: /\)/,
+                keywords: CPP_KEYWORDS,
+                relevance: 0,
+                contains: [
+                    hljs.C_LINE_COMMENT_MODE,
+                    hljs.C_BLOCK_COMMENT_MODE,
+                    STRINGS,
+                    NUMBERS,
+                    CPP_PRIMITIVE_TYPES,
+                    // Count matching parentheses.
+                    {
+                        begin: /\(/,
+                        end: /\)/,
+                        keywords: CPP_KEYWORDS,
+                        relevance: 0,
+                        contains: ['self', hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE, STRINGS, NUMBERS, CPP_PRIMITIVE_TYPES]
+                    }
+                ]
+            },
+            CPP_PRIMITIVE_TYPES,
+            hljs.C_LINE_COMMENT_MODE,
+            hljs.C_BLOCK_COMMENT_MODE,
+            PREPROCESSOR
+        ]
+    };
+    return {
+        aliases: ['c', 'cc', 'h', 'c++', 'h++', 'hpp', 'hh', 'hxx', 'cxx'],
+        keywords: CPP_KEYWORDS,
+        // the base c-like language will NEVER be auto-detected, rather the
+        // derivitives: c, c++, arduino turn auto-detect back on for themselves
+        disableAutodetect: true,
+        illegal: '</',
+        contains: [].concat(EXPRESSION_CONTEXT, FUNCTION_DECLARATION, EXPRESSION_CONTAINS, [
+            PREPROCESSOR,
+            {
+                begin: '\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<',
+                end: '>',
+                keywords: CPP_KEYWORDS,
+                contains: ['self', CPP_PRIMITIVE_TYPES]
+            },
+            {
+                begin: hljs.IDENT_RE + '::',
+                keywords: CPP_KEYWORDS
+            },
+            {
+                className: 'class',
+                beginKeywords: 'class struct',
+                end: /[{;:]/,
+                contains: [
+                    {
+                        begin: /</,
+                        end: />/,
+                        contains: ['self']
+                    },
+                    // skip generic stuff
+                    hljs.TITLE_MODE
+                ]
+            }
+        ]),
+        exports: {
+            preprocessor: PREPROCESSOR,
+            strings: STRINGS,
+            keywords: CPP_KEYWORDS
+        }
+    };
+}

+ 20 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/c.js

@@ -0,0 +1,20 @@
+/*
+Language: C
+Category: common, system
+Website: https://en.wikipedia.org/wiki/C_(programming_language)
+Requires: c-like.js
+*/
+
+export default function (hljs) {
+    var lang = hljs.getLanguage('c-like').rawDefinition();
+    // Until C is actually different than C++ there is no reason to auto-detect C
+    // as it's own language since it would just fail auto-detect testing or
+    // simply match with C++.
+    //
+    // See further comments in c-like.js.
+
+    // lang.disableAutodetect = false;
+    lang.name = 'C';
+    lang.aliases = ['c', 'h'];
+    return lang;
+}

+ 138 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/css.js

@@ -0,0 +1,138 @@
+/*
+Language: CSS
+Category: common, css
+Website: https://developer.mozilla.org/en-US/docs/Web/CSS
+*/
+
+export default function (hljs) {
+    var FUNCTION_LIKE = {
+        begin: /[\w-]+\(/,
+        returnBegin: true,
+        contains: [
+            {
+                className: 'built_in',
+                begin: /[\w-]+/
+            },
+            {
+                begin: /\(/,
+                end: /\)/,
+                contains: [hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE, hljs.CSS_NUMBER_MODE]
+            }
+        ]
+    };
+    var ATTRIBUTE = {
+        className: 'attribute',
+        begin: /\S/,
+        end: ':',
+        excludeEnd: true,
+        starts: {
+            endsWithParent: true,
+            excludeEnd: true,
+            contains: [
+                FUNCTION_LIKE,
+                hljs.CSS_NUMBER_MODE,
+                hljs.QUOTE_STRING_MODE,
+                hljs.APOS_STRING_MODE,
+                hljs.C_BLOCK_COMMENT_MODE,
+                {
+                    className: 'number',
+                    begin: '#[0-9A-Fa-f]+'
+                },
+                {
+                    className: 'meta',
+                    begin: '!important'
+                }
+            ]
+        }
+    };
+    var AT_IDENTIFIER = '@[a-z-]+'; // @font-face
+    var AT_MODIFIERS = 'and or not only';
+    var AT_PROPERTY_RE = /@\-?\w[\w]*(\-\w+)*/; // @-webkit-keyframes
+    var IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';
+    var RULE = {
+        begin: /(?:[A-Z\_\.\-]+|--[a-zA-Z0-9_-]+)\s*:/,
+        returnBegin: true,
+        end: ';',
+        endsWithParent: true,
+        contains: [ATTRIBUTE]
+    };
+    return {
+        name: 'CSS',
+        case_insensitive: true,
+        illegal: /[=\/|'\$]/,
+        contains: [
+            hljs.C_BLOCK_COMMENT_MODE,
+            {
+                className: 'selector-id',
+                begin: /#[A-Za-z0-9_-]+/
+            },
+            {
+                className: 'selector-class',
+                begin: /\.[A-Za-z0-9_-]+/
+            },
+            {
+                className: 'selector-attr',
+                begin: /\[/,
+                end: /\]/,
+                illegal: '$',
+                contains: [hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE]
+            },
+            {
+                className: 'selector-pseudo',
+                begin: /:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/
+            },
+            // matching these here allows us to treat them more like regular CSS
+            // rules so everything between the {} gets regular rule highlighting,
+            // which is what we want for page and font-face
+            {
+                begin: '@(page|font-face)',
+                lexemes: AT_IDENTIFIER,
+                keywords: '@page @font-face'
+            },
+            {
+                begin: '@',
+                end: '[{;]',
+                // at_rule eating first "{" is a good thing
+                // because it doesn’t let it to be parsed as
+                // a rule set but instead drops parser into
+                // the default mode which is how it should be.
+                illegal: /:/,
+                // break on Less variables @var: ...
+                returnBegin: true,
+                contains: [
+                    {
+                        className: 'keyword',
+                        begin: AT_PROPERTY_RE
+                    },
+                    {
+                        begin: /\s/,
+                        endsWithParent: true,
+                        excludeEnd: true,
+                        relevance: 0,
+                        keywords: AT_MODIFIERS,
+                        contains: [
+                            {
+                                begin: /[a-z-]+:/,
+                                className: 'attribute'
+                            },
+                            hljs.APOS_STRING_MODE,
+                            hljs.QUOTE_STRING_MODE,
+                            hljs.CSS_NUMBER_MODE
+                        ]
+                    }
+                ]
+            },
+            {
+                className: 'selector-tag',
+                begin: IDENT_RE,
+                relevance: 0
+            },
+            {
+                begin: '{',
+                end: '}',
+                illegal: /\S/,
+                contains: [hljs.C_BLOCK_COMMENT_MODE, RULE]
+            }
+        ]
+    };
+}

+ 126 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/dart.js

@@ -0,0 +1,126 @@
+/*
+Language: Dart
+Requires: markdown.js
+Author: Maxim Dikun <dikmax@gmail.com>
+Description: Dart a modern, object-oriented language developed by Google. For more information see https://www.dartlang.org/
+Website: https://dart.dev
+Category: scripting
+*/
+
+export default function (hljs) {
+    var SUBST = {
+        className: 'subst',
+        variants: [
+            {
+                begin: '\\$[A-Za-z0-9_]+'
+            }
+        ]
+    };
+    var BRACED_SUBST = {
+        className: 'subst',
+        variants: [
+            {
+                begin: '\\${',
+                end: '}'
+            }
+        ],
+        keywords: 'true false null this is new super'
+    };
+    var STRING = {
+        className: 'string',
+        variants: [
+            {
+                begin: "r'''",
+                end: "'''"
+            },
+            {
+                begin: 'r"""',
+                end: '"""'
+            },
+            {
+                begin: "r'",
+                end: "'",
+                illegal: '\\n'
+            },
+            {
+                begin: 'r"',
+                end: '"',
+                illegal: '\\n'
+            },
+            {
+                begin: "'''",
+                end: "'''",
+                contains: [hljs.BACKSLASH_ESCAPE, SUBST, BRACED_SUBST]
+            },
+            {
+                begin: '"""',
+                end: '"""',
+                contains: [hljs.BACKSLASH_ESCAPE, SUBST, BRACED_SUBST]
+            },
+            {
+                begin: "'",
+                end: "'",
+                illegal: '\\n',
+                contains: [hljs.BACKSLASH_ESCAPE, SUBST, BRACED_SUBST]
+            },
+            {
+                begin: '"',
+                end: '"',
+                illegal: '\\n',
+                contains: [hljs.BACKSLASH_ESCAPE, SUBST, BRACED_SUBST]
+            }
+        ]
+    };
+    BRACED_SUBST.contains = [hljs.C_NUMBER_MODE, STRING];
+    var KEYWORDS = {
+        keyword:
+            'abstract as assert async await break case catch class const continue covariant default deferred do dynamic else enum export extends extension external factory false final finally for Function get hide if implements import in inferface is library mixin new null on operator part rethrow return set show static ' +
+            'super switch sync this throw true try typedef var void while with yield',
+        // dart:core
+        built_in:
+            'Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set Stopwatch String StringBuffer StringSink Symbol Type Uri bool double dynamic int num print Element ElementList document querySelector querySelectorAll window'
+    };
+    return {
+        name: 'Dart',
+        keywords: KEYWORDS,
+        contains: [
+            STRING,
+            hljs.COMMENT('/\\*\\*', '\\*/', {
+                subLanguage: 'markdown',
+                relevance: 0
+            }),
+            hljs.COMMENT('///+\\s*', '$', {
+                contains: [
+                    {
+                        subLanguage: 'markdown',
+                        begin: '.',
+                        end: '$',
+                        relevance: 0
+                    }
+                ]
+            }),
+            hljs.C_LINE_COMMENT_MODE,
+            hljs.C_BLOCK_COMMENT_MODE,
+            {
+                className: 'class',
+                beginKeywords: 'class interface',
+                end: '{',
+                excludeEnd: true,
+                contains: [
+                    {
+                        beginKeywords: 'extends implements'
+                    },
+                    hljs.UNDERSCORE_TITLE_MODE
+                ]
+            },
+            hljs.C_NUMBER_MODE,
+            {
+                className: 'meta',
+                begin: '@[A-Za-z]+'
+            },
+            {
+                begin: '=>' // No markup, just a relevance booster
+            }
+        ]
+    };
+}

+ 68 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/go.js

@@ -0,0 +1,68 @@
+/*
+Language: Go
+Author: Stephan Kountso aka StepLg <steplg@gmail.com>
+Contributors: Evgeny Stepanischev <imbolk@gmail.com>
+Description: Google go language (golang). For info about language
+Website: http://golang.org/
+Category: common, system
+*/
+
+export default function (hljs) {
+    var GO_KEYWORDS = {
+        keyword:
+            'break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 ' +
+            'uint16 uint32 uint64 int uint uintptr rune',
+        literal: 'true false iota nil',
+        built_in: 'append cap close complex copy imag len make new panic print println real recover delete'
+    };
+    return {
+        name: 'Go',
+        aliases: ['golang'],
+        keywords: GO_KEYWORDS,
+        illegal: '</',
+        contains: [
+            hljs.C_LINE_COMMENT_MODE,
+            hljs.C_BLOCK_COMMENT_MODE,
+            {
+                className: 'string',
+                variants: [
+                    hljs.QUOTE_STRING_MODE,
+                    hljs.APOS_STRING_MODE,
+                    {
+                        begin: '`',
+                        end: '`'
+                    }
+                ]
+            },
+            {
+                className: 'number',
+                variants: [
+                    {
+                        begin: hljs.C_NUMBER_RE + '[i]',
+                        relevance: 1
+                    },
+                    hljs.C_NUMBER_MODE
+                ]
+            },
+            {
+                begin: /:=/ // relevance booster
+            },
+            {
+                className: 'function',
+                beginKeywords: 'func',
+                end: '\\s*(\\{|$)',
+                excludeEnd: true,
+                contains: [
+                    hljs.TITLE_MODE,
+                    {
+                        className: 'params',
+                        begin: /\(/,
+                        end: /\)/,
+                        keywords: GO_KEYWORDS,
+                        illegal: /["']/
+                    }
+                ]
+            }
+        ]
+    };
+}

+ 67 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/htmlbars.js

@@ -0,0 +1,67 @@
+/*
+Language: HTMLBars
+Requires: xml.js
+Author: Michael Johnston <lastobelus@gmail.com>
+Description: Matcher for HTMLBars
+Website: https://github.com/tildeio/htmlbars
+Category: template
+*/
+
+export default function (hljs) {
+    var BUILT_INS =
+        'action collection component concat debugger each each-in else get hash if input link-to loc log mut outlet partial query-params render textarea unbound unless with yield view';
+    var ATTR_ASSIGNMENT = {
+        illegal: /\}\}/,
+        begin: /[a-zA-Z0-9_]+=/,
+        returnBegin: true,
+        relevance: 0,
+        contains: [
+            {
+                className: 'attr',
+                begin: /[a-zA-Z0-9_]+/
+            }
+        ]
+    };
+    var TAG_INNARDS = {
+        endsWithParent: true,
+        relevance: 0,
+        keywords: {
+            keyword: 'as',
+            built_in: BUILT_INS
+        },
+        contains: [hljs.QUOTE_STRING_MODE, ATTR_ASSIGNMENT, hljs.NUMBER_MODE]
+    };
+    return {
+        name: 'HTMLBars',
+        case_insensitive: true,
+        subLanguage: 'xml',
+        contains: [
+            hljs.COMMENT('{{!(--)?', '(--)?}}'),
+            {
+                className: 'template-tag',
+                begin: /\{\{[#\/]/,
+                end: /\}\}/,
+                contains: [
+                    {
+                        className: 'name',
+                        begin: /[a-zA-Z\.\-]+/,
+                        keywords: {
+                            'builtin-name': BUILT_INS
+                        },
+                        starts: TAG_INNARDS
+                    }
+                ]
+            },
+            {
+                className: 'template-variable',
+                begin: /\{\{[a-zA-Z][a-zA-Z\-]+/,
+                end: /\}\}/,
+                keywords: {
+                    keyword: 'as',
+                    built_in: BUILT_INS
+                },
+                contains: [hljs.QUOTE_STRING_MODE]
+            }
+        ]
+    };
+}

+ 122 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/java.js

@@ -0,0 +1,122 @@
+/*
+Language: Java
+Author: Vsevolod Solovyov <vsevolod.solovyov@gmail.com>
+Category: common, enterprise
+Website: https://www.java.com/
+*/
+
+export default function (hljs) {
+    var JAVA_IDENT_RE = '[\xC0-\u02B8a-zA-Z_$][\xC0-\u02B8a-zA-Z_$0-9]*';
+    var GENERIC_IDENT_RE = JAVA_IDENT_RE + '(<' + JAVA_IDENT_RE + '(\\s*,\\s*' + JAVA_IDENT_RE + ')*>)?';
+    var KEYWORDS =
+        'false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short ' +
+        'package default double public try this switch continue throws protected public private ' +
+        'module requires exports do';
+    var ANNOTATION = {
+        className: 'meta',
+        begin: '@' + JAVA_IDENT_RE,
+        contains: [
+            {
+                begin: /\(/,
+                end: /\)/,
+                contains: ['self'] // allow nested () inside our annotation
+            }
+        ]
+    };
+    // https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html
+    var JAVA_NUMBER_RE =
+        '\\b(0[bB]([01]+[01_]+[01]+|[01]+)' +
+        // 0b...
+        '|' +
+        '0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)' +
+        // 0x...
+        '|' +
+        '(' +
+        '([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?' +
+        '|' +
+        '\\.([\\d]+[\\d_]+[\\d]+|[\\d]+)' +
+        ')' +
+        '([eE][-+]?\\d+)?' +
+        // octal, decimal, float
+        ')' +
+        '[lLfF]?';
+    var JAVA_NUMBER_MODE = {
+        className: 'number',
+        begin: JAVA_NUMBER_RE,
+        relevance: 0
+    };
+    return {
+        name: 'Java',
+        aliases: ['jsp'],
+        keywords: KEYWORDS,
+        illegal: /<\/|#/,
+        contains: [
+            hljs.COMMENT('/\\*\\*', '\\*/', {
+                relevance: 0,
+                contains: [
+                    {
+                        // eat up @'s in emails to prevent them to be recognized as doctags
+                        begin: /\w+@/,
+                        relevance: 0
+                    },
+                    {
+                        className: 'doctag',
+                        begin: '@[A-Za-z]+'
+                    }
+                ]
+            }),
+            hljs.C_LINE_COMMENT_MODE,
+            hljs.C_BLOCK_COMMENT_MODE,
+            hljs.APOS_STRING_MODE,
+            hljs.QUOTE_STRING_MODE,
+            {
+                className: 'class',
+                beginKeywords: 'class interface',
+                end: /[{;=]/,
+                excludeEnd: true,
+                keywords: 'class interface',
+                illegal: /[:"\[\]]/,
+                contains: [
+                    {
+                        beginKeywords: 'extends implements'
+                    },
+                    hljs.UNDERSCORE_TITLE_MODE
+                ]
+            },
+            {
+                // Expression keywords prevent 'keyword Name(...)' from being
+                // recognized as a function definition
+                beginKeywords: 'new throw return else',
+                relevance: 0
+            },
+            {
+                className: 'function',
+                begin: '(' + GENERIC_IDENT_RE + '\\s+)+' + hljs.UNDERSCORE_IDENT_RE + '\\s*\\(',
+                returnBegin: true,
+                end: /[{;=]/,
+                excludeEnd: true,
+                keywords: KEYWORDS,
+                contains: [
+                    {
+                        begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(',
+                        returnBegin: true,
+                        relevance: 0,
+                        contains: [hljs.UNDERSCORE_TITLE_MODE]
+                    },
+                    {
+                        className: 'params',
+                        begin: /\(/,
+                        end: /\)/,
+                        keywords: KEYWORDS,
+                        relevance: 0,
+                        contains: [ANNOTATION, hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE, hljs.C_NUMBER_MODE, hljs.C_BLOCK_COMMENT_MODE]
+                    },
+                    hljs.C_LINE_COMMENT_MODE,
+                    hljs.C_BLOCK_COMMENT_MODE
+                ]
+            },
+            JAVA_NUMBER_MODE,
+            ANNOTATION
+        ]
+    };
+}

+ 287 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/javascript.js

@@ -0,0 +1,287 @@
+/*
+Language: JavaScript
+Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.
+Category: common, scripting
+Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript
+*/
+
+export default function (hljs) {
+    var FRAGMENT = {
+        begin: '<>',
+        end: '</>'
+    };
+    var XML_TAG = {
+        begin: /<[A-Za-z0-9\\._:-]+/,
+        end: /\/[A-Za-z0-9\\._:-]+>|\/>/
+    };
+    var IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
+    var KEYWORDS = {
+        keyword:
+            'in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static ' +
+            // ECMAScript 6 modules import
+            'import from as',
+        literal: 'true false null undefined NaN Infinity',
+        built_in:
+            'eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError ' +
+            'TypeError URIError Number Math Date String RegExp Array Float32Array ' +
+            'Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array ' +
+            'Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require ' +
+            'module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect ' +
+            'Promise'
+    };
+    var NUMBER = {
+        className: 'number',
+        variants: [
+            {
+                begin: '\\b(0[bB][01]+)n?'
+            },
+            {
+                begin: '\\b(0[oO][0-7]+)n?'
+            },
+            {
+                begin: hljs.C_NUMBER_RE + 'n?'
+            }
+        ],
+        relevance: 0
+    };
+    var SUBST = {
+        className: 'subst',
+        begin: '\\$\\{',
+        end: '\\}',
+        keywords: KEYWORDS,
+        contains: [] // defined later
+    };
+
+    var HTML_TEMPLATE = {
+        begin: 'html`',
+        end: '',
+        starts: {
+            end: '`',
+            returnEnd: false,
+            contains: [hljs.BACKSLASH_ESCAPE, SUBST],
+            subLanguage: 'xml'
+        }
+    };
+    var CSS_TEMPLATE = {
+        begin: 'css`',
+        end: '',
+        starts: {
+            end: '`',
+            returnEnd: false,
+            contains: [hljs.BACKSLASH_ESCAPE, SUBST],
+            subLanguage: 'css'
+        }
+    };
+    var TEMPLATE_STRING = {
+        className: 'string',
+        begin: '`',
+        end: '`',
+        contains: [hljs.BACKSLASH_ESCAPE, SUBST]
+    };
+    SUBST.contains = [hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE, HTML_TEMPLATE, CSS_TEMPLATE, TEMPLATE_STRING, NUMBER, hljs.REGEXP_MODE];
+    var PARAMS_CONTAINS = SUBST.contains.concat([hljs.C_BLOCK_COMMENT_MODE, hljs.C_LINE_COMMENT_MODE]);
+    var PARAMS = {
+        className: 'params',
+        begin: /\(/,
+        end: /\)/,
+        excludeBegin: true,
+        excludeEnd: true,
+        contains: PARAMS_CONTAINS
+    };
+    return {
+        name: 'JavaScript',
+        aliases: ['js', 'jsx', 'mjs', 'cjs'],
+        keywords: KEYWORDS,
+        contains: [
+            {
+                className: 'meta',
+                relevance: 10,
+                begin: /^\s*['"]use (strict|asm)['"]/
+            },
+            {
+                className: 'meta',
+                begin: /^#!/,
+                end: /$/
+            },
+            hljs.APOS_STRING_MODE,
+            hljs.QUOTE_STRING_MODE,
+            HTML_TEMPLATE,
+            CSS_TEMPLATE,
+            TEMPLATE_STRING,
+            hljs.C_LINE_COMMENT_MODE,
+            hljs.COMMENT('/\\*\\*', '\\*/', {
+                relevance: 0,
+                contains: [
+                    {
+                        className: 'doctag',
+                        begin: '@[A-Za-z]+',
+                        contains: [
+                            {
+                                className: 'type',
+                                begin: '\\{',
+                                end: '\\}',
+                                relevance: 0
+                            },
+                            {
+                                className: 'variable',
+                                begin: IDENT_RE + '(?=\\s*(-)|$)',
+                                endsParent: true,
+                                relevance: 0
+                            },
+                            // eat spaces (not newlines) so we can find
+                            // types or variables
+                            {
+                                begin: /(?=[^\n])\s/,
+                                relevance: 0
+                            }
+                        ]
+                    }
+                ]
+            }),
+            hljs.C_BLOCK_COMMENT_MODE,
+            NUMBER,
+            {
+                // object attr container
+                begin: /[{,\n]\s*/,
+                relevance: 0,
+                contains: [
+                    {
+                        begin: IDENT_RE + '\\s*:',
+                        returnBegin: true,
+                        relevance: 0,
+                        contains: [
+                            {
+                                className: 'attr',
+                                begin: IDENT_RE,
+                                relevance: 0
+                            }
+                        ]
+                    }
+                ]
+            },
+            {
+                // "value" container
+                begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
+                keywords: 'return throw case',
+                contains: [
+                    hljs.C_LINE_COMMENT_MODE,
+                    hljs.C_BLOCK_COMMENT_MODE,
+                    hljs.REGEXP_MODE,
+                    {
+                        className: 'function',
+                        begin: '(\\(.*?\\)|' + IDENT_RE + ')\\s*=>',
+                        returnBegin: true,
+                        end: '\\s*=>',
+                        contains: [
+                            {
+                                className: 'params',
+                                variants: [
+                                    {
+                                        begin: IDENT_RE
+                                    },
+                                    {
+                                        begin: /\(\s*\)/
+                                    },
+                                    {
+                                        begin: /\(/,
+                                        end: /\)/,
+                                        excludeBegin: true,
+                                        excludeEnd: true,
+                                        keywords: KEYWORDS,
+                                        contains: PARAMS_CONTAINS
+                                    }
+                                ]
+                            }
+                        ]
+                    },
+                    {
+                        // could be a comma delimited list of params to a function call
+                        begin: /,/,
+                        relevance: 0
+                    },
+                    {
+                        className: '',
+                        begin: /\s/,
+                        end: /\s*/,
+                        skip: true
+                    },
+                    {
+                        // JSX
+                        variants: [
+                            {
+                                begin: FRAGMENT.begin,
+                                end: FRAGMENT.end
+                            },
+                            {
+                                begin: XML_TAG.begin,
+                                end: XML_TAG.end
+                            }
+                        ],
+                        subLanguage: 'xml',
+                        contains: [
+                            {
+                                begin: XML_TAG.begin,
+                                end: XML_TAG.end,
+                                skip: true,
+                                contains: ['self']
+                            }
+                        ]
+                    }
+                ],
+                relevance: 0
+            },
+            {
+                className: 'function',
+                beginKeywords: 'function',
+                end: /\{/,
+                excludeEnd: true,
+                contains: [
+                    hljs.inherit(hljs.TITLE_MODE, {
+                        begin: IDENT_RE
+                    }),
+                    PARAMS
+                ],
+                illegal: /\[|%/
+            },
+            {
+                begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
+            },
+            hljs.METHOD_GUARD,
+            {
+                // ES6 class
+                className: 'class',
+                beginKeywords: 'class',
+                end: /[{;=]/,
+                excludeEnd: true,
+                illegal: /[:"\[\]]/,
+                contains: [
+                    {
+                        beginKeywords: 'extends'
+                    },
+                    hljs.UNDERSCORE_TITLE_MODE
+                ]
+            },
+            {
+                beginKeywords: 'constructor',
+                end: /\{/,
+                excludeEnd: true
+            },
+            {
+                begin: '(get|set)\\s*(?=' + IDENT_RE + '\\()',
+                end: /{/,
+                keywords: 'get set',
+                contains: [
+                    hljs.inherit(hljs.TITLE_MODE, {
+                        begin: IDENT_RE
+                    }),
+                    {
+                        begin: /\(\)/
+                    },
+                    // eat to avoid empty params
+                    PARAMS
+                ]
+            }
+        ],
+        illegal: /#(?!!)/
+    };
+}

+ 56 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/json.js

@@ -0,0 +1,56 @@
+/*
+Language: JSON
+Description: JSON (JavaScript Object Notation) is a lightweight data-interchange format.
+Author: Ivan Sagalaev <maniac@softwaremaniacs.org>
+Website: http://www.json.org
+Category: common, protocols
+*/
+
+export default function (hljs) {
+    var LITERALS = {
+        literal: 'true false null'
+    };
+    var ALLOWED_COMMENTS = [hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE];
+    var TYPES = [hljs.QUOTE_STRING_MODE, hljs.C_NUMBER_MODE];
+    var VALUE_CONTAINER = {
+        end: ',',
+        endsWithParent: true,
+        excludeEnd: true,
+        contains: TYPES,
+        keywords: LITERALS
+    };
+    var OBJECT = {
+        begin: '{',
+        end: '}',
+        contains: [
+            {
+                className: 'attr',
+                begin: /"/,
+                end: /"/,
+                contains: [hljs.BACKSLASH_ESCAPE],
+                illegal: '\\n'
+            },
+            hljs.inherit(VALUE_CONTAINER, {
+                begin: /:/
+            })
+        ].concat(ALLOWED_COMMENTS),
+        illegal: '\\S'
+    };
+    var ARRAY = {
+        begin: '\\[',
+        end: '\\]',
+        contains: [hljs.inherit(VALUE_CONTAINER)],
+        // inherit is a workaround for a bug that makes shared modes with endsWithParent compile only the ending of one of the parents
+        illegal: '\\S'
+    };
+    TYPES.push(OBJECT, ARRAY);
+    ALLOWED_COMMENTS.forEach(function (rule) {
+        TYPES.push(rule);
+    });
+    return {
+        name: 'JSON',
+        contains: TYPES,
+        keywords: LITERALS,
+        illegal: '\\S'
+    };
+}

+ 201 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/less.js

@@ -0,0 +1,201 @@
+/*
+Language: Less
+Description: It's CSS, with just a little more.
+Author:   Max Mikhailov <seven.phases.max@gmail.com>
+Website: http://lesscss.org
+Category: common, css
+*/
+
+export default function (hljs) {
+    var IDENT_RE = '[\\w-]+'; // yes, Less identifiers may begin with a digit
+    var INTERP_IDENT_RE = '(' + IDENT_RE + '|@{' + IDENT_RE + '})';
+
+    /* Generic Modes */
+    var RULES = [];
+    var VALUE = []; // forward def. for recursive modes
+    var STRING_MODE = function (c) {
+        return {
+            // Less strings are not multiline (also include '~' for more consistent coloring of "escaped" strings)
+            className: 'string',
+            begin: '~?' + c + '.*?' + c
+        };
+    };
+    var IDENT_MODE = function (name, begin, relevance) {
+        return {
+            className: name,
+            begin: begin,
+            relevance: relevance
+        };
+    };
+    var PARENS_MODE = {
+        // used only to properly balance nested parens inside mixin call, def. arg list
+        begin: '\\(',
+        end: '\\)',
+        contains: VALUE,
+        relevance: 0
+    };
+
+    // generic Less highlighter (used almost everywhere except selectors):
+    VALUE.push(
+        hljs.C_LINE_COMMENT_MODE,
+        hljs.C_BLOCK_COMMENT_MODE,
+        STRING_MODE("'"),
+        STRING_MODE('"'),
+        hljs.CSS_NUMBER_MODE,
+        // fixme: it does not include dot for numbers like .5em :(
+        {
+            begin: '(url|data-uri)\\(',
+            starts: {
+                className: 'string',
+                end: '[\\)\\n]',
+                excludeEnd: true
+            }
+        },
+        IDENT_MODE('number', '#[0-9A-Fa-f]+\\b'),
+        PARENS_MODE,
+        IDENT_MODE('variable', '@@?' + IDENT_RE, 10),
+        IDENT_MODE('variable', '@{' + IDENT_RE + '}'),
+        IDENT_MODE('built_in', '~?`[^`]*?`'),
+        // inline javascript (or whatever host language) *multiline* string
+        {
+            // @media features (it’s here to not duplicate things in AT_RULE_MODE with extra PARENS_MODE overriding):
+            className: 'attribute',
+            begin: IDENT_RE + '\\s*:',
+            end: ':',
+            returnBegin: true,
+            excludeEnd: true
+        },
+        {
+            className: 'meta',
+            begin: '!important'
+        }
+    );
+    var VALUE_WITH_RULESETS = VALUE.concat({
+        begin: '{',
+        end: '}',
+        contains: RULES
+    });
+    var MIXIN_GUARD_MODE = {
+        beginKeywords: 'when',
+        endsWithParent: true,
+        contains: [
+            {
+                beginKeywords: 'and not'
+            }
+        ].concat(VALUE) // using this form to override VALUE’s 'function' match
+    };
+
+    /* Rule-Level Modes */
+
+    var RULE_MODE = {
+        begin: INTERP_IDENT_RE + '\\s*:',
+        returnBegin: true,
+        end: '[;}]',
+        relevance: 0,
+        contains: [
+            {
+                className: 'attribute',
+                begin: INTERP_IDENT_RE,
+                end: ':',
+                excludeEnd: true,
+                starts: {
+                    endsWithParent: true,
+                    illegal: '[<=$]',
+                    relevance: 0,
+                    contains: VALUE
+                }
+            }
+        ]
+    };
+    var AT_RULE_MODE = {
+        className: 'keyword',
+        begin: '@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b',
+        starts: {
+            end: '[;{}]',
+            returnEnd: true,
+            contains: VALUE,
+            relevance: 0
+        }
+    };
+
+    // variable definitions and calls
+    var VAR_RULE_MODE = {
+        className: 'variable',
+        variants: [
+            // using more strict pattern for higher relevance to increase chances of Less detection.
+            // this is *the only* Less specific statement used in most of the sources, so...
+            // (we’ll still often loose to the css-parser unless there's '//' comment,
+            // simply because 1 variable just can't beat 99 properties :)
+            {
+                begin: '@' + IDENT_RE + '\\s*:',
+                relevance: 15
+            },
+            {
+                begin: '@' + IDENT_RE
+            }
+        ],
+        starts: {
+            end: '[;}]',
+            returnEnd: true,
+            contains: VALUE_WITH_RULESETS
+        }
+    };
+    var SELECTOR_MODE = {
+        // first parse unambiguous selectors (i.e. those not starting with tag)
+        // then fall into the scary lookahead-discriminator variant.
+        // this mode also handles mixin definitions and calls
+        variants: [
+            {
+                begin: '[\\.#:&\\[>]',
+                end: '[;{}]' // mixin calls end with ';'
+            },
+            {
+                begin: INTERP_IDENT_RE,
+                end: '{'
+            }
+        ],
+        returnBegin: true,
+        returnEnd: true,
+        illegal: '[<=\'$"]',
+        relevance: 0,
+        contains: [
+            hljs.C_LINE_COMMENT_MODE,
+            hljs.C_BLOCK_COMMENT_MODE,
+            MIXIN_GUARD_MODE,
+            IDENT_MODE('keyword', 'all\\b'),
+            IDENT_MODE('variable', '@{' + IDENT_RE + '}'),
+            // otherwise it’s identified as tag
+            IDENT_MODE('selector-tag', INTERP_IDENT_RE + '%?', 0),
+            // '%' for more consistent coloring of @keyframes "tags"
+            IDENT_MODE('selector-id', '#' + INTERP_IDENT_RE),
+            IDENT_MODE('selector-class', '\\.' + INTERP_IDENT_RE, 0),
+            IDENT_MODE('selector-tag', '&', 0),
+            {
+                className: 'selector-attr',
+                begin: '\\[',
+                end: '\\]'
+            },
+            {
+                className: 'selector-pseudo',
+                begin: /:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/
+            },
+            {
+                begin: '\\(',
+                end: '\\)',
+                contains: VALUE_WITH_RULESETS
+            },
+            // argument list of parametric mixins
+            {
+                begin: '!important'
+            } // eat !important after mixin call or it will be colored as tag
+        ]
+    };
+
+    RULES.push(hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE, AT_RULE_MODE, VAR_RULE_MODE, RULE_MODE, SELECTOR_MODE);
+    return {
+        name: 'Less',
+        case_insensitive: true,
+        illegal: '[=>\'/<($"]',
+        contains: RULES
+    };
+}

+ 34 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/python-repl.js

@@ -0,0 +1,34 @@
+/*
+Language: Python REPL
+Requires: python.js
+Author: Josh Goebel <hello@joshgoebel.com>
+Category: common
+*/
+
+export default function (hljs) {
+    return {
+        aliases: ['pycon'],
+        contains: [
+            {
+                className: 'meta',
+                starts: {
+                    // a space separates the REPL prefix from the actual code
+                    // this is purely for cleaner HTML output
+                    end: / |$/,
+                    starts: {
+                        end: '$',
+                        subLanguage: 'python'
+                    }
+                },
+                variants: [
+                    {
+                        begin: /^>>>(?=[ ]|$)/
+                    },
+                    {
+                        begin: /^\.\.\.(?=[ ]|$)/
+                    }
+                ]
+            }
+        ]
+    };
+}

+ 159 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/python.js

@@ -0,0 +1,159 @@
+/*
+Language: Python
+Description: Python is an interpreted, object-oriented, high-level programming language with dynamic semantics.
+Website: https://www.python.org
+Category: common
+*/
+
+export default function (hljs) {
+    var KEYWORDS = {
+        keyword:
+            'and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10',
+        built_in: 'Ellipsis NotImplemented',
+        literal: 'False None True'
+    };
+    var PROMPT = {
+        className: 'meta',
+        begin: /^(>>>|\.\.\.) /
+    };
+    var SUBST = {
+        className: 'subst',
+        begin: /\{/,
+        end: /\}/,
+        keywords: KEYWORDS,
+        illegal: /#/
+    };
+    var LITERAL_BRACKET = {
+        begin: /\{\{/,
+        relevance: 0
+    };
+    var STRING = {
+        className: 'string',
+        contains: [hljs.BACKSLASH_ESCAPE],
+        variants: [
+            {
+                begin: /(u|b)?r?'''/,
+                end: /'''/,
+                contains: [hljs.BACKSLASH_ESCAPE, PROMPT],
+                relevance: 10
+            },
+            {
+                begin: /(u|b)?r?"""/,
+                end: /"""/,
+                contains: [hljs.BACKSLASH_ESCAPE, PROMPT],
+                relevance: 10
+            },
+            {
+                begin: /(fr|rf|f)'''/,
+                end: /'''/,
+                contains: [hljs.BACKSLASH_ESCAPE, PROMPT, LITERAL_BRACKET, SUBST]
+            },
+            {
+                begin: /(fr|rf|f)"""/,
+                end: /"""/,
+                contains: [hljs.BACKSLASH_ESCAPE, PROMPT, LITERAL_BRACKET, SUBST]
+            },
+            {
+                begin: /(u|r|ur)'/,
+                end: /'/,
+                relevance: 10
+            },
+            {
+                begin: /(u|r|ur)"/,
+                end: /"/,
+                relevance: 10
+            },
+            {
+                begin: /(b|br)'/,
+                end: /'/
+            },
+            {
+                begin: /(b|br)"/,
+                end: /"/
+            },
+            {
+                begin: /(fr|rf|f)'/,
+                end: /'/,
+                contains: [hljs.BACKSLASH_ESCAPE, LITERAL_BRACKET, SUBST]
+            },
+            {
+                begin: /(fr|rf|f)"/,
+                end: /"/,
+                contains: [hljs.BACKSLASH_ESCAPE, LITERAL_BRACKET, SUBST]
+            },
+            hljs.APOS_STRING_MODE,
+            hljs.QUOTE_STRING_MODE
+        ]
+    };
+    var NUMBER = {
+        className: 'number',
+        relevance: 0,
+        variants: [
+            {
+                begin: hljs.BINARY_NUMBER_RE + '[lLjJ]?'
+            },
+            {
+                begin: '\\b(0o[0-7]+)[lLjJ]?'
+            },
+            {
+                begin: hljs.C_NUMBER_RE + '[lLjJ]?'
+            }
+        ]
+    };
+    var PARAMS = {
+        className: 'params',
+        begin: /\(/,
+        end: /\)/,
+        contains: ['self', PROMPT, NUMBER, STRING, hljs.HASH_COMMENT_MODE]
+    };
+    SUBST.contains = [STRING, NUMBER, PROMPT];
+    return {
+        name: 'Python',
+        aliases: ['py', 'gyp', 'ipython'],
+        keywords: KEYWORDS,
+        illegal: /(<\/|->|\?)|=>/,
+        contains: [
+            PROMPT,
+            NUMBER,
+            // eat "if" prior to string so that it won't accidentally be
+            // labeled as an f-string as in:
+            {
+                beginKeywords: 'if',
+                relevance: 0
+            },
+            STRING,
+            hljs.HASH_COMMENT_MODE,
+            {
+                variants: [
+                    {
+                        className: 'function',
+                        beginKeywords: 'def'
+                    },
+                    {
+                        className: 'class',
+                        beginKeywords: 'class'
+                    }
+                ],
+                end: /:/,
+                illegal: /[${=;\n,]/,
+                contains: [
+                    hljs.UNDERSCORE_TITLE_MODE,
+                    PARAMS,
+                    {
+                        begin: /->/,
+                        endsWithParent: true,
+                        keywords: 'None'
+                    }
+                ]
+            },
+            {
+                className: 'meta',
+                begin: /^[\t ]*@/,
+                end: /$/
+            },
+            {
+                begin: /\b(print|exec)\(/ // don’t highlight keywords-turned-functions in Python 3
+            }
+        ]
+    };
+}

File diff suppressed because it is too large
+ 112 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/scss.js


+ 23 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/shell.js

@@ -0,0 +1,23 @@
+/*
+Language: Shell Session
+Requires: bash.js
+Author: TSUYUSATO Kitsune <make.just.on@gmail.com>
+Category: common
+*/
+
+export default function (hljs) {
+    return {
+        name: 'Shell Session',
+        aliases: ['console'],
+        contains: [
+            {
+                className: 'meta',
+                begin: '^\\s{0,3}[/\\w\\d\\[\\]()@-]*[>%$#]',
+                starts: {
+                    end: '$',
+                    subLanguage: 'bash'
+                }
+            }
+        ]
+    };
+}

+ 201 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/typescript.js

@@ -0,0 +1,201 @@
+/*
+Language: TypeScript
+Author: Panu Horsmalahti <panu.horsmalahti@iki.fi>
+Contributors: Ike Ku <dempfi@yahoo.com>
+Description: TypeScript is a strict superset of JavaScript
+Website: https://www.typescriptlang.org
+Category: common, scripting
+*/
+
+export default function (hljs) {
+    var JS_IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
+    var KEYWORDS = {
+        keyword:
+            'in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super ' +
+            'static implements enum export import declare type namespace abstract ' +
+            'as from extends async await',
+        literal: 'true false null undefined NaN Infinity',
+        built_in:
+            'eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError ' +
+            'TypeError URIError Number Math Date String RegExp Array Float32Array ' +
+            'Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array ' +
+            'Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require ' +
+            'module console window document any number boolean string void Promise'
+    };
+    var DECORATOR = {
+        className: 'meta',
+        begin: '@' + JS_IDENT_RE
+    };
+    var ARGS = {
+        begin: '\\(',
+        end: /\)/,
+        keywords: KEYWORDS,
+        contains: ['self', hljs.QUOTE_STRING_MODE, hljs.APOS_STRING_MODE, hljs.NUMBER_MODE]
+    };
+    var PARAMS = {
+        className: 'params',
+        begin: /\(/,
+        end: /\)/,
+        excludeBegin: true,
+        excludeEnd: true,
+        keywords: KEYWORDS,
+        contains: [hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE, DECORATOR, ARGS]
+    };
+    var NUMBER = {
+        className: 'number',
+        variants: [
+            {
+                begin: '\\b(0[bB][01]+)n?'
+            },
+            {
+                begin: '\\b(0[oO][0-7]+)n?'
+            },
+            {
+                begin: hljs.C_NUMBER_RE + 'n?'
+            }
+        ],
+        relevance: 0
+    };
+    var SUBST = {
+        className: 'subst',
+        begin: '\\$\\{',
+        end: '\\}',
+        keywords: KEYWORDS,
+        contains: [] // defined later
+    };
+
+    var HTML_TEMPLATE = {
+        begin: 'html`',
+        end: '',
+        starts: {
+            end: '`',
+            returnEnd: false,
+            contains: [hljs.BACKSLASH_ESCAPE, SUBST],
+            subLanguage: 'xml'
+        }
+    };
+    var CSS_TEMPLATE = {
+        begin: 'css`',
+        end: '',
+        starts: {
+            end: '`',
+            returnEnd: false,
+            contains: [hljs.BACKSLASH_ESCAPE, SUBST],
+            subLanguage: 'css'
+        }
+    };
+    var TEMPLATE_STRING = {
+        className: 'string',
+        begin: '`',
+        end: '`',
+        contains: [hljs.BACKSLASH_ESCAPE, SUBST]
+    };
+    SUBST.contains = [hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE, HTML_TEMPLATE, CSS_TEMPLATE, TEMPLATE_STRING, NUMBER, hljs.REGEXP_MODE];
+    return {
+        name: 'TypeScript',
+        aliases: ['ts'],
+        keywords: KEYWORDS,
+        contains: [
+            {
+                className: 'meta',
+                begin: /^\s*['"]use strict['"]/
+            },
+            hljs.APOS_STRING_MODE,
+            hljs.QUOTE_STRING_MODE,
+            HTML_TEMPLATE,
+            CSS_TEMPLATE,
+            TEMPLATE_STRING,
+            hljs.C_LINE_COMMENT_MODE,
+            hljs.C_BLOCK_COMMENT_MODE,
+            NUMBER,
+            {
+                // "value" container
+                begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
+                keywords: 'return throw case',
+                contains: [
+                    hljs.C_LINE_COMMENT_MODE,
+                    hljs.C_BLOCK_COMMENT_MODE,
+                    hljs.REGEXP_MODE,
+                    {
+                        className: 'function',
+                        begin: '(\\(.*?\\)|' + hljs.IDENT_RE + ')\\s*=>',
+                        returnBegin: true,
+                        end: '\\s*=>',
+                        contains: [
+                            {
+                                className: 'params',
+                                variants: [
+                                    {
+                                        begin: hljs.IDENT_RE
+                                    },
+                                    {
+                                        begin: /\(\s*\)/
+                                    },
+                                    {
+                                        begin: /\(/,
+                                        end: /\)/,
+                                        excludeBegin: true,
+                                        excludeEnd: true,
+                                        keywords: KEYWORDS,
+                                        contains: ['self', hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE]
+                                    }
+                                ]
+                            }
+                        ]
+                    }
+                ],
+                relevance: 0
+            },
+            {
+                className: 'function',
+                beginKeywords: 'function',
+                end: /[\{;]/,
+                excludeEnd: true,
+                keywords: KEYWORDS,
+                contains: [
+                    'self',
+                    hljs.inherit(hljs.TITLE_MODE, {
+                        begin: JS_IDENT_RE
+                    }),
+                    PARAMS
+                ],
+                illegal: /%/,
+                relevance: 0 // () => {} is more typical in TypeScript
+            },
+            {
+                beginKeywords: 'constructor',
+                end: /[\{;]/,
+                excludeEnd: true,
+                contains: ['self', PARAMS]
+            },
+            {
+                // prevent references like module.id from being higlighted as module definitions
+                begin: /module\./,
+                keywords: {
+                    built_in: 'module'
+                },
+                relevance: 0
+            },
+            {
+                beginKeywords: 'module',
+                end: /\{/,
+                excludeEnd: true
+            },
+            {
+                beginKeywords: 'interface',
+                end: /\{/,
+                excludeEnd: true,
+                keywords: 'interface extends'
+            },
+            {
+                begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
+            },
+            {
+                begin: '\\.' + hljs.IDENT_RE,
+                relevance: 0 // hack: prevents detection of keywords after dots
+            },
+            DECORATOR,
+            ARGS
+        ]
+    };
+}

+ 164 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/languages/xml.js

@@ -0,0 +1,164 @@
+/*
+Language: HTML, XML
+Website: https://www.w3.org/XML/
+Category: common
+*/
+
+export default function (hljs) {
+    var XML_IDENT_RE = '[A-Za-z0-9\\._:-]+';
+    var XML_ENTITIES = {
+        className: 'symbol',
+        begin: '&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;'
+    };
+    var XML_META_KEYWORDS = {
+        begin: '\\s',
+        contains: [
+            {
+                className: 'meta-keyword',
+                begin: '#?[a-z_][a-z1-9_-]+',
+                illegal: '\\n'
+            }
+        ]
+    };
+    var XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {
+        begin: '\\(',
+        end: '\\)'
+    });
+    var APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, {
+        className: 'meta-string'
+    });
+    var QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, {
+        className: 'meta-string'
+    });
+    var TAG_INTERNALS = {
+        endsWithParent: true,
+        illegal: /</,
+        relevance: 0,
+        contains: [
+            {
+                className: 'attr',
+                begin: XML_IDENT_RE,
+                relevance: 0
+            },
+            {
+                begin: /=\s*/,
+                relevance: 0,
+                contains: [
+                    {
+                        className: 'string',
+                        endsParent: true,
+                        variants: [
+                            {
+                                begin: /"/,
+                                end: /"/,
+                                contains: [XML_ENTITIES]
+                            },
+                            {
+                                begin: /'/,
+                                end: /'/,
+                                contains: [XML_ENTITIES]
+                            },
+                            {
+                                begin: /[^\s"'=<>`]+/
+                            }
+                        ]
+                    }
+                ]
+            }
+        ]
+    };
+    return {
+        name: 'HTML, XML',
+        aliases: ['html', 'xhtml', 'rss', 'atom', 'xjb', 'xsd', 'xsl', 'plist', 'wsf', 'svg'],
+        case_insensitive: true,
+        contains: [
+            {
+                className: 'meta',
+                begin: '<![a-z]',
+                end: '>',
+                relevance: 10,
+                contains: [
+                    XML_META_KEYWORDS,
+                    QUOTE_META_STRING_MODE,
+                    APOS_META_STRING_MODE,
+                    XML_META_PAR_KEYWORDS,
+                    {
+                        begin: '\\[',
+                        end: '\\]',
+                        contains: [
+                            {
+                                className: 'meta',
+                                begin: '<![a-z]',
+                                end: '>',
+                                contains: [XML_META_KEYWORDS, XML_META_PAR_KEYWORDS, QUOTE_META_STRING_MODE, APOS_META_STRING_MODE]
+                            }
+                        ]
+                    }
+                ]
+            },
+            hljs.COMMENT('<!--', '-->', {
+                relevance: 10
+            }),
+            {
+                begin: '<\\!\\[CDATA\\[',
+                end: '\\]\\]>',
+                relevance: 10
+            },
+            XML_ENTITIES,
+            {
+                className: 'meta',
+                begin: /<\?xml/,
+                end: /\?>/,
+                relevance: 10
+            },
+            {
+                className: 'tag',
+                /*
+      The lookahead pattern (?=...) ensures that 'begin' only matches
+      '<style' as a single word, followed by a whitespace or an
+      ending braket. The '$' is needed for the lexeme to be recognized
+      by hljs.subMode() that tests lexemes outside the stream.
+      */
+                begin: '<style(?=\\s|>)',
+                end: '>',
+                keywords: {
+                    name: 'style'
+                },
+                contains: [TAG_INTERNALS],
+                starts: {
+                    end: '</style>',
+                    returnEnd: true,
+                    subLanguage: ['css', 'xml']
+                }
+            },
+            {
+                className: 'tag',
+                // See the comment in the <style tag about the lookahead pattern
+                begin: '<script(?=\\s|>)',
+                end: '>',
+                keywords: {
+                    name: 'script'
+                },
+                contains: [TAG_INTERNALS],
+                starts: {
+                    end: '</script>',
+                    returnEnd: true,
+                    subLanguage: ['javascript', 'handlebars', 'xml']
+                }
+            },
+            {
+                className: 'tag',
+                begin: '</?',
+                end: '/?>',
+                contains: [
+                    {
+                        className: 'name',
+                        begin: /[^\/><\s]+/,
+                        relevance: 0
+                    },
+                    TAG_INTERNALS
+                ]
+            }
+        ]
+    };
+}

+ 99 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/style/github.css

@@ -0,0 +1,99 @@
+/*
+
+github.com style (c) Vasily Polovnyov <vast@whiteants.net>
+
+*/
+
+.h2w-light .hljs {
+    display: block;
+    overflow-x: auto;
+    padding: 0.5em;
+    color: #333;
+    background: #f8f8f8;
+}
+
+.h2w-light .hljs-comment,
+.h2w-light .hljs-quote {
+    color: #998;
+    font-style: italic;
+}
+
+.h2w-light .hljs-keyword,
+.h2w-light .hljs-selector-tag,
+.h2w-light .hljs-subst {
+    color: #333;
+    font-weight: bold;
+}
+
+.h2w-light .hljs-number,
+.h2w-light .hljs-literal,
+.h2w-light .hljs-variable,
+.h2w-light .hljs-template-variable,
+.h2w-light .hljs-tag .hljs-attr {
+    color: #008080;
+}
+
+.h2w-light .hljs-string,
+.h2w-light .hljs-doctag {
+    color: #d14;
+}
+
+.h2w-light .hljs-title,
+.h2w-light .hljs-section,
+.h2w-light .hljs-selector-id {
+    color: #900;
+    font-weight: bold;
+}
+
+.h2w-light .hljs-subst {
+    font-weight: normal;
+}
+
+.h2w-light .hljs-type,
+.h2w-light .hljs-class .hljs-title {
+    color: #458;
+    font-weight: bold;
+}
+
+.h2w-light .hljs-tag,
+.h2w-light .hljs-name,
+.h2w-light .hljs-attribute {
+    color: #000080;
+    font-weight: normal;
+}
+
+.h2w-light .hljs-regexp,
+.h2w-light .hljs-link {
+    color: #009926;
+}
+
+.h2w-light .hljs-symbol,
+.h2w-light .hljs-bullet {
+    color: #990073;
+}
+
+.h2w-light .hljs-built_in,
+.h2w-light .hljs-builtin-name {
+    color: #0086b3;
+}
+
+.h2w-light .hljs-meta {
+    color: #999;
+    font-weight: bold;
+}
+
+.h2w-light .hljs-deletion {
+    background: #fdd;
+}
+
+.h2w-light .hljs-addition {
+    background: #dfd;
+}
+
+.h2w-light .hljs-emphasis {
+    font-style: italic;
+}
+
+.h2w-light .hljs-strong {
+    font-weight: bold;
+}

+ 71 - 0
components/agent-ui/markdownPreview/towxml/parse/highlight/style/monokai.css

@@ -0,0 +1,71 @@
+/*
+Monokai style - ported by Luigi Maselli - http://grigio.org
+*/
+
+.h2w-dark .hljs {
+    display: block;
+    overflow-x: auto;
+    padding: 0.5em;
+    background: #272822;
+    color: #ddd;
+}
+
+.h2w-dark .hljs-tag,
+.h2w-dark .hljs-keyword,
+.h2w-dark .hljs-selector-tag,
+.h2w-dark .hljs-literal,
+.h2w-dark .hljs-strong,
+.h2w-dark .hljs-name {
+    color: #f92672;
+}
+
+.h2w-dark .hljs-code {
+    color: #66d9ef;
+}
+
+.h2w-dark .hljs-class .hljs-title {
+    color: white;
+}
+
+.h2w-dark .hljs-attribute,
+.h2w-dark .hljs-symbol,
+.h2w-dark .hljs-regexp,
+.h2w-dark .hljs-link {
+    color: #bf79db;
+}
+
+.h2w-dark .hljs-string,
+.h2w-dark .hljs-bullet,
+.h2w-dark .hljs-subst,
+.h2w-dark .hljs-title,
+.h2w-dark .hljs-section,
+.h2w-dark .hljs-emphasis,
+.h2w-dark .hljs-type,
+.h2w-dark .hljs-built_in,
+.h2w-dark .hljs-builtin-name,
+.h2w-dark .hljs-selector-attr,
+.h2w-dark .hljs-selector-pseudo,
+.h2w-dark .hljs-addition,
+.h2w-dark .hljs-variable,
+.h2w-dark .hljs-template-tag,
+.h2w-dark .hljs-template-variable {
+    color: #a6e22e;
+}
+
+.h2w-dark .hljs-comment,
+.h2w-dark .hljs-quote,
+.h2w-dark .hljs-deletion,
+.h2w-dark .hljs-meta {
+    color: #75715e;
+}
+
+.h2w-dark .hljs-keyword,
+.h2w-dark .hljs-selector-tag,
+.h2w-dark .hljs-literal,
+.h2w-dark .hljs-doctag,
+.h2w-dark .hljs-title,
+.h2w-dark .hljs-section,
+.h2w-dark .hljs-type,
+.h2w-dark .hljs-selector-id {
+    font-weight: bold;
+}

+ 113 - 0
components/agent-ui/markdownPreview/towxml/parse/index.js

@@ -0,0 +1,113 @@
+const parse2 = require('./parse2/index');
+const // parse5 = require('./parse5/index').parse,
+    config = require('../config');
+const // html与wxml转换关系
+    correspondTag = (() => {
+        let result = {
+            a: 'navigator',
+            todogroup: 'checkbox-group',
+            audio: 'audio-player'
+        };
+
+        // 该系列的标签都转换为text
+        // ['span','b','strong','i','em','code','sub','sup','g-emoji','mark','ins','u'].forEach(item => {
+        //     result[item] = 'text';
+        // });
+
+        // 该系列小程序原生tag,不需转换
+        [...config.wxml, ...config.components].forEach((item) => {
+            result[item] = item;
+        });
+        return result;
+    })();
+const // 元素与html对应的wxml标签名
+    getWxmlTag = (tagStr) => (!tagStr ? undefined : correspondTag[tagStr] || 'view');
+const // 依赖父级的元素
+    relyList = ['li'];
+const // 精简数据,并初始化相关事件等
+    initObj = (obj, option) => {
+        const result = {
+            theme: option.theme || 'light',
+            _e: {}
+        };
+        const events = (global._events = {});
+        const base = option.base; // 主题保存到全局
+        global._theme = result.theme;
+
+        // 事件添加到全局中,各个组件在触发事件时会从全局调用
+        if (option.events) {
+            for (let key in option.events) {
+                events[key] = option.events[key];
+            }
+        }
+        // 遍历原始数据,处理成能解析的数据
+        let eachFn;
+        (eachFn = (arr, obj, _e, isRichTextContent) => {
+            obj.children = obj.children || [];
+            _e.child = _e.child || [];
+            let child = obj.children;
+            let child_e = _e.child;
+            arr.forEach((item) => {
+                if (item.type === 'comment') {
+                    return;
+                }
+                let o = {
+                    type: item.type === 'text' ? 'text' : isRichTextContent ? 'node' : item.type
+                };
+                let e = {};
+                let attrs = (o.attrs = item.attribs || {});
+                if (item.type === 'text') {
+                    o.text = e.text = item.data;
+                } else {
+                    if (isRichTextContent) {
+                        o.name = item.name;
+                    } else {
+                        o.tag = getWxmlTag(item.name); // 转换之后的标签
+                        // o.tag = o.tag === 'text' ? 'view' : o.tag;
+                        e.tag = item.name; // 原始
+                        o.attrs = item.attribs;
+                        e.attrs = JSON.parse(JSON.stringify(attrs));
+                    }
+                    attrs.class = attrs.class ? `h2w__${item.name} ${attrs.class}` : `h2w__${item.name}`;
+
+                    // 处理资源相对路径
+                    if (base && attrs.src) {
+                        let src = attrs.src;
+                        switch (src.indexOf('//')) {
+                            case 0:
+                                attrs.src = `https:${src}`;
+                                break;
+                            case -1:
+                                attrs.src = `${base}${src}`;
+                                break;
+                        }
+                    }
+                }
+                o.rely = relyList.indexOf(e.tag) > -1; // 判断是否不能嵌套其它标签
+
+                if (item.children) {
+                    eachFn(item.children, o, e, isRichTextContent || item.name === 'rich-text');
+                }
+                child.push(o);
+                child_e.push(e);
+            });
+        })(obj, result, result._e, false);
+        return result;
+    };
+module.exports = (str, option) => {
+    str = (() => {
+        let re = /<body[^>]*>([\s\S]*)<\/body>/i;
+        if (re.test(str)) {
+            let result = re.exec(str);
+            return result[1] || str;
+        } else {
+            return str;
+        }
+    })();
+    return initObj(
+        parse2(str, {
+            decodeEntities: true
+        }),
+        option
+    );
+};

+ 64 - 0
components/agent-ui/markdownPreview/towxml/parse/markdown/index.js

@@ -0,0 +1,64 @@
+let hljs;
+hljs = require('../highlight/index');
+const config = require('../../config');
+const mdOption = (() => {
+    let result = {
+        html: true,
+        xhtmlOut: true,
+        typographer: true,
+        breaks: true
+    };
+    if (config.highlight.length && hljs) {
+        result.highlight = (code, lang, callback) => {
+            let lineLen = code.split(/\r|\n/gi).length;
+            let result = hljs.highlightAuto(code).value; // 代码块多换行的问题
+            result = result.replace(/(\r|\n){2,}/g, (str) => {
+                return new Array(str.length).join('<p>&nbsp;</p>');
+            });
+            result = result.replace(/\r|\n/g, (str) => {
+                return '<br/>';
+            });
+
+            // 代码空格处理
+            result = result
+                .replace(/>[^<]+</g, (str) => {
+                    return str.replace(/\s/g, '&nbsp;');
+                })
+                .replace(/\t/g, new Array(4).join('&nbsp;'));
+            if (config.showLineNumber) {
+                let lineStr = (() => {
+                    let str = `<ul class="h2w__lineNum">`;
+                    for (let i = 0; i < lineLen - 1; i++) {
+                        str += `<li class="h2w__lineNumLine">${i + 1}</li>`;
+                    }
+                    str += `</ul>`;
+                    return str;
+                })();
+                return lineStr + result;
+            }
+            return result;
+        };
+    }
+    return result;
+})();
+const md = require('./markdown')(mdOption); // 应用Markdown解析扩展,包括自定义组件(['sub','sup','ins','mark','emoji','todo','latex','yuml','echarts'])
+// [...config.markdown,...config.components].forEach(item => {
+//     if(!/^audio-player|table|todogroup|img$/.test(item)){
+//         md.use(require(`./plugins/${item}`));
+//     };
+// });
+md.use(require('./plugins/sub'));
+md.use(require('./plugins/sup'));
+md.use(require('./plugins/ins'));
+md.use(require('./plugins/mark'));
+
+// 定义emoji渲染规则
+md.renderer.rules.emoji = (token, index) => {
+    let item = token[index];
+    return `<g-emoji class="h2w__emoji h2w__emoji--${item.markup}">${item.content}</g-emoji>`;
+};
+
+// 导出模块
+module.exports = (str) => {
+    return md.render(str);
+};

File diff suppressed because it is too large
+ 6632 - 0
components/agent-ui/markdownPreview/towxml/parse/markdown/markdown.js


+ 143 - 0
components/agent-ui/markdownPreview/towxml/parse/markdown/plugins/ins.js

@@ -0,0 +1,143 @@
+!(function (e) {
+    if ('object' == typeof exports && 'undefined' != typeof module) module.exports = e();
+    else if ('function' == typeof define && define.amd) {
+        define([], e);
+    } else {
+        var n;
+        n = 'undefined' != typeof window ? window : 'undefined' != typeof global ? global : 'undefined' != typeof self ? self : this;
+        n.markdownitIns = e();
+    }
+})(function () {
+    return (function e(n, t, o) {
+        function r(s, f) {
+            if (!t[s]) {
+                if (!n[s]) {
+                    var u = 'function' == typeof require && require;
+                    if (!f && u) {
+                        return u(s, true);
+                    }
+                    if (i) {
+                        return i(s, true);
+                    }
+                    var l = new Error("Cannot find module '" + s + "'");
+                    throw ((l.code = 'MODULE_NOT_FOUND'), l);
+                }
+                var p = (t[s] = {
+                    exports: {}
+                });
+                n[s][0].call(
+                    p.exports,
+                    function (e) {
+                        var t = n[s][1][e];
+                        return r(t ? t : e);
+                    },
+                    p,
+                    p.exports,
+                    e,
+                    n,
+                    t,
+                    o
+                );
+            }
+            return t[s].exports;
+        }
+        for (var i = 'function' == typeof require && require, s = 0; s < o.length; s++) {
+            r(o[s]);
+        }
+        return r;
+    })(
+        {
+            1: [
+                function (e, n, t) {
+                    'use strict';
+
+                    n.exports = function (e) {
+                        function n(e, n) {
+                            var t;
+                            var o;
+                            var r;
+                            var i;
+                            var s;
+                            var f = e.pos;
+                            var u = e.src.charCodeAt(f);
+                            if (n) {
+                                return false;
+                            }
+                            if (43 !== u) {
+                                return false;
+                            }
+                            o = e.scanDelims(e.pos, true);
+                            i = o.length;
+                            s = String.fromCharCode(u);
+                            if (2 > i) {
+                                return false;
+                            }
+                            for (i % 2 && ((r = e.push('text', '', 0)), (r.content = s), i--), t = 0; i > t; t += 2) {
+                                r = e.push('text', '', 0);
+                                r.content = s + s;
+                                e.delimiters.push({
+                                    marker: u,
+                                    jump: t,
+                                    token: e.tokens.length - 1,
+                                    level: e.level,
+                                    end: -1,
+                                    open: o.can_open,
+                                    close: o.can_close
+                                });
+                            }
+                            e.pos += o.length;
+                            return true;
+                        }
+                        function t(e) {
+                            var n;
+                            var t;
+                            var o;
+                            var r;
+                            var i;
+                            var s = [];
+                            var f = e.delimiters;
+                            var u = e.delimiters.length;
+                            for (n = 0; u > n; n++) {
+                                o = f[n];
+                                if (43 === o.marker && -1 !== o.end) {
+                                    r = f[o.end];
+                                    i = e.tokens[o.token];
+                                    i.type = 'ins_open';
+                                    i.tag = 'ins';
+                                    i.nesting = 1;
+                                    i.markup = '++';
+                                    i.content = '';
+                                    i = e.tokens[r.token];
+                                    i.type = 'ins_close';
+                                    i.tag = 'ins';
+                                    i.nesting = -1;
+                                    i.markup = '++';
+                                    i.content = '';
+                                    if ('text' === e.tokens[r.token - 1].type && '+' === e.tokens[r.token - 1].content) {
+                                        s.push(r.token - 1);
+                                    }
+                                }
+                            }
+                            for (; s.length; ) {
+                                for (n = s.pop(), t = n + 1; t < e.tokens.length && 'ins_close' === e.tokens[t].type; ) {
+                                    t++;
+                                }
+                                t--;
+                                if (n !== t) {
+                                    i = e.tokens[t];
+                                    e.tokens[t] = e.tokens[n];
+                                    e.tokens[n] = i;
+                                }
+                            }
+                        }
+                        e.inline.ruler.before('emphasis', 'ins', n);
+                        e.inline.ruler2.before('emphasis', 'ins', t);
+                    };
+                },
+                {}
+            ]
+        },
+        {},
+        [1]
+    )(1);
+});

+ 143 - 0
components/agent-ui/markdownPreview/towxml/parse/markdown/plugins/mark.js

@@ -0,0 +1,143 @@
+!(function (e) {
+    if ('object' == typeof exports && 'undefined' != typeof module) module.exports = e();
+    else if ('function' == typeof define && define.amd) {
+        define([], e);
+    } else {
+        var n;
+        n = 'undefined' != typeof window ? window : 'undefined' != typeof global ? global : 'undefined' != typeof self ? self : this;
+        n.markdownitMark = e();
+    }
+})(function () {
+    return (function e(n, t, o) {
+        function r(s, f) {
+            if (!t[s]) {
+                if (!n[s]) {
+                    var u = 'function' == typeof require && require;
+                    if (!f && u) {
+                        return u(s, true);
+                    }
+                    if (i) {
+                        return i(s, true);
+                    }
+                    var l = new Error("Cannot find module '" + s + "'");
+                    throw ((l.code = 'MODULE_NOT_FOUND'), l);
+                }
+                var p = (t[s] = {
+                    exports: {}
+                });
+                n[s][0].call(
+                    p.exports,
+                    function (e) {
+                        var t = n[s][1][e];
+                        return r(t ? t : e);
+                    },
+                    p,
+                    p.exports,
+                    e,
+                    n,
+                    t,
+                    o
+                );
+            }
+            return t[s].exports;
+        }
+        for (var i = 'function' == typeof require && require, s = 0; s < o.length; s++) {
+            r(o[s]);
+        }
+        return r;
+    })(
+        {
+            1: [
+                function (e, n, t) {
+                    'use strict';
+
+                    n.exports = function (e) {
+                        function n(e, n) {
+                            var t;
+                            var o;
+                            var r;
+                            var i;
+                            var s;
+                            var f = e.pos;
+                            var u = e.src.charCodeAt(f);
+                            if (n) {
+                                return false;
+                            }
+                            if (61 !== u) {
+                                return false;
+                            }
+                            o = e.scanDelims(e.pos, true);
+                            i = o.length;
+                            s = String.fromCharCode(u);
+                            if (2 > i) {
+                                return false;
+                            }
+                            for (i % 2 && ((r = e.push('text', '', 0)), (r.content = s), i--), t = 0; i > t; t += 2) {
+                                r = e.push('text', '', 0);
+                                r.content = s + s;
+                                e.delimiters.push({
+                                    marker: u,
+                                    jump: t,
+                                    token: e.tokens.length - 1,
+                                    level: e.level,
+                                    end: -1,
+                                    open: o.can_open,
+                                    close: o.can_close
+                                });
+                            }
+                            e.pos += o.length;
+                            return true;
+                        }
+                        function t(e) {
+                            var n;
+                            var t;
+                            var o;
+                            var r;
+                            var i;
+                            var s = [];
+                            var f = e.delimiters;
+                            var u = e.delimiters.length;
+                            for (n = 0; u > n; n++) {
+                                o = f[n];
+                                if (61 === o.marker && -1 !== o.end) {
+                                    r = f[o.end];
+                                    i = e.tokens[o.token];
+                                    i.type = 'mark_open';
+                                    i.tag = 'mark';
+                                    i.nesting = 1;
+                                    i.markup = '==';
+                                    i.content = '';
+                                    i = e.tokens[r.token];
+                                    i.type = 'mark_close';
+                                    i.tag = 'mark';
+                                    i.nesting = -1;
+                                    i.markup = '==';
+                                    i.content = '';
+                                    if ('text' === e.tokens[r.token - 1].type && '=' === e.tokens[r.token - 1].content) {
+                                        s.push(r.token - 1);
+                                    }
+                                }
+                            }
+                            for (; s.length; ) {
+                                for (n = s.pop(), t = n + 1; t < e.tokens.length && 'mark_close' === e.tokens[t].type; ) {
+                                    t++;
+                                }
+                                t--;
+                                if (n !== t) {
+                                    i = e.tokens[t];
+                                    e.tokens[t] = e.tokens[n];
+                                    e.tokens[n] = i;
+                                }
+                            }
+                        }
+                        e.inline.ruler.before('emphasis', 'mark', n);
+                        e.inline.ruler2.before('emphasis', 'mark', t);
+                    };
+                },
+                {}
+            ]
+        },
+        {},
+        [1]
+    )(1);
+});

+ 104 - 0
components/agent-ui/markdownPreview/towxml/parse/markdown/plugins/sub.js

@@ -0,0 +1,104 @@
+!(function (e) {
+    if ('object' == typeof exports && 'undefined' != typeof module) module.exports = e();
+    else if ('function' == typeof define && define.amd) {
+        define([], e);
+    } else {
+        var r;
+        r = 'undefined' != typeof window ? window : 'undefined' != typeof global ? global : 'undefined' != typeof self ? self : this;
+        r.markdownitSub = e();
+    }
+})(function () {
+    return (function e(r, o, n) {
+        function t(i, u) {
+            if (!o[i]) {
+                if (!r[i]) {
+                    var f = 'function' == typeof require && require;
+                    if (!u && f) {
+                        return f(i, true);
+                    }
+                    if (s) {
+                        return s(i, true);
+                    }
+                    var p = new Error("Cannot find module '" + i + "'");
+                    throw ((p.code = 'MODULE_NOT_FOUND'), p);
+                }
+                var a = (o[i] = {
+                    exports: {}
+                });
+                r[i][0].call(
+                    a.exports,
+                    function (e) {
+                        var o = r[i][1][e];
+                        return t(o ? o : e);
+                    },
+                    a,
+                    a.exports,
+                    e,
+                    r,
+                    o,
+                    n
+                );
+            }
+            return o[i].exports;
+        }
+        for (var s = 'function' == typeof require && require, i = 0; i < n.length; i++) {
+            t(n[i]);
+        }
+        return t;
+    })(
+        {
+            1: [
+                function (e, r) {
+                    'use strict';
+
+                    function o(e, r) {
+                        var o;
+                        var t;
+                        var s;
+                        var i = e.posMax;
+                        var u = e.pos;
+                        if (126 !== e.src.charCodeAt(u)) {
+                            return false;
+                        }
+                        if (r) {
+                            return false;
+                        }
+                        if (u + 2 >= i) {
+                            return false;
+                        }
+                        for (e.pos = u + 1; e.pos < i; ) {
+                            if (126 === e.src.charCodeAt(e.pos)) {
+                                o = true;
+                                break;
+                            }
+                            e.md.inline.skipToken(e);
+                        }
+                        return o && u + 1 !== e.pos
+                            ? ((t = e.src.slice(u + 1, e.pos)),
+                              t.match(/(^|[^\\])(\\\\)*\s/)
+                                  ? ((e.pos = u), false)
+                                  : ((e.posMax = e.pos),
+                                    (e.pos = u + 1),
+                                    (s = e.push('sub_open', 'sub', 1)),
+                                    (s.markup = '~'),
+                                    (s = e.push('text', '', 0)),
+                                    (s.content = t.replace(n, '$1')),
+                                    (s = e.push('sub_close', 'sub', -1)),
+                                    (s.markup = '~'),
+                                    (e.pos = e.posMax + 1),
+                                    (e.posMax = i),
+                                    true))
+                            : ((e.pos = u), false);
+                    }
+                    var n = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;
+                    r.exports = function (e) {
+                        e.inline.ruler.after('emphasis', 'sub', o);
+                    };
+                },
+                {}
+            ]
+        },
+        {},
+        [1]
+    )(1);
+});

+ 104 - 0
components/agent-ui/markdownPreview/towxml/parse/markdown/plugins/sup.js

@@ -0,0 +1,104 @@
+!(function (e) {
+    if ('object' == typeof exports && 'undefined' != typeof module) module.exports = e();
+    else if ('function' == typeof define && define.amd) {
+        define([], e);
+    } else {
+        var r;
+        r = 'undefined' != typeof window ? window : 'undefined' != typeof global ? global : 'undefined' != typeof self ? self : this;
+        r.markdownitSup = e();
+    }
+})(function () {
+    return (function e(r, o, n) {
+        function t(i, p) {
+            if (!o[i]) {
+                if (!r[i]) {
+                    var u = 'function' == typeof require && require;
+                    if (!p && u) {
+                        return u(i, true);
+                    }
+                    if (s) {
+                        return s(i, true);
+                    }
+                    var f = new Error("Cannot find module '" + i + "'");
+                    throw ((f.code = 'MODULE_NOT_FOUND'), f);
+                }
+                var a = (o[i] = {
+                    exports: {}
+                });
+                r[i][0].call(
+                    a.exports,
+                    function (e) {
+                        var o = r[i][1][e];
+                        return t(o ? o : e);
+                    },
+                    a,
+                    a.exports,
+                    e,
+                    r,
+                    o,
+                    n
+                );
+            }
+            return o[i].exports;
+        }
+        for (var s = 'function' == typeof require && require, i = 0; i < n.length; i++) {
+            t(n[i]);
+        }
+        return t;
+    })(
+        {
+            1: [
+                function (e, r) {
+                    'use strict';
+
+                    function o(e, r) {
+                        var o;
+                        var t;
+                        var s;
+                        var i = e.posMax;
+                        var p = e.pos;
+                        if (94 !== e.src.charCodeAt(p)) {
+                            return false;
+                        }
+                        if (r) {
+                            return false;
+                        }
+                        if (p + 2 >= i) {
+                            return false;
+                        }
+                        for (e.pos = p + 1; e.pos < i; ) {
+                            if (94 === e.src.charCodeAt(e.pos)) {
+                                o = true;
+                                break;
+                            }
+                            e.md.inline.skipToken(e);
+                        }
+                        return o && p + 1 !== e.pos
+                            ? ((t = e.src.slice(p + 1, e.pos)),
+                              t.match(/(^|[^\\])(\\\\)*\s/)
+                                  ? ((e.pos = p), false)
+                                  : ((e.posMax = e.pos),
+                                    (e.pos = p + 1),
+                                    (s = e.push('sup_open', 'sup', 1)),
+                                    (s.markup = '^'),
+                                    (s = e.push('text', '', 0)),
+                                    (s.content = t.replace(n, '$1')),
+                                    (s = e.push('sup_close', 'sup', -1)),
+                                    (s.markup = '^'),
+                                    (e.pos = e.posMax + 1),
+                                    (e.posMax = i),
+                                    true))
+                            : ((e.pos = p), false);
+                    }
+                    var n = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;
+                    r.exports = function (e) {
+                        e.inline.ruler.after('emphasis', 'sup', o);
+                    };
+                },
+                {}
+            ]
+        },
+        {},
+        [1]
+    )(1);
+});

+ 499 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/Parser.js

@@ -0,0 +1,499 @@
+var Tokenizer_js_1 = require('./Tokenizer.js');
+var decode_js_1 = require('./entities/decode.js');
+var formTags = new Set(['input', 'option', 'optgroup', 'select', 'button', 'datalist', 'textarea']);
+var pTag = new Set(['p']);
+var tableSectionTags = new Set(['thead', 'tbody']);
+var ddtTags = new Set(['dd', 'dt']);
+var rtpTags = new Set(['rt', 'rp']);
+var openImpliesClose = new Map([
+    ['tr', new Set(['tr', 'th', 'td'])],
+    ['th', new Set(['th'])],
+    ['td', new Set(['thead', 'th', 'td'])],
+    ['body', new Set(['head', 'link', 'script'])],
+    ['li', new Set(['li'])],
+    ['p', pTag],
+    ['h1', pTag],
+    ['h2', pTag],
+    ['h3', pTag],
+    ['h4', pTag],
+    ['h5', pTag],
+    ['h6', pTag],
+    ['select', formTags],
+    ['input', formTags],
+    ['output', formTags],
+    ['button', formTags],
+    ['datalist', formTags],
+    ['textarea', formTags],
+    ['option', new Set(['option'])],
+    ['optgroup', new Set(['optgroup', 'option'])],
+    ['dd', ddtTags],
+    ['dt', ddtTags],
+    ['address', pTag],
+    ['article', pTag],
+    ['aside', pTag],
+    ['blockquote', pTag],
+    ['details', pTag],
+    ['div', pTag],
+    ['dl', pTag],
+    ['fieldset', pTag],
+    ['figcaption', pTag],
+    ['figure', pTag],
+    ['footer', pTag],
+    ['form', pTag],
+    ['header', pTag],
+    ['hr', pTag],
+    ['main', pTag],
+    ['nav', pTag],
+    ['ol', pTag],
+    ['pre', pTag],
+    ['section', pTag],
+    ['table', pTag],
+    ['ul', pTag],
+    ['rt', rtpTags],
+    ['rp', rtpTags],
+    ['tbody', tableSectionTags],
+    ['tfoot', tableSectionTags]
+]);
+var voidElements = new Set([
+    'area',
+    'base',
+    'basefont',
+    'br',
+    'col',
+    'command',
+    'embed',
+    'frame',
+    'hr',
+    'img',
+    'input',
+    'isindex',
+    'keygen',
+    'link',
+    'meta',
+    'param',
+    'source',
+    'track',
+    'wbr'
+]);
+var foreignContextElements = new Set(['math', 'svg']);
+var htmlIntegrationElements = new Set(['mi', 'mo', 'mn', 'ms', 'mtext', 'annotation-xml', 'foreignobject', 'desc', 'title']);
+var reNameEnd = /\s|\//;
+var Parser = /** @class */ (function () {
+    function Parser(cbs, options) {
+        if (options === void 0) {
+            options = {};
+        }
+        var _a;
+        var _b;
+        var _c;
+        var _d;
+        var _e;
+        this.options = options;
+        /** The start index of the last event. */
+        this.startIndex = 0;
+        /** The end index of the last event. */
+        this.endIndex = 0;
+        /**
+         * Store the start index of the current open tag,
+         * so we can update the start index for attributes.
+         */
+        this.openTagStart = 0;
+        this.tagname = '';
+        this.attribname = '';
+        this.attribvalue = '';
+        this.attribs = null;
+        this.stack = [];
+        this.foreignContext = [];
+        this.buffers = [];
+        this.bufferOffset = 0;
+        /** The index of the last written buffer. Used when resuming after a `pause()`. */
+        this.writeIndex = 0;
+        /** Indicates whether the parser has finished running / `.end` has been called. */
+        this.ended = false;
+        this.cbs = cbs !== null && cbs !== void 0 ? cbs : {};
+        this.lowerCaseTagNames = (_a = options.lowerCaseTags) !== null && _a !== void 0 ? _a : !options.xmlMode;
+        this.lowerCaseAttributeNames = (_b = options.lowerCaseAttributeNames) !== null && _b !== void 0 ? _b : !options.xmlMode;
+        this.tokenizer = new ((_c = options.Tokenizer) !== null && _c !== void 0 ? _c : Tokenizer_js_1.default)(this.options, this);
+        (_e = (_d = this.cbs).onparserinit) === null || _e === void 0 ? void 0 : _e.call(_d, this);
+    }
+    // Tokenizer event handlers
+    /** @internal */
+    Parser.prototype.ontext = function (start, endIndex) {
+        var _a;
+        var _b;
+        var data = this.getSlice(start, endIndex);
+        this.endIndex = endIndex - 1;
+        (_b = (_a = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a, data);
+        this.startIndex = endIndex;
+    };
+    /** @internal */
+    Parser.prototype.ontextentity = function (cp) {
+        var _a;
+        var _b;
+        /*
+         * Entities can be emitted on the character, or directly after.
+         * We use the section start here to get accurate indices.
+         */
+        var idx = this.tokenizer.getSectionStart();
+        this.endIndex = idx - 1;
+        (_b = (_a = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a, (0, decode_js_1.fromCodePoint)(cp));
+        this.startIndex = idx;
+    };
+    Parser.prototype.isVoidElement = function (name) {
+        return !this.options.xmlMode && voidElements.has(name);
+    };
+    /** @internal */
+    Parser.prototype.onopentagname = function (start, endIndex) {
+        this.endIndex = endIndex;
+        var name = this.getSlice(start, endIndex);
+        if (this.lowerCaseTagNames) {
+            name = name.toLowerCase();
+        }
+        this.emitOpenTag(name);
+    };
+    Parser.prototype.emitOpenTag = function (name) {
+        var _a;
+        var _b;
+        var _c;
+        var _d;
+        this.openTagStart = this.startIndex;
+        this.tagname = name;
+        var impliesClose = !this.options.xmlMode && openImpliesClose.get(name);
+        if (impliesClose) {
+            while (this.stack.length > 0 && impliesClose.has(this.stack[this.stack.length - 1])) {
+                var el = this.stack.pop();
+                (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, el, true);
+            }
+        }
+        if (!this.isVoidElement(name)) {
+            this.stack.push(name);
+            if (foreignContextElements.has(name)) {
+                this.foreignContext.push(true);
+            } else if (htmlIntegrationElements.has(name)) {
+                this.foreignContext.push(false);
+            }
+        }
+        (_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, name);
+        if (this.cbs.onopentag) {
+            this.attribs = {};
+        }
+    };
+    Parser.prototype.endOpenTag = function (isImplied) {
+        var _a;
+        var _b;
+        this.startIndex = this.openTagStart;
+        if (this.attribs) {
+            (_b = (_a = this.cbs).onopentag) === null || _b === void 0 ? void 0 : _b.call(_a, this.tagname, this.attribs, isImplied);
+            this.attribs = null;
+        }
+        if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) {
+            this.cbs.onclosetag(this.tagname, true);
+        }
+        this.tagname = '';
+    };
+    /** @internal */
+    Parser.prototype.onopentagend = function (endIndex) {
+        this.endIndex = endIndex;
+        this.endOpenTag(false);
+        // Set `startIndex` for next node
+        this.startIndex = endIndex + 1;
+    };
+    /** @internal */
+    Parser.prototype.onclosetag = function (start, endIndex) {
+        var _a;
+        var _b;
+        var _c;
+        var _d;
+        var _e;
+        var _f;
+        this.endIndex = endIndex;
+        var name = this.getSlice(start, endIndex);
+        if (this.lowerCaseTagNames) {
+            name = name.toLowerCase();
+        }
+        if (foreignContextElements.has(name) || htmlIntegrationElements.has(name)) {
+            this.foreignContext.pop();
+        }
+        if (!this.isVoidElement(name)) {
+            var pos = this.stack.lastIndexOf(name);
+            if (pos !== -1) {
+                if (this.cbs.onclosetag) {
+                    var count = this.stack.length - pos;
+                    while (count--) {
+                        // We know the stack has sufficient elements.
+                        this.cbs.onclosetag(this.stack.pop(), count !== 0);
+                    }
+                } else {
+                    this.stack.length = pos;
+                }
+            } else if (!this.options.xmlMode && name === 'p') {
+                // Implicit open before close
+                this.emitOpenTag('p');
+                this.closeCurrentTag(true);
+            }
+        } else if (!this.options.xmlMode && name === 'br') {
+            // We can't use `emitOpenTag` for implicit open, as `br` would be implicitly closed.
+            (_b = (_a = this.cbs).onopentagname) === null || _b === void 0 ? void 0 : _b.call(_a, 'br');
+            (_d = (_c = this.cbs).onopentag) === null || _d === void 0 ? void 0 : _d.call(_c, 'br', {}, true);
+            (_f = (_e = this.cbs).onclosetag) === null || _f === void 0 ? void 0 : _f.call(_e, 'br', false);
+        }
+        // Set `startIndex` for next node
+        this.startIndex = endIndex + 1;
+    };
+    /** @internal */
+    Parser.prototype.onselfclosingtag = function (endIndex) {
+        this.endIndex = endIndex;
+        if (this.options.xmlMode || this.options.recognizeSelfClosing || this.foreignContext[this.foreignContext.length - 1]) {
+            this.closeCurrentTag(false);
+            // Set `startIndex` for next node
+            this.startIndex = endIndex + 1;
+        } else {
+            // Ignore the fact that the tag is self-closing.
+            this.onopentagend(endIndex);
+        }
+    };
+    Parser.prototype.closeCurrentTag = function (isOpenImplied) {
+        var _a;
+        var _b;
+        var name = this.tagname;
+        this.endOpenTag(isOpenImplied);
+        // Self-closing tags will be on the top of the stack
+        if (this.stack[this.stack.length - 1] === name) {
+            // If the opening tag isn't implied, the closing tag has to be implied.
+            (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, name, !isOpenImplied);
+            this.stack.pop();
+        }
+    };
+    /** @internal */
+    Parser.prototype.onattribname = function (start, endIndex) {
+        this.startIndex = start;
+        var name = this.getSlice(start, endIndex);
+        this.attribname = this.lowerCaseAttributeNames ? name.toLowerCase() : name;
+    };
+    /** @internal */
+    Parser.prototype.onattribdata = function (start, endIndex) {
+        this.attribvalue += this.getSlice(start, endIndex);
+    };
+    /** @internal */
+    Parser.prototype.onattribentity = function (cp) {
+        this.attribvalue += (0, decode_js_1.fromCodePoint)(cp);
+    };
+    /** @internal */
+    Parser.prototype.onattribend = function (quote, endIndex) {
+        var _a;
+        var _b;
+        this.endIndex = endIndex;
+        (_b = (_a = this.cbs).onattribute) === null || _b === void 0
+            ? void 0
+            : _b.call(
+                  _a,
+                  this.attribname,
+                  this.attribvalue,
+                  quote === Tokenizer_js_1.QuoteType.Double ? '"' : quote === Tokenizer_js_1.QuoteType.Single ? "'" : quote === Tokenizer_js_1.QuoteType.NoValue ? undefined : null
+              );
+        if (this.attribs && !Object.prototype.hasOwnProperty.call(this.attribs, this.attribname)) {
+            this.attribs[this.attribname] = this.attribvalue;
+        }
+        this.attribvalue = '';
+    };
+    Parser.prototype.getInstructionName = function (value) {
+        var idx = value.search(reNameEnd);
+        var name = idx < 0 ? value : value.substr(0, idx);
+        if (this.lowerCaseTagNames) {
+            name = name.toLowerCase();
+        }
+        return name;
+    };
+    /** @internal */
+    Parser.prototype.ondeclaration = function (start, endIndex) {
+        this.endIndex = endIndex;
+        var value = this.getSlice(start, endIndex);
+        if (this.cbs.onprocessinginstruction) {
+            var name = this.getInstructionName(value);
+            this.cbs.onprocessinginstruction('!'.concat(name), '!'.concat(value));
+        }
+        // Set `startIndex` for next node
+        this.startIndex = endIndex + 1;
+    };
+    /** @internal */
+    Parser.prototype.onprocessinginstruction = function (start, endIndex) {
+        this.endIndex = endIndex;
+        var value = this.getSlice(start, endIndex);
+        if (this.cbs.onprocessinginstruction) {
+            var name = this.getInstructionName(value);
+            this.cbs.onprocessinginstruction('?'.concat(name), '?'.concat(value));
+        }
+        // Set `startIndex` for next node
+        this.startIndex = endIndex + 1;
+    };
+    /** @internal */
+    Parser.prototype.oncomment = function (start, endIndex, offset) {
+        var _a;
+        var _b;
+        var _c;
+        var _d;
+        this.endIndex = endIndex;
+        (_b = (_a = this.cbs).oncomment) === null || _b === void 0 ? void 0 : _b.call(_a, this.getSlice(start, endIndex - offset));
+        (_d = (_c = this.cbs).oncommentend) === null || _d === void 0 ? void 0 : _d.call(_c);
+        // Set `startIndex` for next node
+        this.startIndex = endIndex + 1;
+    };
+    /** @internal */
+    Parser.prototype.oncdata = function (start, endIndex, offset) {
+        var _a;
+        var _b;
+        var _c;
+        var _d;
+        var _e;
+        var _f;
+        var _g;
+        var _h;
+        var _j;
+        var _k;
+        this.endIndex = endIndex;
+        var value = this.getSlice(start, endIndex - offset);
+        if (this.options.xmlMode || this.options.recognizeCDATA) {
+            (_b = (_a = this.cbs).oncdatastart) === null || _b === void 0 ? void 0 : _b.call(_a);
+            (_d = (_c = this.cbs).ontext) === null || _d === void 0 ? void 0 : _d.call(_c, value);
+            (_f = (_e = this.cbs).oncdataend) === null || _f === void 0 ? void 0 : _f.call(_e);
+        } else {
+            (_h = (_g = this.cbs).oncomment) === null || _h === void 0 ? void 0 : _h.call(_g, '[CDATA['.concat(value, ']]'));
+            (_k = (_j = this.cbs).oncommentend) === null || _k === void 0 ? void 0 : _k.call(_j);
+        }
+        // Set `startIndex` for next node
+        this.startIndex = endIndex + 1;
+    };
+    /** @internal */
+    Parser.prototype.onend = function () {
+        var _a;
+        var _b;
+        if (this.cbs.onclosetag) {
+            // Set the end index for all remaining tags
+            this.endIndex = this.startIndex;
+            for (var i = this.stack.length; i > 0; this.cbs.onclosetag(this.stack[--i], true)) {}
+        }
+        (_b = (_a = this.cbs).onend) === null || _b === void 0 ? void 0 : _b.call(_a);
+    };
+    /**
+     * Resets the parser to a blank state, ready to parse a new HTML document
+     */
+    Parser.prototype.reset = function () {
+        var _a;
+        var _b;
+        var _c;
+        var _d;
+        (_b = (_a = this.cbs).onreset) === null || _b === void 0 ? void 0 : _b.call(_a);
+        this.tokenizer.reset();
+        this.tagname = '';
+        this.attribname = '';
+        this.attribs = null;
+        this.stack.length = 0;
+        this.startIndex = 0;
+        this.endIndex = 0;
+        (_d = (_c = this.cbs).onparserinit) === null || _d === void 0 ? void 0 : _d.call(_c, this);
+        this.buffers.length = 0;
+        this.bufferOffset = 0;
+        this.writeIndex = 0;
+        this.ended = false;
+    };
+    /**
+     * Resets the parser, then parses a complete document and
+     * pushes it to the handler.
+     *
+     * @param data Document to parse.
+     */
+    Parser.prototype.parseComplete = function (data) {
+        this.reset();
+        this.end(data);
+    };
+    Parser.prototype.getSlice = function (start, end) {
+        while (start - this.bufferOffset >= this.buffers[0].length) {
+            this.shiftBuffer();
+        }
+        var str = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset);
+        while (end - this.bufferOffset > this.buffers[0].length) {
+            this.shiftBuffer();
+            str += this.buffers[0].slice(0, end - this.bufferOffset);
+        }
+        return str;
+    };
+    Parser.prototype.shiftBuffer = function () {
+        this.bufferOffset += this.buffers[0].length;
+        this.writeIndex--;
+        this.buffers.shift();
+    };
+    /**
+     * Parses a chunk of data and calls the corresponding callbacks.
+     *
+     * @param chunk Chunk to parse.
+     */
+    Parser.prototype.write = function (chunk) {
+        var _a;
+        var _b;
+        if (this.ended) {
+            (_b = (_a = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, new Error('.write() after done!'));
+            return;
+        }
+        this.buffers.push(chunk);
+        if (this.tokenizer.running) {
+            this.tokenizer.write(chunk);
+            this.writeIndex++;
+        }
+    };
+    /**
+     * Parses the end of the buffer and clears the stack, calls onend.
+     *
+     * @param chunk Optional final chunk to parse.
+     */
+    Parser.prototype.end = function (chunk) {
+        var _a;
+        var _b;
+        if (this.ended) {
+            (_b = (_a = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, Error('.end() after done!'));
+            return;
+        }
+        if (chunk) {
+            this.write(chunk);
+        }
+        this.ended = true;
+        this.tokenizer.end();
+    };
+    /**
+     * Pauses parsing. The parser won't emit events until `resume` is called.
+     */
+    Parser.prototype.pause = function () {
+        this.tokenizer.pause();
+    };
+    /**
+     * Resumes parsing after `pause` was called.
+     */
+    Parser.prototype.resume = function () {
+        this.tokenizer.resume();
+        while (this.tokenizer.running && this.writeIndex < this.buffers.length) {
+            this.tokenizer.write(this.buffers[this.writeIndex++]);
+        }
+        if (this.ended) {
+            this.tokenizer.end();
+        }
+    };
+    /**
+     * Alias of `write`, for backwards compatibility.
+     *
+     * @param chunk Chunk to parse.
+     * @deprecated
+     */
+    Parser.prototype.parseChunk = function (chunk) {
+        this.write(chunk);
+    };
+    /**
+     * Alias of `end`, for backwards compatibility.
+     *
+     * @param chunk Optional final chunk to parse.
+     * @deprecated
+     */
+    Parser.prototype.done = function (chunk) {
+        this.end(chunk);
+    };
+    return Parser;
+})();
+module.exports = Parser;

+ 806 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/Tokenizer.js

@@ -0,0 +1,806 @@
+var decode_js_1 = require('./entities/decode.js');
+var CharCodes;
+(function (CharCodes) {
+    CharCodes[(CharCodes['Tab'] = 9)] = 'Tab';
+    CharCodes[(CharCodes['NewLine'] = 10)] = 'NewLine';
+    CharCodes[(CharCodes['FormFeed'] = 12)] = 'FormFeed';
+    CharCodes[(CharCodes['CarriageReturn'] = 13)] = 'CarriageReturn';
+    CharCodes[(CharCodes['Space'] = 32)] = 'Space';
+    CharCodes[(CharCodes['ExclamationMark'] = 33)] = 'ExclamationMark';
+    CharCodes[(CharCodes['Num'] = 35)] = 'Num';
+    CharCodes[(CharCodes['Amp'] = 38)] = 'Amp';
+    CharCodes[(CharCodes['SingleQuote'] = 39)] = 'SingleQuote';
+    CharCodes[(CharCodes['DoubleQuote'] = 34)] = 'DoubleQuote';
+    CharCodes[(CharCodes['Dash'] = 45)] = 'Dash';
+    CharCodes[(CharCodes['Slash'] = 47)] = 'Slash';
+    CharCodes[(CharCodes['Zero'] = 48)] = 'Zero';
+    CharCodes[(CharCodes['Nine'] = 57)] = 'Nine';
+    CharCodes[(CharCodes['Semi'] = 59)] = 'Semi';
+    CharCodes[(CharCodes['Lt'] = 60)] = 'Lt';
+    CharCodes[(CharCodes['Eq'] = 61)] = 'Eq';
+    CharCodes[(CharCodes['Gt'] = 62)] = 'Gt';
+    CharCodes[(CharCodes['Questionmark'] = 63)] = 'Questionmark';
+    CharCodes[(CharCodes['UpperA'] = 65)] = 'UpperA';
+    CharCodes[(CharCodes['LowerA'] = 97)] = 'LowerA';
+    CharCodes[(CharCodes['UpperF'] = 70)] = 'UpperF';
+    CharCodes[(CharCodes['LowerF'] = 102)] = 'LowerF';
+    CharCodes[(CharCodes['UpperZ'] = 90)] = 'UpperZ';
+    CharCodes[(CharCodes['LowerZ'] = 122)] = 'LowerZ';
+    CharCodes[(CharCodes['LowerX'] = 120)] = 'LowerX';
+    CharCodes[(CharCodes['OpeningSquareBracket'] = 91)] = 'OpeningSquareBracket';
+})(CharCodes || (CharCodes = {}));
+/** All the states the tokenizer can be in. */
+var State;
+(function (State) {
+    State[(State['Text'] = 1)] = 'Text';
+    State[(State['BeforeTagName'] = 2)] = 'BeforeTagName';
+    State[(State['InTagName'] = 3)] = 'InTagName';
+    State[(State['InSelfClosingTag'] = 4)] = 'InSelfClosingTag';
+    State[(State['BeforeClosingTagName'] = 5)] = 'BeforeClosingTagName';
+    State[(State['InClosingTagName'] = 6)] = 'InClosingTagName';
+    State[(State['AfterClosingTagName'] = 7)] = 'AfterClosingTagName';
+    // Attributes
+    State[(State['BeforeAttributeName'] = 8)] = 'BeforeAttributeName';
+    State[(State['InAttributeName'] = 9)] = 'InAttributeName';
+    State[(State['AfterAttributeName'] = 10)] = 'AfterAttributeName';
+    State[(State['BeforeAttributeValue'] = 11)] = 'BeforeAttributeValue';
+    State[(State['InAttributeValueDq'] = 12)] = 'InAttributeValueDq';
+    State[(State['InAttributeValueSq'] = 13)] = 'InAttributeValueSq';
+    State[(State['InAttributeValueNq'] = 14)] = 'InAttributeValueNq';
+    // Declarations
+    State[(State['BeforeDeclaration'] = 15)] = 'BeforeDeclaration';
+    State[(State['InDeclaration'] = 16)] = 'InDeclaration';
+    // Processing instructions
+    State[(State['InProcessingInstruction'] = 17)] = 'InProcessingInstruction';
+    // Comments & CDATA
+    State[(State['BeforeComment'] = 18)] = 'BeforeComment';
+    State[(State['CDATASequence'] = 19)] = 'CDATASequence';
+    State[(State['InSpecialComment'] = 20)] = 'InSpecialComment';
+    State[(State['InCommentLike'] = 21)] = 'InCommentLike';
+    // Special tags
+    State[(State['BeforeSpecialS'] = 22)] = 'BeforeSpecialS';
+    State[(State['SpecialStartSequence'] = 23)] = 'SpecialStartSequence';
+    State[(State['InSpecialTag'] = 24)] = 'InSpecialTag';
+    State[(State['BeforeEntity'] = 25)] = 'BeforeEntity';
+    State[(State['BeforeNumericEntity'] = 26)] = 'BeforeNumericEntity';
+    State[(State['InNamedEntity'] = 27)] = 'InNamedEntity';
+    State[(State['InNumericEntity'] = 28)] = 'InNumericEntity';
+    State[(State['InHexEntity'] = 29)] = 'InHexEntity';
+})(State || (State = {}));
+function isWhitespace(c) {
+    return c === CharCodes.Space || c === CharCodes.NewLine || c === CharCodes.Tab || c === CharCodes.FormFeed || c === CharCodes.CarriageReturn;
+}
+function isEndOfTagSection(c) {
+    return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace(c);
+}
+function isNumber(c) {
+    return c >= CharCodes.Zero && c <= CharCodes.Nine;
+}
+function isASCIIAlpha(c) {
+    return (c >= CharCodes.LowerA && c <= CharCodes.LowerZ) || (c >= CharCodes.UpperA && c <= CharCodes.UpperZ);
+}
+function isHexDigit(c) {
+    return (c >= CharCodes.UpperA && c <= CharCodes.UpperF) || (c >= CharCodes.LowerA && c <= CharCodes.LowerF);
+}
+var QuoteType;
+(function (QuoteType) {
+    QuoteType[(QuoteType['NoValue'] = 0)] = 'NoValue';
+    QuoteType[(QuoteType['Unquoted'] = 1)] = 'Unquoted';
+    QuoteType[(QuoteType['Single'] = 2)] = 'Single';
+    QuoteType[(QuoteType['Double'] = 3)] = 'Double';
+})((QuoteType = exports.QuoteType || (exports.QuoteType = {})));
+/**
+ * Sequences used to match longer strings.
+ *
+ * We don't have `Script`, `Style`, or `Title` here. Instead, we re-use the *End
+ * sequences with an increased offset.
+ */
+var Sequences = {
+    Cdata: new Uint8Array([67, 68, 65, 84, 65, 91]),
+    CdataEnd: new Uint8Array([93, 93, 62]),
+    CommentEnd: new Uint8Array([45, 45, 62]),
+    ScriptEnd: new Uint8Array([60, 47, 115, 99, 114, 105, 112, 116]),
+    StyleEnd: new Uint8Array([60, 47, 115, 116, 121, 108, 101]),
+    TitleEnd: new Uint8Array([60, 47, 116, 105, 116, 108, 101]) // `</title`
+};
+
+var Tokenizer = /** @class */ (function () {
+    function Tokenizer(_a, cbs) {
+        var _b = _a.xmlMode;
+        var xmlMode = _b === void 0 ? false : _b;
+        var _c = _a.decodeEntities;
+        var decodeEntities = _c === void 0 ? true : _c;
+        this.cbs = cbs;
+        /** The current state the tokenizer is in. */
+        this.state = State.Text;
+        /** The read buffer. */
+        this.buffer = '';
+        /** The beginning of the section that is currently being read. */
+        this.sectionStart = 0;
+        /** The index within the buffer that we are currently looking at. */
+        this.index = 0;
+        /** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */
+        this.baseState = State.Text;
+        /** For special parsing behavior inside of script and style tags. */
+        this.isSpecial = false;
+        /** Indicates whether the tokenizer has been paused. */
+        this.running = true;
+        /** The offset of the current buffer. */
+        this.offset = 0;
+        this.sequenceIndex = 0;
+        this.trieIndex = 0;
+        this.trieCurrent = 0;
+        /** For named entities, the index of the value. For numeric entities, the code point. */
+        this.entityResult = 0;
+        this.entityExcess = 0;
+        this.xmlMode = xmlMode;
+        this.decodeEntities = decodeEntities;
+        this.entityTrie = xmlMode ? decode_js_1.xmlDecodeTree : decode_js_1.htmlDecodeTree;
+    }
+    Tokenizer.prototype.reset = function () {
+        this.state = State.Text;
+        this.buffer = '';
+        this.sectionStart = 0;
+        this.index = 0;
+        this.baseState = State.Text;
+        this.currentSequence = undefined;
+        this.running = true;
+        this.offset = 0;
+    };
+    Tokenizer.prototype.write = function (chunk) {
+        this.offset += this.buffer.length;
+        this.buffer = chunk;
+        this.parse();
+    };
+    Tokenizer.prototype.end = function () {
+        if (this.running) {
+            this.finish();
+        }
+    };
+    Tokenizer.prototype.pause = function () {
+        this.running = false;
+    };
+    Tokenizer.prototype.resume = function () {
+        this.running = true;
+        if (this.index < this.buffer.length + this.offset) {
+            this.parse();
+        }
+    };
+    /**
+     * The current index within all of the written data.
+     */
+    Tokenizer.prototype.getIndex = function () {
+        return this.index;
+    };
+    /**
+     * The start of the current section.
+     */
+    Tokenizer.prototype.getSectionStart = function () {
+        return this.sectionStart;
+    };
+    Tokenizer.prototype.stateText = function (c) {
+        if (c === CharCodes.Lt || (!this.decodeEntities && this.fastForwardTo(CharCodes.Lt))) {
+            if (this.index > this.sectionStart) {
+                this.cbs.ontext(this.sectionStart, this.index);
+            }
+            this.state = State.BeforeTagName;
+            this.sectionStart = this.index;
+        } else if (this.decodeEntities && c === CharCodes.Amp) {
+            this.state = State.BeforeEntity;
+        }
+    };
+    Tokenizer.prototype.stateSpecialStartSequence = function (c) {
+        var isEnd = this.sequenceIndex === this.currentSequence.length;
+        var isMatch = isEnd
+            ? // If we are at the end of the sequence, make sure the tag name has ended
+              isEndOfTagSection(c)
+            : // Otherwise, do a case-insensitive comparison
+              (c | 32) === this.currentSequence[this.sequenceIndex];
+        if (!isMatch) {
+            this.isSpecial = false;
+        } else if (!isEnd) {
+            this.sequenceIndex++;
+            return;
+        }
+        this.sequenceIndex = 0;
+        this.state = State.InTagName;
+        this.stateInTagName(c);
+    };
+    /** Look for an end tag. For <title> tags, also decode entities. */
+    Tokenizer.prototype.stateInSpecialTag = function (c) {
+        if (this.sequenceIndex === this.currentSequence.length) {
+            if (c === CharCodes.Gt || isWhitespace(c)) {
+                var endOfText = this.index - this.currentSequence.length;
+                if (this.sectionStart < endOfText) {
+                    // Spoof the index so that reported locations match up.
+                    var actualIndex = this.index;
+                    this.index = endOfText;
+                    this.cbs.ontext(this.sectionStart, endOfText);
+                    this.index = actualIndex;
+                }
+                this.isSpecial = false;
+                this.sectionStart = endOfText + 2; // Skip over the `</`
+                this.stateInClosingTagName(c);
+                return; // We are done; skip the rest of the function.
+            }
+
+            this.sequenceIndex = 0;
+        }
+        if ((c | 32) === this.currentSequence[this.sequenceIndex]) {
+            this.sequenceIndex += 1;
+        } else if (this.sequenceIndex === 0) {
+            if (this.currentSequence === Sequences.TitleEnd) {
+                // We have to parse entities in <title> tags.
+                if (this.decodeEntities && c === CharCodes.Amp) {
+                    this.state = State.BeforeEntity;
+                }
+            } else if (this.fastForwardTo(CharCodes.Lt)) {
+                // Outside of <title> tags, we can fast-forward.
+                this.sequenceIndex = 1;
+            }
+        } else {
+            // If we see a `<`, set the sequence index to 1; useful for eg. `<</script>`.
+            this.sequenceIndex = Number(c === CharCodes.Lt);
+        }
+    };
+    Tokenizer.prototype.stateCDATASequence = function (c) {
+        if (c === Sequences.Cdata[this.sequenceIndex]) {
+            if (++this.sequenceIndex === Sequences.Cdata.length) {
+                this.state = State.InCommentLike;
+                this.currentSequence = Sequences.CdataEnd;
+                this.sequenceIndex = 0;
+                this.sectionStart = this.index + 1;
+            }
+        } else {
+            this.sequenceIndex = 0;
+            this.state = State.InDeclaration;
+            this.stateInDeclaration(c); // Reconsume the character
+        }
+    };
+    /**
+     * When we wait for one specific character, we can speed things up
+     * by skipping through the buffer until we find it.
+     *
+     * @returns Whether the character was found.
+     */
+    Tokenizer.prototype.fastForwardTo = function (c) {
+        while (++this.index < this.buffer.length + this.offset) {
+            if (this.buffer.charCodeAt(this.index - this.offset) === c) {
+                return true;
+            }
+        }
+        /*
+         * We increment the index at the end of the `parse` loop,
+         * so set it to `buffer.length - 1` here.
+         *
+         * TODO: Refactor `parse` to increment index before calling states.
+         */
+        this.index = this.buffer.length + this.offset - 1;
+        return false;
+    };
+    /**
+     * Comments and CDATA end with `-->` and `]]>`.
+     *
+     * Their common qualities are:
+     * - Their end sequences have a distinct character they start with.
+     * - That character is then repeated, so we have to check multiple repeats.
+     * - All characters but the start character of the sequence can be skipped.
+     */
+    Tokenizer.prototype.stateInCommentLike = function (c) {
+        if (c === this.currentSequence[this.sequenceIndex]) {
+            if (++this.sequenceIndex === this.currentSequence.length) {
+                if (this.currentSequence === Sequences.CdataEnd) {
+                    this.cbs.oncdata(this.sectionStart, this.index, 2);
+                } else {
+                    this.cbs.oncomment(this.sectionStart, this.index, 2);
+                }
+                this.sequenceIndex = 0;
+                this.sectionStart = this.index + 1;
+                this.state = State.Text;
+            }
+        } else if (this.sequenceIndex === 0) {
+            // Fast-forward to the first character of the sequence
+            if (this.fastForwardTo(this.currentSequence[0])) {
+                this.sequenceIndex = 1;
+            }
+        } else if (c !== this.currentSequence[this.sequenceIndex - 1]) {
+            // Allow long sequences, eg. --->, ]]]>
+            this.sequenceIndex = 0;
+        }
+    };
+    /**
+     * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.
+     *
+     * XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).
+     * We allow anything that wouldn't end the tag.
+     */
+    Tokenizer.prototype.isTagStartChar = function (c) {
+        return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);
+    };
+    Tokenizer.prototype.startSpecial = function (sequence, offset) {
+        this.isSpecial = true;
+        this.currentSequence = sequence;
+        this.sequenceIndex = offset;
+        this.state = State.SpecialStartSequence;
+    };
+    Tokenizer.prototype.stateBeforeTagName = function (c) {
+        if (c === CharCodes.ExclamationMark) {
+            this.state = State.BeforeDeclaration;
+            this.sectionStart = this.index + 1;
+        } else if (c === CharCodes.Questionmark) {
+            this.state = State.InProcessingInstruction;
+            this.sectionStart = this.index + 1;
+        } else if (this.isTagStartChar(c)) {
+            var lower = c | 32;
+            this.sectionStart = this.index;
+            if (!this.xmlMode && lower === Sequences.TitleEnd[2]) {
+                this.startSpecial(Sequences.TitleEnd, 3);
+            } else {
+                this.state = !this.xmlMode && lower === Sequences.ScriptEnd[2] ? State.BeforeSpecialS : State.InTagName;
+            }
+        } else if (c === CharCodes.Slash) {
+            this.state = State.BeforeClosingTagName;
+        } else {
+            this.state = State.Text;
+            this.stateText(c);
+        }
+    };
+    Tokenizer.prototype.stateInTagName = function (c) {
+        if (isEndOfTagSection(c)) {
+            this.cbs.onopentagname(this.sectionStart, this.index);
+            this.sectionStart = -1;
+            this.state = State.BeforeAttributeName;
+            this.stateBeforeAttributeName(c);
+        }
+    };
+    Tokenizer.prototype.stateBeforeClosingTagName = function (c) {
+        if (isWhitespace(c)) {
+            // Ignore
+        } else if (c === CharCodes.Gt) {
+            this.state = State.Text;
+        } else {
+            this.state = this.isTagStartChar(c) ? State.InClosingTagName : State.InSpecialComment;
+            this.sectionStart = this.index;
+        }
+    };
+    Tokenizer.prototype.stateInClosingTagName = function (c) {
+        if (c === CharCodes.Gt || isWhitespace(c)) {
+            this.cbs.onclosetag(this.sectionStart, this.index);
+            this.sectionStart = -1;
+            this.state = State.AfterClosingTagName;
+            this.stateAfterClosingTagName(c);
+        }
+    };
+    Tokenizer.prototype.stateAfterClosingTagName = function (c) {
+        // Skip everything until ">"
+        if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
+            this.state = State.Text;
+            this.sectionStart = this.index + 1;
+        }
+    };
+    Tokenizer.prototype.stateBeforeAttributeName = function (c) {
+        if (c === CharCodes.Gt) {
+            this.cbs.onopentagend(this.index);
+            if (this.isSpecial) {
+                this.state = State.InSpecialTag;
+                this.sequenceIndex = 0;
+            } else {
+                this.state = State.Text;
+            }
+            this.baseState = this.state;
+            this.sectionStart = this.index + 1;
+        } else if (c === CharCodes.Slash) {
+            this.state = State.InSelfClosingTag;
+        } else if (!isWhitespace(c)) {
+            this.state = State.InAttributeName;
+            this.sectionStart = this.index;
+        }
+    };
+    Tokenizer.prototype.stateInSelfClosingTag = function (c) {
+        if (c === CharCodes.Gt) {
+            this.cbs.onselfclosingtag(this.index);
+            this.state = State.Text;
+            this.baseState = State.Text;
+            this.sectionStart = this.index + 1;
+            this.isSpecial = false; // Reset special state, in case of self-closing special tags
+        } else if (!isWhitespace(c)) {
+            this.state = State.BeforeAttributeName;
+            this.stateBeforeAttributeName(c);
+        }
+    };
+    Tokenizer.prototype.stateInAttributeName = function (c) {
+        if (c === CharCodes.Eq || isEndOfTagSection(c)) {
+            this.cbs.onattribname(this.sectionStart, this.index);
+            this.sectionStart = -1;
+            this.state = State.AfterAttributeName;
+            this.stateAfterAttributeName(c);
+        }
+    };
+    Tokenizer.prototype.stateAfterAttributeName = function (c) {
+        if (c === CharCodes.Eq) {
+            this.state = State.BeforeAttributeValue;
+        } else if (c === CharCodes.Slash || c === CharCodes.Gt) {
+            this.cbs.onattribend(QuoteType.NoValue, this.index);
+            this.state = State.BeforeAttributeName;
+            this.stateBeforeAttributeName(c);
+        } else if (!isWhitespace(c)) {
+            this.cbs.onattribend(QuoteType.NoValue, this.index);
+            this.state = State.InAttributeName;
+            this.sectionStart = this.index;
+        }
+    };
+    Tokenizer.prototype.stateBeforeAttributeValue = function (c) {
+        if (c === CharCodes.DoubleQuote) {
+            this.state = State.InAttributeValueDq;
+            this.sectionStart = this.index + 1;
+        } else if (c === CharCodes.SingleQuote) {
+            this.state = State.InAttributeValueSq;
+            this.sectionStart = this.index + 1;
+        } else if (!isWhitespace(c)) {
+            this.sectionStart = this.index;
+            this.state = State.InAttributeValueNq;
+            this.stateInAttributeValueNoQuotes(c); // Reconsume token
+        }
+    };
+
+    Tokenizer.prototype.handleInAttributeValue = function (c, quote) {
+        if (c === quote || (!this.decodeEntities && this.fastForwardTo(quote))) {
+            this.cbs.onattribdata(this.sectionStart, this.index);
+            this.sectionStart = -1;
+            this.cbs.onattribend(quote === CharCodes.DoubleQuote ? QuoteType.Double : QuoteType.Single, this.index);
+            this.state = State.BeforeAttributeName;
+        } else if (this.decodeEntities && c === CharCodes.Amp) {
+            this.baseState = this.state;
+            this.state = State.BeforeEntity;
+        }
+    };
+    Tokenizer.prototype.stateInAttributeValueDoubleQuotes = function (c) {
+        this.handleInAttributeValue(c, CharCodes.DoubleQuote);
+    };
+    Tokenizer.prototype.stateInAttributeValueSingleQuotes = function (c) {
+        this.handleInAttributeValue(c, CharCodes.SingleQuote);
+    };
+    Tokenizer.prototype.stateInAttributeValueNoQuotes = function (c) {
+        if (isWhitespace(c) || c === CharCodes.Gt) {
+            this.cbs.onattribdata(this.sectionStart, this.index);
+            this.sectionStart = -1;
+            this.cbs.onattribend(QuoteType.Unquoted, this.index);
+            this.state = State.BeforeAttributeName;
+            this.stateBeforeAttributeName(c);
+        } else if (this.decodeEntities && c === CharCodes.Amp) {
+            this.baseState = this.state;
+            this.state = State.BeforeEntity;
+        }
+    };
+    Tokenizer.prototype.stateBeforeDeclaration = function (c) {
+        if (c === CharCodes.OpeningSquareBracket) {
+            this.state = State.CDATASequence;
+            this.sequenceIndex = 0;
+        } else {
+            this.state = c === CharCodes.Dash ? State.BeforeComment : State.InDeclaration;
+        }
+    };
+    Tokenizer.prototype.stateInDeclaration = function (c) {
+        if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
+            this.cbs.ondeclaration(this.sectionStart, this.index);
+            this.state = State.Text;
+            this.sectionStart = this.index + 1;
+        }
+    };
+    Tokenizer.prototype.stateInProcessingInstruction = function (c) {
+        if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
+            this.cbs.onprocessinginstruction(this.sectionStart, this.index);
+            this.state = State.Text;
+            this.sectionStart = this.index + 1;
+        }
+    };
+    Tokenizer.prototype.stateBeforeComment = function (c) {
+        if (c === CharCodes.Dash) {
+            this.state = State.InCommentLike;
+            this.currentSequence = Sequences.CommentEnd;
+            // Allow short comments (eg. <!-->)
+            this.sequenceIndex = 2;
+            this.sectionStart = this.index + 1;
+        } else {
+            this.state = State.InDeclaration;
+        }
+    };
+    Tokenizer.prototype.stateInSpecialComment = function (c) {
+        if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
+            this.cbs.oncomment(this.sectionStart, this.index, 0);
+            this.state = State.Text;
+            this.sectionStart = this.index + 1;
+        }
+    };
+    Tokenizer.prototype.stateBeforeSpecialS = function (c) {
+        var lower = c | 32;
+        if (lower === Sequences.ScriptEnd[3]) {
+            this.startSpecial(Sequences.ScriptEnd, 4);
+        } else if (lower === Sequences.StyleEnd[3]) {
+            this.startSpecial(Sequences.StyleEnd, 4);
+        } else {
+            this.state = State.InTagName;
+            this.stateInTagName(c); // Consume the token again
+        }
+    };
+
+    Tokenizer.prototype.stateBeforeEntity = function (c) {
+        // Start excess with 1 to include the '&'
+        this.entityExcess = 1;
+        this.entityResult = 0;
+        if (c === CharCodes.Num) {
+            this.state = State.BeforeNumericEntity;
+        } else if (c === CharCodes.Amp) {
+            // We have two `&` characters in a row. Stay in the current state.
+        } else {
+            this.trieIndex = 0;
+            this.trieCurrent = this.entityTrie[0];
+            this.state = State.InNamedEntity;
+            this.stateInNamedEntity(c);
+        }
+    };
+    Tokenizer.prototype.stateInNamedEntity = function (c) {
+        this.entityExcess += 1;
+        this.trieIndex = (0, decode_js_1.determineBranch)(this.entityTrie, this.trieCurrent, this.trieIndex + 1, c);
+        if (this.trieIndex < 0) {
+            this.emitNamedEntity();
+            this.index--;
+            return;
+        }
+        this.trieCurrent = this.entityTrie[this.trieIndex];
+        var masked = this.trieCurrent & decode_js_1.BinTrieFlags.VALUE_LENGTH;
+        // If the branch is a value, store it and continue
+        if (masked) {
+            // The mask is the number of bytes of the value, including the current byte.
+            var valueLength = (masked >> 14) - 1;
+            // If we have a legacy entity while parsing strictly, just skip the number of bytes
+            if (!this.allowLegacyEntity() && c !== CharCodes.Semi) {
+                this.trieIndex += valueLength;
+            } else {
+                // Add 1 as we have already incremented the excess
+                var entityStart = this.index - this.entityExcess + 1;
+                if (entityStart > this.sectionStart) {
+                    this.emitPartial(this.sectionStart, entityStart);
+                }
+                // If this is a surrogate pair, consume the next two bytes
+                this.entityResult = this.trieIndex;
+                this.trieIndex += valueLength;
+                this.entityExcess = 0;
+                this.sectionStart = this.index + 1;
+                if (valueLength === 0) {
+                    this.emitNamedEntity();
+                }
+            }
+        }
+    };
+    Tokenizer.prototype.emitNamedEntity = function () {
+        this.state = this.baseState;
+        if (this.entityResult === 0) {
+            return;
+        }
+        var valueLength = (this.entityTrie[this.entityResult] & decode_js_1.BinTrieFlags.VALUE_LENGTH) >> 14;
+        switch (valueLength) {
+            case 1:
+                this.emitCodePoint(this.entityTrie[this.entityResult] & ~decode_js_1.BinTrieFlags.VALUE_LENGTH);
+                break;
+            case 2:
+                this.emitCodePoint(this.entityTrie[this.entityResult + 1]);
+                break;
+            case 3: {
+                this.emitCodePoint(this.entityTrie[this.entityResult + 1]);
+                this.emitCodePoint(this.entityTrie[this.entityResult + 2]);
+            }
+        }
+    };
+    Tokenizer.prototype.stateBeforeNumericEntity = function (c) {
+        if ((c | 32) === CharCodes.LowerX) {
+            this.entityExcess++;
+            this.state = State.InHexEntity;
+        } else {
+            this.state = State.InNumericEntity;
+            this.stateInNumericEntity(c);
+        }
+    };
+    Tokenizer.prototype.emitNumericEntity = function (strict) {
+        var entityStart = this.index - this.entityExcess - 1;
+        var numberStart = entityStart + 2 + Number(this.state === State.InHexEntity);
+        if (numberStart !== this.index) {
+            // Emit leading data if any
+            if (entityStart > this.sectionStart) {
+                this.emitPartial(this.sectionStart, entityStart);
+            }
+            this.sectionStart = this.index + Number(strict);
+            this.emitCodePoint((0, decode_js_1.replaceCodePoint)(this.entityResult));
+        }
+        this.state = this.baseState;
+    };
+    Tokenizer.prototype.stateInNumericEntity = function (c) {
+        if (c === CharCodes.Semi) {
+            this.emitNumericEntity(true);
+        } else if (isNumber(c)) {
+            this.entityResult = this.entityResult * 10 + (c - CharCodes.Zero);
+            this.entityExcess++;
+        } else {
+            if (this.allowLegacyEntity()) {
+                this.emitNumericEntity(false);
+            } else {
+                this.state = this.baseState;
+            }
+            this.index--;
+        }
+    };
+    Tokenizer.prototype.stateInHexEntity = function (c) {
+        if (c === CharCodes.Semi) {
+            this.emitNumericEntity(true);
+        } else if (isNumber(c)) {
+            this.entityResult = this.entityResult * 16 + (c - CharCodes.Zero);
+            this.entityExcess++;
+        } else if (isHexDigit(c)) {
+            this.entityResult = this.entityResult * 16 + ((c | 32) - CharCodes.LowerA + 10);
+            this.entityExcess++;
+        } else {
+            if (this.allowLegacyEntity()) {
+                this.emitNumericEntity(false);
+            } else {
+                this.state = this.baseState;
+            }
+            this.index--;
+        }
+    };
+    Tokenizer.prototype.allowLegacyEntity = function () {
+        return !this.xmlMode && (this.baseState === State.Text || this.baseState === State.InSpecialTag);
+    };
+    /**
+     * Remove data that has already been consumed from the buffer.
+     */
+    Tokenizer.prototype.cleanup = function () {
+        // If we are inside of text or attributes, emit what we already have.
+        if (this.running && this.sectionStart !== this.index) {
+            if (this.state === State.Text || (this.state === State.InSpecialTag && this.sequenceIndex === 0)) {
+                this.cbs.ontext(this.sectionStart, this.index);
+                this.sectionStart = this.index;
+            } else if (this.state === State.InAttributeValueDq || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueNq) {
+                this.cbs.onattribdata(this.sectionStart, this.index);
+                this.sectionStart = this.index;
+            }
+        }
+    };
+    Tokenizer.prototype.shouldContinue = function () {
+        return this.index < this.buffer.length + this.offset && this.running;
+    };
+    /**
+     * Iterates through the buffer, calling the function corresponding to the current state.
+     *
+     * States that are more likely to be hit are higher up, as a performance improvement.
+     */
+    Tokenizer.prototype.parse = function () {
+        while (this.shouldContinue()) {
+            var c = this.buffer.charCodeAt(this.index - this.offset);
+            if (this.state === State.Text) {
+                this.stateText(c);
+            } else if (this.state === State.SpecialStartSequence) {
+                this.stateSpecialStartSequence(c);
+            } else if (this.state === State.InSpecialTag) {
+                this.stateInSpecialTag(c);
+            } else if (this.state === State.CDATASequence) {
+                this.stateCDATASequence(c);
+            } else if (this.state === State.InAttributeValueDq) {
+                this.stateInAttributeValueDoubleQuotes(c);
+            } else if (this.state === State.InAttributeName) {
+                this.stateInAttributeName(c);
+            } else if (this.state === State.InCommentLike) {
+                this.stateInCommentLike(c);
+            } else if (this.state === State.InSpecialComment) {
+                this.stateInSpecialComment(c);
+            } else if (this.state === State.BeforeAttributeName) {
+                this.stateBeforeAttributeName(c);
+            } else if (this.state === State.InTagName) {
+                this.stateInTagName(c);
+            } else if (this.state === State.InClosingTagName) {
+                this.stateInClosingTagName(c);
+            } else if (this.state === State.BeforeTagName) {
+                this.stateBeforeTagName(c);
+            } else if (this.state === State.AfterAttributeName) {
+                this.stateAfterAttributeName(c);
+            } else if (this.state === State.InAttributeValueSq) {
+                this.stateInAttributeValueSingleQuotes(c);
+            } else if (this.state === State.BeforeAttributeValue) {
+                this.stateBeforeAttributeValue(c);
+            } else if (this.state === State.BeforeClosingTagName) {
+                this.stateBeforeClosingTagName(c);
+            } else if (this.state === State.AfterClosingTagName) {
+                this.stateAfterClosingTagName(c);
+            } else if (this.state === State.BeforeSpecialS) {
+                this.stateBeforeSpecialS(c);
+            } else if (this.state === State.InAttributeValueNq) {
+                this.stateInAttributeValueNoQuotes(c);
+            } else if (this.state === State.InSelfClosingTag) {
+                this.stateInSelfClosingTag(c);
+            } else if (this.state === State.InDeclaration) {
+                this.stateInDeclaration(c);
+            } else if (this.state === State.BeforeDeclaration) {
+                this.stateBeforeDeclaration(c);
+            } else if (this.state === State.BeforeComment) {
+                this.stateBeforeComment(c);
+            } else if (this.state === State.InProcessingInstruction) {
+                this.stateInProcessingInstruction(c);
+            } else if (this.state === State.InNamedEntity) {
+                this.stateInNamedEntity(c);
+            } else if (this.state === State.BeforeEntity) {
+                this.stateBeforeEntity(c);
+            } else if (this.state === State.InHexEntity) {
+                this.stateInHexEntity(c);
+            } else if (this.state === State.InNumericEntity) {
+                this.stateInNumericEntity(c);
+            } else {
+                // `this._state === State.BeforeNumericEntity`
+                this.stateBeforeNumericEntity(c);
+            }
+            this.index++;
+        }
+        this.cleanup();
+    };
+    Tokenizer.prototype.finish = function () {
+        if (this.state === State.InNamedEntity) {
+            this.emitNamedEntity();
+        }
+        // If there is remaining data, emit it in a reasonable way
+        if (this.sectionStart < this.index) {
+            this.handleTrailingData();
+        }
+        this.cbs.onend();
+    };
+    /** Handle any trailing data. */
+    Tokenizer.prototype.handleTrailingData = function () {
+        var endIndex = this.buffer.length + this.offset;
+        if (this.state === State.InCommentLike) {
+            if (this.currentSequence === Sequences.CdataEnd) {
+                this.cbs.oncdata(this.sectionStart, endIndex, 0);
+            } else {
+                this.cbs.oncomment(this.sectionStart, endIndex, 0);
+            }
+        } else if (this.state === State.InNumericEntity && this.allowLegacyEntity()) {
+            this.emitNumericEntity(false);
+            // All trailing data will have been consumed
+        } else if (this.state === State.InHexEntity && this.allowLegacyEntity()) {
+            this.emitNumericEntity(false);
+            // All trailing data will have been consumed
+        } else if (
+            this.state === State.InTagName ||
+            this.state === State.BeforeAttributeName ||
+            this.state === State.BeforeAttributeValue ||
+            this.state === State.AfterAttributeName ||
+            this.state === State.InAttributeName ||
+            this.state === State.InAttributeValueSq ||
+            this.state === State.InAttributeValueDq ||
+            this.state === State.InAttributeValueNq ||
+            this.state === State.InClosingTagName
+        ) {
+            /*
+             * If we are currently in an opening or closing tag, us not calling the
+             * respective callback signals that the tag should be ignored.
+             */
+        } else {
+            this.cbs.ontext(this.sectionStart, endIndex);
+        }
+    };
+    Tokenizer.prototype.emitPartial = function (start, endIndex) {
+        if (this.baseState !== State.Text && this.baseState !== State.InSpecialTag) {
+            this.cbs.onattribdata(start, endIndex);
+        } else {
+            this.cbs.ontext(start, endIndex);
+        }
+    };
+    Tokenizer.prototype.emitCodePoint = function (cp) {
+        if (this.baseState !== State.Text && this.baseState !== State.InSpecialTag) {
+            this.cbs.onattribentity(cp);
+        } else {
+            this.cbs.ontextentity(cp);
+        }
+    };
+    return Tokenizer;
+})();
+module.exports = {
+    default: Tokenizer,
+    QuoteType
+};

+ 66 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/domelementtype/index.js

@@ -0,0 +1,66 @@
+'use strict';
+Object.defineProperty(exports, '__esModule', {
+    value: true
+});
+exports.Doctype =
+    exports.CDATA =
+    exports.Tag =
+    exports.Style =
+    exports.Script =
+    exports.Comment =
+    exports.Directive =
+    exports.Text =
+    exports.Root =
+    exports.isTag =
+    exports.ElementType =
+        void 0;
+/** Types of elements found in htmlparser2's DOM */
+var ElementType;
+(function (ElementType) {
+    /** Type for the root element of a document */
+    ElementType['Root'] = 'root';
+    /** Type for Text */
+    ElementType['Text'] = 'text';
+    /** Type for <? ... ?> */
+    ElementType['Directive'] = 'directive';
+    /** Type for <!-- ... --> */
+    ElementType['Comment'] = 'comment';
+    /** Type for <script> tags */
+    ElementType['Script'] = 'script';
+    /** Type for <style> tags */
+    ElementType['Style'] = 'style';
+    /** Type for Any tag */
+    ElementType['Tag'] = 'tag';
+    /** Type for <![CDATA[ ... ]]> */
+    ElementType['CDATA'] = 'cdata';
+    /** Type for <!doctype ...> */
+    ElementType['Doctype'] = 'doctype';
+})((ElementType = exports.ElementType || (exports.ElementType = {})));
+/**
+ * Tests whether an element is a tag or not.
+ *
+ * @param elem Element to test
+ */
+function isTag(elem) {
+    return elem.type === ElementType.Tag || elem.type === ElementType.Script || elem.type === ElementType.Style;
+}
+exports.isTag = isTag;
+// Exports for backwards compatibility
+/** Type for the root element of a document */
+exports.Root = ElementType.Root;
+/** Type for Text */
+exports.Text = ElementType.Text;
+/** Type for <? ... ?> */
+exports.Directive = ElementType.Directive;
+/** Type for <!-- ... --> */
+exports.Comment = ElementType.Comment;
+/** Type for <script> tags */
+exports.Script = ElementType.Script;
+/** Type for <style> tags */
+exports.Style = ElementType.Style;
+/** Type for Any tag */
+exports.Tag = ElementType.Tag;
+/** Type for <![CDATA[ ... ]]> */
+exports.CDATA = ElementType.CDATA;
+/** Type for <!doctype ...> */
+exports.Doctype = ElementType.Doctype;

+ 145 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/domhandler/index.js

@@ -0,0 +1,145 @@
+var domelementtype_1 = require('../domelementtype/index.js');
+var node_js_1 = require('./node.js');
+var defaultOpts = {
+    withStartIndices: false,
+    withEndIndices: false,
+    xmlMode: false
+};
+var DomHandler = /** @class */ (function () {
+    /**
+     * @param callback Called once parsing has completed.
+     * @param options Settings for the handler.
+     * @param elementCB Callback whenever a tag is closed.
+     */
+    function DomHandler(callback, options, elementCB) {
+        /** The elements of the DOM */
+        this.dom = [];
+        /** The root element for the DOM */
+        this.root = new node_js_1.Document(this.dom);
+        /** Indicated whether parsing has been completed. */
+        this.done = false;
+        /** Stack of open tags. */
+        this.tagStack = [this.root];
+        /** A data node that is still being written to. */
+        this.lastNode = null;
+        /** Reference to the parser instance. Used for location information. */
+        this.parser = null;
+        // Make it possible to skip arguments, for backwards-compatibility
+        if (typeof options === 'function') {
+            elementCB = options;
+            options = defaultOpts;
+        }
+        if (typeof callback === 'object') {
+            options = callback;
+            callback = undefined;
+        }
+        this.callback = callback !== null && callback !== void 0 ? callback : null;
+        this.options = options !== null && options !== void 0 ? options : defaultOpts;
+        this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null;
+    }
+    DomHandler.prototype.onparserinit = function (parser) {
+        this.parser = parser;
+    };
+    // Resets the handler back to starting state
+    DomHandler.prototype.onreset = function () {
+        this.dom = [];
+        this.root = new node_js_1.Document(this.dom);
+        this.done = false;
+        this.tagStack = [this.root];
+        this.lastNode = null;
+        this.parser = null;
+    };
+    // Signals the handler that parsing is done
+    DomHandler.prototype.onend = function () {
+        if (this.done) {
+            return;
+        }
+        this.done = true;
+        this.parser = null;
+        this.handleCallback(null);
+    };
+    DomHandler.prototype.onerror = function (error) {
+        this.handleCallback(error);
+    };
+    DomHandler.prototype.onclosetag = function () {
+        this.lastNode = null;
+        var elem = this.tagStack.pop();
+        if (this.options.withEndIndices) {
+            elem.endIndex = this.parser.endIndex;
+        }
+        if (this.elementCB) {
+            this.elementCB(elem);
+        }
+    };
+    DomHandler.prototype.onopentag = function (name, attribs) {
+        var type = this.options.xmlMode ? domelementtype_1.ElementType.Tag : undefined;
+        var element = new node_js_1.Element(name, attribs, undefined, type);
+        this.addNode(element);
+        this.tagStack.push(element);
+    };
+    DomHandler.prototype.ontext = function (data) {
+        var lastNode = this.lastNode;
+        if (lastNode && lastNode.type === domelementtype_1.ElementType.Text) {
+            lastNode.data += data;
+            if (this.options.withEndIndices) {
+                lastNode.endIndex = this.parser.endIndex;
+            }
+        } else {
+            var node = new node_js_1.Text(data);
+            this.addNode(node);
+            this.lastNode = node;
+        }
+    };
+    DomHandler.prototype.oncomment = function (data) {
+        if (this.lastNode && this.lastNode.type === domelementtype_1.ElementType.Comment) {
+            this.lastNode.data += data;
+            return;
+        }
+        var node = new node_js_1.Comment(data);
+        this.addNode(node);
+        this.lastNode = node;
+    };
+    DomHandler.prototype.oncommentend = function () {
+        this.lastNode = null;
+    };
+    DomHandler.prototype.oncdatastart = function () {
+        var text = new node_js_1.Text('');
+        var node = new node_js_1.CDATA([text]);
+        this.addNode(node);
+        text.parent = node;
+        this.lastNode = text;
+    };
+    DomHandler.prototype.oncdataend = function () {
+        this.lastNode = null;
+    };
+    DomHandler.prototype.onprocessinginstruction = function (name, data) {
+        var node = new node_js_1.ProcessingInstruction(name, data);
+        this.addNode(node);
+    };
+    DomHandler.prototype.handleCallback = function (error) {
+        if (typeof this.callback === 'function') {
+            this.callback(error, this.dom);
+        } else if (error) {
+            throw error;
+        }
+    };
+    DomHandler.prototype.addNode = function (node) {
+        var parent = this.tagStack[this.tagStack.length - 1];
+        var previousSibling = parent.children[parent.children.length - 1];
+        if (this.options.withStartIndices) {
+            node.startIndex = this.parser.startIndex;
+        }
+        if (this.options.withEndIndices) {
+            node.endIndex = this.parser.endIndex;
+        }
+        parent.children.push(node);
+        if (previousSibling) {
+            node.prev = previousSibling;
+            previousSibling.next = node;
+        }
+        node.parent = parent;
+        this.lastNode = null;
+    };
+    return DomHandler;
+})();
+module.exports = DomHandler;

+ 484 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/domhandler/node.js

@@ -0,0 +1,484 @@
+"use strict";
+var __extends = this && this.__extends || function () {
+  var extendStatics = function (d, b) {
+    extendStatics = Object.setPrototypeOf || {
+      __proto__: []
+    } instanceof Array && function (d, b) {
+      d.__proto__ = b;
+    } || function (d, b) {
+      for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
+    };
+    return extendStatics(d, b);
+  };
+  return function (d, b) {
+    if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
+    extendStatics(d, b);
+    function __() {
+      this.constructor = d;
+    }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+  };
+}();
+var __assign = this && this.__assign || function () {
+  __assign = Object.assign || function (t) {
+    for (var s, i = 1, n = arguments.length; i < n; i++) {
+      s = arguments[i];
+      for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+    }
+    return t;
+  };
+  return __assign.apply(this, arguments);
+};
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.cloneNode = exports.hasChildren = exports.isDocument = exports.isDirective = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = exports.Element = exports.Document = exports.CDATA = exports.NodeWithChildren = exports.ProcessingInstruction = exports.Comment = exports.Text = exports.DataNode = exports.Node = void 0;
+var domelementtype_1 = require("../domelementtype/index.js");
+/**
+ * This object will be used as the prototype for Nodes when creating a
+ * DOM-Level-1-compliant structure.
+ */
+var Node = /** @class */function () {
+  function Node() {
+    /** Parent of the node */
+    this.parent = null;
+    /** Previous sibling */
+    this.prev = null;
+    /** Next sibling */
+    this.next = null;
+    /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */
+    this.startIndex = null;
+    /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */
+    this.endIndex = null;
+  }
+  Object.defineProperty(Node.prototype, "parentNode", {
+    // Read-write aliases for properties
+    /**
+     * Same as {@link parent}.
+     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
+     */
+    get: function () {
+      return this.parent;
+    },
+    set: function (parent) {
+      this.parent = parent;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  Object.defineProperty(Node.prototype, "previousSibling", {
+    /**
+     * Same as {@link prev}.
+     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
+     */
+    get: function () {
+      return this.prev;
+    },
+    set: function (prev) {
+      this.prev = prev;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  Object.defineProperty(Node.prototype, "nextSibling", {
+    /**
+     * Same as {@link next}.
+     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
+     */
+    get: function () {
+      return this.next;
+    },
+    set: function (next) {
+      this.next = next;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  /**
+   * Clone this node, and optionally its children.
+   *
+   * @param recursive Clone child nodes as well.
+   * @returns A clone of the node.
+   */
+  Node.prototype.cloneNode = function (recursive) {
+    if (recursive === void 0) {
+      recursive = false;
+    }
+    return cloneNode(this, recursive);
+  };
+  return Node;
+}();
+exports.Node = Node;
+/**
+ * A node that contains some data.
+ */
+var DataNode = /** @class */function (_super) {
+  __extends(DataNode, _super);
+  /**
+   * @param data The content of the data node
+   */
+  function DataNode(data) {
+    var _this = _super.call(this) || this;
+    _this.data = data;
+    return _this;
+  }
+  Object.defineProperty(DataNode.prototype, "nodeValue", {
+    /**
+     * Same as {@link data}.
+     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
+     */
+    get: function () {
+      return this.data;
+    },
+    set: function (data) {
+      this.data = data;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  return DataNode;
+}(Node);
+exports.DataNode = DataNode;
+/**
+ * Text within the document.
+ */
+var Text = /** @class */function (_super) {
+  __extends(Text, _super);
+  function Text() {
+    var _this = _super !== null && _super.apply(this, arguments) || this;
+    _this.type = domelementtype_1.ElementType.Text;
+    return _this;
+  }
+  Object.defineProperty(Text.prototype, "nodeType", {
+    get: function () {
+      return 3;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  return Text;
+}(DataNode);
+exports.Text = Text;
+/**
+ * Comments within the document.
+ */
+var Comment = /** @class */function (_super) {
+  __extends(Comment, _super);
+  function Comment() {
+    var _this = _super !== null && _super.apply(this, arguments) || this;
+    _this.type = domelementtype_1.ElementType.Comment;
+    return _this;
+  }
+  Object.defineProperty(Comment.prototype, "nodeType", {
+    get: function () {
+      return 8;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  return Comment;
+}(DataNode);
+exports.Comment = Comment;
+/**
+ * Processing instructions, including doc types.
+ */
+var ProcessingInstruction = /** @class */function (_super) {
+  __extends(ProcessingInstruction, _super);
+  function ProcessingInstruction(name, data) {
+    var _this = _super.call(this, data) || this;
+    _this.name = name;
+    _this.type = domelementtype_1.ElementType.Directive;
+    return _this;
+  }
+  Object.defineProperty(ProcessingInstruction.prototype, "nodeType", {
+    get: function () {
+      return 1;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  return ProcessingInstruction;
+}(DataNode);
+exports.ProcessingInstruction = ProcessingInstruction;
+/**
+ * A `Node` that can have children.
+ */
+var NodeWithChildren = /** @class */function (_super) {
+  __extends(NodeWithChildren, _super);
+  /**
+   * @param children Children of the node. Only certain node types can have children.
+   */
+  function NodeWithChildren(children) {
+    var _this = _super.call(this) || this;
+    _this.children = children;
+    return _this;
+  }
+  Object.defineProperty(NodeWithChildren.prototype, "firstChild", {
+    // Aliases
+    /** First child of the node. */
+    get: function () {
+      var _a;
+      return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  Object.defineProperty(NodeWithChildren.prototype, "lastChild", {
+    /** Last child of the node. */
+    get: function () {
+      return this.children.length > 0 ? this.children[this.children.length - 1] : null;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  Object.defineProperty(NodeWithChildren.prototype, "childNodes", {
+    /**
+     * Same as {@link children}.
+     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
+     */
+    get: function () {
+      return this.children;
+    },
+    set: function (children) {
+      this.children = children;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  return NodeWithChildren;
+}(Node);
+exports.NodeWithChildren = NodeWithChildren;
+var CDATA = /** @class */function (_super) {
+  __extends(CDATA, _super);
+  function CDATA() {
+    var _this = _super !== null && _super.apply(this, arguments) || this;
+    _this.type = domelementtype_1.ElementType.CDATA;
+    return _this;
+  }
+  Object.defineProperty(CDATA.prototype, "nodeType", {
+    get: function () {
+      return 4;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  return CDATA;
+}(NodeWithChildren);
+exports.CDATA = CDATA;
+/**
+ * The root node of the document.
+ */
+var Document = /** @class */function (_super) {
+  __extends(Document, _super);
+  function Document() {
+    var _this = _super !== null && _super.apply(this, arguments) || this;
+    _this.type = domelementtype_1.ElementType.Root;
+    return _this;
+  }
+  Object.defineProperty(Document.prototype, "nodeType", {
+    get: function () {
+      return 9;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  return Document;
+}(NodeWithChildren);
+exports.Document = Document;
+/**
+ * An element within the DOM.
+ */
+var Element = /** @class */function (_super) {
+  __extends(Element, _super);
+  /**
+   * @param name Name of the tag, eg. `div`, `span`.
+   * @param attribs Object mapping attribute names to attribute values.
+   * @param children Children of the node.
+   */
+  function Element(name, attribs, children, type) {
+    if (children === void 0) {
+      children = [];
+    }
+    if (type === void 0) {
+      type = name === "script" ? domelementtype_1.ElementType.Script : name === "style" ? domelementtype_1.ElementType.Style : domelementtype_1.ElementType.Tag;
+    }
+    var _this = _super.call(this, children) || this;
+    _this.name = name;
+    _this.attribs = attribs;
+    _this.type = type;
+    return _this;
+  }
+  Object.defineProperty(Element.prototype, "nodeType", {
+    get: function () {
+      return 1;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  Object.defineProperty(Element.prototype, "tagName", {
+    // DOM Level 1 aliases
+    /**
+     * Same as {@link name}.
+     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
+     */
+    get: function () {
+      return this.name;
+    },
+    set: function (name) {
+      this.name = name;
+    },
+    enumerable: false,
+    configurable: true
+  });
+  Object.defineProperty(Element.prototype, "attributes", {
+    get: function () {
+      var _this = this;
+      return Object.keys(this.attribs).map(function (name) {
+        var _a, _b;
+        return {
+          name: name,
+          value: _this.attribs[name],
+          namespace: (_a = _this["x-attribsNamespace"]) === null || _a === void 0 ? void 0 : _a[name],
+          prefix: (_b = _this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name]
+        };
+      });
+    },
+    enumerable: false,
+    configurable: true
+  });
+  return Element;
+}(NodeWithChildren);
+exports.Element = Element;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node is a `Element`, `false` otherwise.
+ */
+function isTag(node) {
+  return (0, domelementtype_1.isTag)(node);
+}
+exports.isTag = isTag;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `CDATA`, `false` otherwise.
+ */
+function isCDATA(node) {
+  return node.type === domelementtype_1.ElementType.CDATA;
+}
+exports.isCDATA = isCDATA;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `Text`, `false` otherwise.
+ */
+function isText(node) {
+  return node.type === domelementtype_1.ElementType.Text;
+}
+exports.isText = isText;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `Comment`, `false` otherwise.
+ */
+function isComment(node) {
+  return node.type === domelementtype_1.ElementType.Comment;
+}
+exports.isComment = isComment;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
+ */
+function isDirective(node) {
+  return node.type === domelementtype_1.ElementType.Directive;
+}
+exports.isDirective = isDirective;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
+ */
+function isDocument(node) {
+  return node.type === domelementtype_1.ElementType.Root;
+}
+exports.isDocument = isDocument;
+/**
+ * @param node Node to check.
+ * @returns `true` if the node has children, `false` otherwise.
+ */
+function hasChildren(node) {
+  return Object.prototype.hasOwnProperty.call(node, "children");
+}
+exports.hasChildren = hasChildren;
+/**
+ * Clone a node, and optionally its children.
+ *
+ * @param recursive Clone child nodes as well.
+ * @returns A clone of the node.
+ */
+function cloneNode(node, recursive) {
+  if (recursive === void 0) {
+    recursive = false;
+  }
+  var result;
+  if (isText(node)) {
+    result = new Text(node.data);
+  } else if (isComment(node)) {
+    result = new Comment(node.data);
+  } else if (isTag(node)) {
+    var children = recursive ? cloneChildren(node.children) : [];
+    var clone_1 = new Element(node.name, __assign({}, node.attribs), children);
+    children.forEach(function (child) {
+      return child.parent = clone_1;
+    });
+    if (node.namespace != null) {
+      clone_1.namespace = node.namespace;
+    }
+    if (node["x-attribsNamespace"]) {
+      clone_1["x-attribsNamespace"] = __assign({}, node["x-attribsNamespace"]);
+    }
+    if (node["x-attribsPrefix"]) {
+      clone_1["x-attribsPrefix"] = __assign({}, node["x-attribsPrefix"]);
+    }
+    result = clone_1;
+  } else if (isCDATA(node)) {
+    var children = recursive ? cloneChildren(node.children) : [];
+    var clone_2 = new CDATA(children);
+    children.forEach(function (child) {
+      return child.parent = clone_2;
+    });
+    result = clone_2;
+  } else if (isDocument(node)) {
+    var children = recursive ? cloneChildren(node.children) : [];
+    var clone_3 = new Document(children);
+    children.forEach(function (child) {
+      return child.parent = clone_3;
+    });
+    if (node["x-mode"]) {
+      clone_3["x-mode"] = node["x-mode"];
+    }
+    result = clone_3;
+  } else if (isDirective(node)) {
+    var instruction = new ProcessingInstruction(node.name, node.data);
+    if (node["x-name"] != null) {
+      instruction["x-name"] = node["x-name"];
+      instruction["x-publicId"] = node["x-publicId"];
+      instruction["x-systemId"] = node["x-systemId"];
+    }
+    result = instruction;
+  } else {
+    throw new Error("Not implemented yet: ".concat(node.type));
+  }
+  result.startIndex = node.startIndex;
+  result.endIndex = node.endIndex;
+  if (node.sourceCodeLocation != null) {
+    result.sourceCodeLocation = node.sourceCodeLocation;
+  }
+  return result;
+}
+exports.cloneNode = cloneNode;
+function cloneChildren(childs) {
+  var children = childs.map(function (child) {
+    return cloneNode(child, true);
+  });
+  for (var i = 1; i < children.length; i++) {
+    children[i].prev = children[i - 1];
+    children[i - 1].next = children[i];
+  }
+  return children;
+}

+ 203 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/entities/decode.js

@@ -0,0 +1,203 @@
+'use strict';
+var __importDefault =
+    (this && this.__importDefault) ||
+    function (mod) {
+        return mod && mod.__esModule
+            ? mod
+            : {
+                  default: mod
+              };
+    };
+Object.defineProperty(exports, '__esModule', {
+    value: true
+});
+exports.decodeXML =
+    exports.decodeHTMLStrict =
+    exports.decodeHTML =
+    exports.determineBranch =
+    exports.BinTrieFlags =
+    exports.fromCodePoint =
+    exports.replaceCodePoint =
+    exports.decodeCodePoint =
+    exports.xmlDecodeTree =
+    exports.htmlDecodeTree =
+        void 0;
+var decode_data_html_js_1 = __importDefault(require('./generated/decode-data-html.js'));
+exports.htmlDecodeTree = decode_data_html_js_1.default;
+var decode_data_xml_js_1 = __importDefault(require('./generated/decode-data-xml.js'));
+exports.xmlDecodeTree = decode_data_xml_js_1.default;
+var decode_codepoint_js_1 = __importDefault(require('./decode_codepoint.js'));
+exports.decodeCodePoint = decode_codepoint_js_1.default;
+var decode_codepoint_js_2 = require('./decode_codepoint.js');
+Object.defineProperty(exports, 'replaceCodePoint', {
+    enumerable: true,
+    get: function () {
+        return decode_codepoint_js_2.replaceCodePoint;
+    }
+});
+Object.defineProperty(exports, 'fromCodePoint', {
+    enumerable: true,
+    get: function () {
+        return decode_codepoint_js_2.fromCodePoint;
+    }
+});
+var CharCodes;
+(function (CharCodes) {
+    CharCodes[(CharCodes['NUM'] = 35)] = 'NUM';
+    CharCodes[(CharCodes['SEMI'] = 59)] = 'SEMI';
+    CharCodes[(CharCodes['ZERO'] = 48)] = 'ZERO';
+    CharCodes[(CharCodes['NINE'] = 57)] = 'NINE';
+    CharCodes[(CharCodes['LOWER_A'] = 97)] = 'LOWER_A';
+    CharCodes[(CharCodes['LOWER_F'] = 102)] = 'LOWER_F';
+    CharCodes[(CharCodes['LOWER_X'] = 120)] = 'LOWER_X';
+    /** Bit that needs to be set to convert an upper case ASCII character to lower case */
+    CharCodes[(CharCodes['To_LOWER_BIT'] = 32)] = 'To_LOWER_BIT';
+})(CharCodes || (CharCodes = {}));
+var BinTrieFlags;
+(function (BinTrieFlags) {
+    BinTrieFlags[(BinTrieFlags['VALUE_LENGTH'] = 49152)] = 'VALUE_LENGTH';
+    BinTrieFlags[(BinTrieFlags['BRANCH_LENGTH'] = 16256)] = 'BRANCH_LENGTH';
+    BinTrieFlags[(BinTrieFlags['JUMP_TABLE'] = 127)] = 'JUMP_TABLE';
+})((BinTrieFlags = exports.BinTrieFlags || (exports.BinTrieFlags = {})));
+function getDecoder(decodeTree) {
+    return function decodeHTMLBinary(str, strict) {
+        var ret = '';
+        var lastIdx = 0;
+        var strIdx = 0;
+        while ((strIdx = str.indexOf('&', strIdx)) >= 0) {
+            ret += str.slice(lastIdx, strIdx);
+            lastIdx = strIdx;
+            // Skip the "&"
+            strIdx += 1;
+            // If we have a numeric entity, handle this separately.
+            if (str.charCodeAt(strIdx) === CharCodes.NUM) {
+                // Skip the leading "&#". For hex entities, also skip the leading "x".
+                var start = strIdx + 1;
+                var base = 10;
+                var cp = str.charCodeAt(start);
+                if ((cp | CharCodes.To_LOWER_BIT) === CharCodes.LOWER_X) {
+                    base = 16;
+                    strIdx += 1;
+                    start += 1;
+                }
+                do cp = str.charCodeAt(++strIdx);
+                while (
+                    (cp >= CharCodes.ZERO && cp <= CharCodes.NINE) ||
+                    (base === 16 && (cp | CharCodes.To_LOWER_BIT) >= CharCodes.LOWER_A && (cp | CharCodes.To_LOWER_BIT) <= CharCodes.LOWER_F)
+                );
+                if (start !== strIdx) {
+                    var entity = str.substring(start, strIdx);
+                    var parsed = parseInt(entity, base);
+                    if (str.charCodeAt(strIdx) === CharCodes.SEMI) {
+                        strIdx += 1;
+                    } else if (strict) {
+                        continue;
+                    }
+                    ret += (0, decode_codepoint_js_1.default)(parsed);
+                    lastIdx = strIdx;
+                }
+                continue;
+            }
+            var resultIdx = 0;
+            var excess = 1;
+            var treeIdx = 0;
+            var current = decodeTree[treeIdx];
+            for (; strIdx < str.length; strIdx++, excess++) {
+                treeIdx = determineBranch(decodeTree, current, treeIdx + 1, str.charCodeAt(strIdx));
+                if (treeIdx < 0) {
+                    break;
+                }
+                current = decodeTree[treeIdx];
+                var masked = current & BinTrieFlags.VALUE_LENGTH;
+                // If the branch is a value, store it and continue
+                if (masked) {
+                    // If we have a legacy entity while parsing strictly, just skip the number of bytes
+                    if (!strict || str.charCodeAt(strIdx) === CharCodes.SEMI) {
+                        resultIdx = treeIdx;
+                        excess = 0;
+                    }
+                    // The mask is the number of bytes of the value, including the current byte.
+                    var valueLength = (masked >> 14) - 1;
+                    if (valueLength === 0) {
+                        break;
+                    }
+                    treeIdx += valueLength;
+                }
+            }
+            if (resultIdx !== 0) {
+                var valueLength = (decodeTree[resultIdx] & BinTrieFlags.VALUE_LENGTH) >> 14;
+                ret +=
+                    valueLength === 1
+                        ? String.fromCharCode(decodeTree[resultIdx] & ~BinTrieFlags.VALUE_LENGTH)
+                        : valueLength === 2
+                        ? String.fromCharCode(decodeTree[resultIdx + 1])
+                        : String.fromCharCode(decodeTree[resultIdx + 1], decodeTree[resultIdx + 2]);
+                lastIdx = strIdx - excess + 1;
+            }
+        }
+        return ret + str.slice(lastIdx);
+    };
+}
+function determineBranch(decodeTree, current, nodeIdx, char) {
+    var branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;
+    var jumpOffset = current & BinTrieFlags.JUMP_TABLE;
+    // Case 1: Single branch encoded in jump offset
+    if (branchCount === 0) {
+        return jumpOffset !== 0 && char === jumpOffset ? nodeIdx : -1;
+    }
+    // Case 2: Multiple branches encoded in jump table
+    if (jumpOffset) {
+        var value = char - jumpOffset;
+        return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIdx + value] - 1;
+    }
+    // Case 3: Multiple branches encoded in dictionary
+    // Binary search for the character.
+    var lo = nodeIdx;
+    var hi = lo + branchCount - 1;
+    while (lo <= hi) {
+        var mid = (lo + hi) >>> 1;
+        var midVal = decodeTree[mid];
+        if (midVal < char) {
+            lo = mid + 1;
+        } else if (midVal > char) {
+            hi = mid - 1;
+        } else {
+            return decodeTree[mid + branchCount];
+        }
+    }
+    return -1;
+}
+exports.determineBranch = determineBranch;
+var htmlDecoder = getDecoder(decode_data_html_js_1.default);
+var xmlDecoder = getDecoder(decode_data_xml_js_1.default);
+/**
+ * Decodes an HTML string, allowing for entities not terminated by a semi-colon.
+ *
+ * @param str The string to decode.
+ * @returns The decoded string.
+ */
+function decodeHTML(str) {
+    return htmlDecoder(str, false);
+}
+exports.decodeHTML = decodeHTML;
+/**
+ * Decodes an HTML string, requiring all entities to be terminated by a semi-colon.
+ *
+ * @param str The string to decode.
+ * @returns The decoded string.
+ */
+function decodeHTMLStrict(str) {
+    return htmlDecoder(str, true);
+}
+exports.decodeHTMLStrict = decodeHTMLStrict;
+/**
+ * Decodes an XML string, requiring all entities to be terminated by a semi-colon.
+ *
+ * @param str The string to decode.
+ * @returns The decoded string.
+ */
+function decodeXML(str) {
+    return xmlDecoder(str, true);
+}
+exports.decodeXML = decodeXML;
+//# sourceMappingURL=decode.js.map

+ 63 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/entities/decode_codepoint.js

@@ -0,0 +1,63 @@
+'use strict';
+// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134
+var _a;
+Object.defineProperty(exports, '__esModule', {
+    value: true
+});
+exports.replaceCodePoint = exports.fromCodePoint = void 0;
+var decodeMap = new Map([
+    [0, 65533],
+    [128, 8364],
+    [130, 8218],
+    [131, 402],
+    [132, 8222],
+    [133, 8230],
+    [134, 8224],
+    [135, 8225],
+    [136, 710],
+    [137, 8240],
+    [138, 352],
+    [139, 8249],
+    [140, 338],
+    [142, 381],
+    [145, 8216],
+    [146, 8217],
+    [147, 8220],
+    [148, 8221],
+    [149, 8226],
+    [150, 8211],
+    [151, 8212],
+    [152, 732],
+    [153, 8482],
+    [154, 353],
+    [155, 8250],
+    [156, 339],
+    [158, 382],
+    [159, 376]
+]);
+exports.fromCodePoint =
+    (_a = String.fromCodePoint) !== null && _a !== void 0
+        ? _a
+        : function (codePoint) {
+              var output = '';
+              if (codePoint > 65535) {
+                  codePoint -= 65536;
+                  output += String.fromCharCode(((codePoint >>> 10) & 1023) | 55296);
+                  codePoint = 56320 | (codePoint & 1023);
+              }
+              output += String.fromCharCode(codePoint);
+              return output;
+          };
+function replaceCodePoint(codePoint) {
+    var _a;
+    if ((codePoint >= 55296 && codePoint <= 57343) || codePoint > 1114111) {
+        return 65533;
+    }
+    return (_a = decodeMap.get(codePoint)) !== null && _a !== void 0 ? _a : codePoint;
+}
+exports.replaceCodePoint = replaceCodePoint;
+function decodeCodePoint(codePoint) {
+    return (0, exports.fromCodePoint)(replaceCodePoint(codePoint));
+}
+exports.default = decodeCodePoint;
+//# sourceMappingURL=decode_codepoint.js.map

+ 80 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/entities/encode.js

@@ -0,0 +1,80 @@
+'use strict';
+var __importDefault =
+    (this && this.__importDefault) ||
+    function (mod) {
+        return mod && mod.__esModule
+            ? mod
+            : {
+                  default: mod
+              };
+    };
+Object.defineProperty(exports, '__esModule', {
+    value: true
+});
+exports.encodeNonAsciiHTML = exports.encodeHTML = void 0;
+var encode_html_js_1 = __importDefault(require('./generated/encode-html.js'));
+var escape_js_1 = require('./escape.js');
+var htmlReplacer = /[\t\n!-,./:-@[-`\f{-}$\x80-\uFFFF]/g;
+/**
+ * Encodes all characters in the input using HTML entities. This includes
+ * characters that are valid ASCII characters in HTML documents, such as `#`.
+ *
+ * To get a more compact output, consider using the `encodeNonAsciiHTML`
+ * function, which will only encode characters that are not valid in HTML
+ * documents, as well as non-ASCII characters.
+ *
+ * If a character has no equivalent entity, a numeric hexadecimal reference
+ * (eg. `&#xfc;`) will be used.
+ */
+function encodeHTML(data) {
+    return encodeHTMLTrieRe(htmlReplacer, data);
+}
+exports.encodeHTML = encodeHTML;
+/**
+ * Encodes all non-ASCII characters, as well as characters not valid in HTML
+ * documents using HTML entities. This function will not encode characters that
+ * are valid in HTML documents, such as `#`.
+ *
+ * If a character has no equivalent entity, a numeric hexadecimal reference
+ * (eg. `&#xfc;`) will be used.
+ */
+function encodeNonAsciiHTML(data) {
+    return encodeHTMLTrieRe(escape_js_1.xmlReplacer, data);
+}
+exports.encodeNonAsciiHTML = encodeNonAsciiHTML;
+function encodeHTMLTrieRe(regExp, str) {
+    var ret = '';
+    var lastIdx = 0;
+    var match;
+    while ((match = regExp.exec(str)) !== null) {
+        var i = match.index;
+        ret += str.substring(lastIdx, i);
+        var char = str.charCodeAt(i);
+        var next = encode_html_js_1.default.get(char);
+        if (typeof next === 'object') {
+            // We are in a branch. Try to match the next char.
+            if (i + 1 < str.length) {
+                var nextChar = str.charCodeAt(i + 1);
+                var value = typeof next.n === 'number' ? (next.n === nextChar ? next.o : undefined) : next.n.get(nextChar);
+                if (value !== undefined) {
+                    ret += value;
+                    lastIdx = regExp.lastIndex += 1;
+                    continue;
+                }
+            }
+            next = next.v;
+        }
+        // We might have a tree node without a value; skip and use a numeric entitiy.
+        if (next !== undefined) {
+            ret += next;
+            lastIdx = i + 1;
+        } else {
+            var cp = (0, escape_js_1.getCodePoint)(str, i);
+            ret += '&#x'.concat(cp.toString(16), ';');
+            // Increase by 1 if we have a surrogate pair
+            lastIdx = regExp.lastIndex += Number(cp !== char);
+        }
+    }
+    return ret + str.substr(lastIdx);
+}
+//# sourceMappingURL=encode.js.map

+ 115 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/entities/escape.js

@@ -0,0 +1,115 @@
+'use strict';
+Object.defineProperty(exports, '__esModule', {
+    value: true
+});
+exports.escapeText = exports.escapeAttribute = exports.escapeUTF8 = exports.escape = exports.encodeXML = exports.getCodePoint = exports.xmlReplacer = void 0;
+exports.xmlReplacer = /["&'<>$\x80-\uFFFF]/g;
+var xmlCodeMap = new Map([
+    [34, '&quot;'],
+    [38, '&amp;'],
+    [39, '&apos;'],
+    [60, '&lt;'],
+    [62, '&gt;']
+]);
+// For compatibility with node < 4, we wrap `codePointAt`
+exports.getCodePoint =
+    String.prototype.codePointAt != null
+        ? function (str, index) {
+              return str.codePointAt(index);
+          }
+        : // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+          function (c, index) {
+              return (c.charCodeAt(index) & 64512) === 55296 ? (c.charCodeAt(index) - 55296) * 1024 + c.charCodeAt(index + 1) - 56320 + 65536 : c.charCodeAt(index);
+          };
+/**
+ * Encodes all non-ASCII characters, as well as characters not valid in XML
+ * documents using XML entities.
+ *
+ * If a character has no equivalent entity, a
+ * numeric hexadecimal reference (eg. `&#xfc;`) will be used.
+ */
+function encodeXML(str) {
+    var ret = '';
+    var lastIdx = 0;
+    var match;
+    while ((match = exports.xmlReplacer.exec(str)) !== null) {
+        var i = match.index;
+        var char = str.charCodeAt(i);
+        var next = xmlCodeMap.get(char);
+        if (next !== undefined) {
+            ret += str.substring(lastIdx, i) + next;
+            lastIdx = i + 1;
+        } else {
+            ret += ''.concat(str.substring(lastIdx, i), '&#x').concat((0, exports.getCodePoint)(str, i).toString(16), ';');
+            // Increase by 1 if we have a surrogate pair
+            lastIdx = exports.xmlReplacer.lastIndex += Number((char & 64512) === 55296);
+        }
+    }
+    return ret + str.substr(lastIdx);
+}
+exports.encodeXML = encodeXML;
+/**
+ * Encodes all non-ASCII characters, as well as characters not valid in XML
+ * documents using numeric hexadecimal reference (eg. `&#xfc;`).
+ *
+ * Have a look at `escapeUTF8` if you want a more concise output at the expense
+ * of reduced transportability.
+ *
+ * @param data String to escape.
+ */
+exports.escape = encodeXML;
+function getEscaper(regex, map) {
+    return function escape(data) {
+        var match;
+        var lastIdx = 0;
+        var result = '';
+        while ((match = regex.exec(data))) {
+            if (lastIdx !== match.index) {
+                result += data.substring(lastIdx, match.index);
+            }
+            // We know that this chararcter will be in the map.
+            result += map.get(match[0].charCodeAt(0));
+            // Every match will be of length 1
+            lastIdx = match.index + 1;
+        }
+        return result + data.substring(lastIdx);
+    };
+}
+/**
+ * Encodes all characters not valid in XML documents using XML entities.
+ *
+ * Note that the output will be character-set dependent.
+ *
+ * @param data String to escape.
+ */
+exports.escapeUTF8 = getEscaper(/[&<>'"]/g, xmlCodeMap);
+/**
+ * Encodes all characters that have to be escaped in HTML attributes,
+ * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.
+ *
+ * @param data String to escape.
+ */
+exports.escapeAttribute = getEscaper(
+    /["&\u00A0]/g,
+    new Map([
+        [34, '&quot;'],
+        [38, '&amp;'],
+        [160, '&nbsp;']
+    ])
+);
+/**
+ * Encodes all characters that have to be escaped in HTML text,
+ * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.
+ *
+ * @param data String to escape.
+ */
+exports.escapeText = getEscaper(
+    /[&<>\u00A0]/g,
+    new Map([
+        [38, '&amp;'],
+        [60, '&lt;'],
+        [62, '&gt;'],
+        [160, '&nbsp;']
+    ])
+);
+//# sourceMappingURL=escape.js.map

File diff suppressed because it is too large
+ 12 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/entities/generated/decode-data-html.js


+ 12 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/entities/generated/decode-data-xml.js

@@ -0,0 +1,12 @@
+'use strict';
+// Generated using scripts/write-decode-map.ts
+Object.defineProperty(exports, '__esModule', {
+    value: true
+});
+exports.default = new Uint16Array(
+    // prettier-ignore
+    "\u0200aglq\t\x15\x18\x1B\u026D\x0F\0\0\x12p;\u4026os;\u4027t;\u403Et;\u403Cuot;\u4022".split("").map(function (c) {
+  return c.charCodeAt(0);
+})
+);
+//# sourceMappingURL=decode-data-xml.js.map

File diff suppressed because it is too large
+ 265 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/entities/generated/encode-html.js


+ 271 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/entities/index.js

@@ -0,0 +1,271 @@
+'use strict';
+Object.defineProperty(exports, '__esModule', {
+    value: true
+});
+exports.decodeXMLStrict =
+    exports.decodeHTML5Strict =
+    exports.decodeHTML4Strict =
+    exports.decodeHTML5 =
+    exports.decodeHTML4 =
+    exports.decodeHTMLStrict =
+    exports.decodeHTML =
+    exports.decodeXML =
+    exports.encodeHTML5 =
+    exports.encodeHTML4 =
+    exports.encodeNonAsciiHTML =
+    exports.encodeHTML =
+    exports.escapeText =
+    exports.escapeAttribute =
+    exports.escapeUTF8 =
+    exports.escape =
+    exports.encodeXML =
+    exports.encode =
+    exports.decodeStrict =
+    exports.decode =
+    exports.EncodingMode =
+    exports.DecodingMode =
+    exports.EntityLevel =
+        void 0;
+var decode_js_1 = require('./decode.js');
+var encode_js_1 = require('./encode.js');
+var escape_js_1 = require('./escape.js');
+/** The level of entities to support. */
+var EntityLevel;
+(function (EntityLevel) {
+    /** Support only XML entities. */
+    EntityLevel[(EntityLevel['XML'] = 0)] = 'XML';
+    /** Support HTML entities, which are a superset of XML entities. */
+    EntityLevel[(EntityLevel['HTML'] = 1)] = 'HTML';
+})((EntityLevel = exports.EntityLevel || (exports.EntityLevel = {})));
+/** Determines whether some entities are allowed to be written without a trailing `;`. */
+var DecodingMode;
+(function (DecodingMode) {
+    /** Support legacy HTML entities. */
+    DecodingMode[(DecodingMode['Legacy'] = 0)] = 'Legacy';
+    /** Do not support legacy HTML entities. */
+    DecodingMode[(DecodingMode['Strict'] = 1)] = 'Strict';
+})((DecodingMode = exports.DecodingMode || (exports.DecodingMode = {})));
+var EncodingMode;
+(function (EncodingMode) {
+    /**
+     * The output is UTF-8 encoded. Only characters that need escaping within
+     * XML will be escaped.
+     */
+    EncodingMode[(EncodingMode['UTF8'] = 0)] = 'UTF8';
+    /**
+     * The output consists only of ASCII characters. Characters that need
+     * escaping within HTML, and characters that aren't ASCII characters will
+     * be escaped.
+     */
+    EncodingMode[(EncodingMode['ASCII'] = 1)] = 'ASCII';
+    /**
+     * Encode all characters that have an equivalent entity, as well as all
+     * characters that are not ASCII characters.
+     */
+    EncodingMode[(EncodingMode['Extensive'] = 2)] = 'Extensive';
+    /**
+     * Encode all characters that have to be escaped in HTML attributes,
+     * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.
+     */
+    EncodingMode[(EncodingMode['Attribute'] = 3)] = 'Attribute';
+    /**
+     * Encode all characters that have to be escaped in HTML text,
+     * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.
+     */
+    EncodingMode[(EncodingMode['Text'] = 4)] = 'Text';
+})((EncodingMode = exports.EncodingMode || (exports.EncodingMode = {})));
+/**
+ * Decodes a string with entities.
+ *
+ * @param data String to decode.
+ * @param options Decoding options.
+ */
+function decode(data, options) {
+    if (options === void 0) {
+        options = EntityLevel.XML;
+    }
+    var opts =
+        typeof options === 'number'
+            ? {
+                  level: options
+              }
+            : options;
+    if (opts.level === EntityLevel.HTML) {
+        if (opts.mode === DecodingMode.Strict) {
+            return (0, decode_js_1.decodeHTMLStrict)(data);
+        }
+        return (0, decode_js_1.decodeHTML)(data);
+    }
+    return (0, decode_js_1.decodeXML)(data);
+}
+exports.decode = decode;
+/**
+ * Decodes a string with entities. Does not allow missing trailing semicolons for entities.
+ *
+ * @param data String to decode.
+ * @param options Decoding options.
+ * @deprecated Use `decode` with the `mode` set to `Strict`.
+ */
+function decodeStrict(data, options) {
+    if (options === void 0) {
+        options = EntityLevel.XML;
+    }
+    var opts =
+        typeof options === 'number'
+            ? {
+                  level: options
+              }
+            : options;
+    if (opts.level === EntityLevel.HTML) {
+        if (opts.mode === DecodingMode.Legacy) {
+            return (0, decode_js_1.decodeHTML)(data);
+        }
+        return (0, decode_js_1.decodeHTMLStrict)(data);
+    }
+    return (0, decode_js_1.decodeXML)(data);
+}
+exports.decodeStrict = decodeStrict;
+/**
+ * Encodes a string with entities.
+ *
+ * @param data String to encode.
+ * @param options Encoding options.
+ */
+function encode(data, options) {
+    if (options === void 0) {
+        options = EntityLevel.XML;
+    }
+    var opts =
+        typeof options === 'number'
+            ? {
+                  level: options
+              }
+            : options;
+    // Mode `UTF8` just escapes XML entities
+    if (opts.mode === EncodingMode.UTF8) {
+        return (0, escape_js_1.escapeUTF8)(data);
+    }
+    if (opts.mode === EncodingMode.Attribute) {
+        return (0, escape_js_1.escapeAttribute)(data);
+    }
+    if (opts.mode === EncodingMode.Text) {
+        return (0, escape_js_1.escapeText)(data);
+    }
+    if (opts.level === EntityLevel.HTML) {
+        if (opts.mode === EncodingMode.ASCII) {
+            return (0, encode_js_1.encodeNonAsciiHTML)(data);
+        }
+        return (0, encode_js_1.encodeHTML)(data);
+    }
+    // ASCII and Extensive are equivalent
+    return (0, escape_js_1.encodeXML)(data);
+}
+exports.encode = encode;
+var escape_js_2 = require('./escape.js');
+Object.defineProperty(exports, 'encodeXML', {
+    enumerable: true,
+    get: function () {
+        return escape_js_2.encodeXML;
+    }
+});
+Object.defineProperty(exports, 'escape', {
+    enumerable: true,
+    get: function () {
+        return escape_js_2.escape;
+    }
+});
+Object.defineProperty(exports, 'escapeUTF8', {
+    enumerable: true,
+    get: function () {
+        return escape_js_2.escapeUTF8;
+    }
+});
+Object.defineProperty(exports, 'escapeAttribute', {
+    enumerable: true,
+    get: function () {
+        return escape_js_2.escapeAttribute;
+    }
+});
+Object.defineProperty(exports, 'escapeText', {
+    enumerable: true,
+    get: function () {
+        return escape_js_2.escapeText;
+    }
+});
+var encode_js_2 = require('./encode.js');
+Object.defineProperty(exports, 'encodeHTML', {
+    enumerable: true,
+    get: function () {
+        return encode_js_2.encodeHTML;
+    }
+});
+Object.defineProperty(exports, 'encodeNonAsciiHTML', {
+    enumerable: true,
+    get: function () {
+        return encode_js_2.encodeNonAsciiHTML;
+    }
+});
+// Legacy aliases (deprecated)
+Object.defineProperty(exports, 'encodeHTML4', {
+    enumerable: true,
+    get: function () {
+        return encode_js_2.encodeHTML;
+    }
+});
+Object.defineProperty(exports, 'encodeHTML5', {
+    enumerable: true,
+    get: function () {
+        return encode_js_2.encodeHTML;
+    }
+});
+var decode_js_2 = require('./decode.js');
+Object.defineProperty(exports, 'decodeXML', {
+    enumerable: true,
+    get: function () {
+        return decode_js_2.decodeXML;
+    }
+});
+Object.defineProperty(exports, 'decodeHTML', {
+    enumerable: true,
+    get: function () {
+        return decode_js_2.decodeHTML;
+    }
+});
+Object.defineProperty(exports, 'decodeHTMLStrict', {
+    enumerable: true,
+    get: function () {
+        return decode_js_2.decodeHTMLStrict;
+    }
+});
+// Legacy aliases (deprecated)
+Object.defineProperty(exports, 'decodeHTML4', {
+    enumerable: true,
+    get: function () {
+        return decode_js_2.decodeHTML;
+    }
+});
+Object.defineProperty(exports, 'decodeHTML5', {
+    enumerable: true,
+    get: function () {
+        return decode_js_2.decodeHTML;
+    }
+});
+Object.defineProperty(exports, 'decodeHTML4Strict', {
+    enumerable: true,
+    get: function () {
+        return decode_js_2.decodeHTMLStrict;
+    }
+});
+Object.defineProperty(exports, 'decodeHTML5Strict', {
+    enumerable: true,
+    get: function () {
+        return decode_js_2.decodeHTMLStrict;
+    }
+});
+Object.defineProperty(exports, 'decodeXMLStrict', {
+    enumerable: true,
+    get: function () {
+        return decode_js_2.decodeXML;
+    }
+});
+//# sourceMappingURL=index.js.map

+ 8 - 0
components/agent-ui/markdownPreview/towxml/parse/parse2/index.js

@@ -0,0 +1,8 @@
+var DomHandler = require('./domhandler/index.js');
+var Parser = require('./Parser.js');
+function parseDocument(data, options) {
+    var handler = new DomHandler(undefined, options);
+    new Parser(handler, options).end(data);
+    return handler.root.children;
+}
+module.exports = parseDocument;

+ 405 - 0
components/agent-ui/markdownPreview/towxml/style/main.css

@@ -0,0 +1,405 @@
+/*正文样式*/
+.h2w {
+    font-family: PingFang SC, Lantinghei SC, Microsoft Yahei, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif;
+    /* font-weight:300; */
+    font-size: 32rpx;
+    line-height: 1.8;
+    word-wrap: break-word;
+    word-break: normal;
+    text-align: justify;
+}
+
+.h2w__main {
+    /* margin: 0 40rpx 40rpx 40rpx; */
+}
+
+/**标题**/
+.h2w__h1,
+.h2w__h2,
+.h2w__h3,
+.h2w__h4,
+.h2w__h5,
+.h2w__h6 {
+    font-weight: bold;
+}
+
+/**设置行间元素样式**/
+.h2w__span,
+.h2w__b,
+.h2w__strong,
+.h2w__i,
+.h2w__em,
+.h2w__code,
+.h2w__sub,
+.h2w__sup,
+.h2w__g-emoji,
+.h2w__mark,
+.h2w__u,
+.h2w__navigatorParent,
+.h2w__ins {
+    display: inline;
+}
+
+.h2w__h1 {
+    border-bottom-style: double;
+    border-bottom-width: 6rpx;
+    font-size: 42rpx;
+    padding-bottom: 10rpx;
+    margin-bottom: 20rpx;
+}
+
+.h2w__h2 {
+    border-bottom-style: solid;
+    border-bottom-width: 1rpx;
+    font-size: 40rpx;
+    padding-bottom: 8rpx;
+    margin-bottom: 18rpx;
+}
+
+.h2w__h3 {
+    font-size: 38rpx;
+    padding-bottom: 6rpx;
+    margin-bottom: 12rpx;
+}
+
+.h2w__h4 {
+    font-size: 36rpx;
+    padding-bottom: 4rpx;
+    margin-bottom: 12rpx;
+}
+
+.h2w__h5 {
+    font-size: 34rpx;
+    padding-bottom: 2rpx;
+    margin-bottom: 12rpx;
+}
+
+.h2w__h6 {
+    margin-bottom: 12rpx;
+}
+
+/**组件父级容器**/
+.h2w__textParent,
+.h2w__viewParent {
+    display: inline;
+}
+.h2w__rich-textParent {
+    overflow-x: auto;
+}
+
+/**表格**/
+.h2w__tableParent {
+    width: 100%;
+    overflow-x: auto;
+}
+
+.h2w__table {
+    width: 99.99%;
+    border-collapse: collapse;
+    border-spacing: 0;
+    display: table;
+    margin-bottom: 40rpx;
+    white-space: nowrap;
+}
+
+.h2w__table .h2w__tr:nth-child(2n) {
+    background-color: red;
+}
+
+.h2w__colgroup {
+    display: table-column-group;
+}
+
+.h2w__col {
+    display: table-column;
+}
+
+.h2w__thead {
+    display: table-header-group;
+}
+
+.h2w__tbody {
+    display: table-row-group;
+}
+
+.h2w__tfoot {
+    display: table-footer-group;
+}
+
+.h2w__tr {
+    display: table-row;
+}
+
+.h2w__th,
+.h2w__td {
+    padding: 8rpx 16rpx;
+    font-size: 28rpx;
+    border-width: 1rpx;
+    border-style: solid;
+    display: table-cell;
+}
+
+.h2w__th {
+    font-weight: bold;
+}
+
+/**代码块**/
+.h2w__pre {
+    /*white-space:nowrap;*/
+    padding: 10rpx 14rpx 10rpx 10rpx;
+    font-size: 28rpx;
+    word-break: normal;
+    border-width: 1rpx;
+    border-style: solid;
+    margin-bottom: 40rpx;
+    white-space: nowrap;
+    overflow-x: auto;
+    tab-size: 4;
+}
+.h2w__pre .h2w__p {
+    margin: 0;
+}
+
+.h2w__pre .h2w__code {
+    padding: 0;
+    border: 0;
+    font-size: 100%;
+}
+
+.h2w__pre,
+.h2w__code {
+    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace, 'STHeitiTC-Light', 'Microsoft YaHei Light', -apple-system, system-ui, BlinkMacSystemFont;
+}
+
+.h2w__code {
+    padding: 4rpx 8rpx;
+    margin: 0 4rpx;
+    border-width: 1rpx;
+    border-style: solid;
+    border-radius: 8rpx;
+    font-size: 80%;
+    overflow-x: auto;
+}
+
+.h2w__pre .h2w__span,
+.h2w__pre .h2w__a,
+.h2w__pre .h2w__span,
+.h2w__pre .h2w__b,
+.h2w__pre .h2w__strong,
+.h2w__pre .h2w__i,
+.h2w__pre .h2w__em {
+    display: inline;
+}
+
+.h2w__pre {
+    white-space: pre;
+    display: block;
+}
+
+.h2w__pre .h2w__code {
+    white-space: nowrap;
+    /* width: 9999px; */
+    display: block;
+    font-size: 80%;
+}
+
+/**列表**/
+.h2w__ul,
+.h2w__ol {
+    margin-bottom: 40rpx;
+    padding-left: 1rem;
+}
+
+.h2w__ul .h2w__ol,
+.h2w__ol .h2w__ul {
+    margin-bottom: 0;
+}
+
+.h2w__li {
+    display: list-item;
+}
+
+/**todo**/
+.h2w__todogroup {
+    margin-bottom: 40rpx;
+}
+
+.h2w__todogroup .h2w__todogroup {
+    padding-left: 1.6rem;
+}
+
+/**一级ol样式**/
+.h2w__ol {
+    list-style-type: decimal;
+}
+
+/**二级ol样式**/
+.h2w__ul .h2w__ol,
+.h2w__ol .h2w__ol {
+    list-style-type: lower-roman;
+}
+
+/**三级ol样式**/
+.h2w__ul .h2w__ul .h2w__ol,
+.h2w__ul .h2w__ol .h2w__ol,
+.h2w__ol .h2w__ul .h2w__ol,
+.h2w__ol .h2w__ol .h2w__ol {
+    list-style-type: lower-alpha;
+}
+
+/**一级ul样式**/
+.h2w__ul {
+    list-style-type: disc;
+}
+
+/**二级ul样式**/
+.h2w__ul .h2w__ul,
+.h2w__ol .h2w__ul {
+    list-style-type: circle;
+}
+
+/**三级样式**/
+.h2w__ol .h2w__ol .h2w__ul,
+.h2w__ol .h2w__ul .h2w__ul,
+.h2w__ul .h2w__ol .h2w__ul,
+.h2w__ul .h2w__ul .h2w__ul {
+    list-style-type: square;
+}
+
+/**块元素**/
+.h2w__p {
+    margin: 20rpx 0 20rpx 0;
+}
+
+.h2w__blockquote {
+    border-left-width: 8rpx;
+    border-left-style: solid;
+    padding: 0 20rpx;
+}
+
+/**内连元素**/
+.h2w__a,
+.h2w__span,
+.h2w__s,
+.h2w__b,
+.h2w__strong,
+.h2w__i,
+.h2w__em {
+    display: inline;
+}
+
+.h2w__b,
+.h2w__strong {
+    font-weight: bold;
+}
+
+.h2w__i,
+.h2w__em {
+    font-style: italic;
+}
+
+/**文本删除线**/
+.h2w__s,
+.h2w__strike,
+.h2w__del {
+    text-decoration: line-through;
+}
+
+/**文本下划线**/
+.h2w__ins,
+.h2w__u {
+    text-decoration: underline;
+}
+
+/**链接**/
+.h2w__a {
+    margin: 0 8rpx;
+    border-bottom-width: 1rpx;
+    border-bottom-style: solid;
+    line-height: 1;
+}
+
+.h2w__hr {
+    height: 8rpx;
+    margin: 40rpx 0;
+}
+
+/**荧光标记**/
+.h2w__mark {
+    border-radius: 4rpx;
+}
+
+/**上标、下标**/
+.h2w__sup,
+.h2w__sub {
+    font-size: 75%;
+    position: relative;
+}
+
+.h2w__sup {
+    top: -0.5em;
+}
+
+.h2w__sub {
+    bottom: -0.25em;
+}
+
+/**emoji表情**/
+.h2w__g-emoji {
+    margin: 0 0.1em;
+    font-family: 'Apple Color Emoji', 'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol';
+}
+
+/**内置元素**/
+image,
+video {
+    max-width: 100%;
+}
+
+video {
+    width: 100%;
+    margin: 10rpx auto;
+}
+
+image {
+    height: auto;
+    vertical-align: middle;
+}
+
+video {
+    height: 220px;
+    font-size: 0;
+}
+
+.h2w__latex--line {
+    margin: 4rpx 8rpx;
+    vertical-align: middle;
+}
+.h2w__latex--block {
+    display: block;
+    margin: 1em auto;
+}
+
+.h2w__yuml {
+    display: block;
+}
+
+.h2w__yumlBox {
+    width: 100%;
+    overflow-x: auto;
+}
+.h2w__yumlView {
+    margin: 0 auto;
+    padding-bottom: 40rpx;
+}
+
+/**代码行号**/
+.h2w__lineNum {
+    text-align: right;
+    float: left;
+    padding: 0;
+    margin: 0 1em 0 0;
+}
+.h2w__lineNumLine {
+    list-style: none;
+}

+ 72 - 0
components/agent-ui/markdownPreview/towxml/style/theme/dark.css

@@ -0,0 +1,72 @@
+@import '../../parse/highlight/style/monokai.css'; /*正文样式*/
+.h2w-dark {
+    color: #ddd;
+    background-color: #000;
+}
+
+/**标题**/
+.h2w-dark .h2w__h1,
+.h2w-dark .h2w__h2 {
+    border-color: #3d3d3d;
+}
+
+/**表格**/
+.h2w-dark .h2w__thead .h2w__tr {
+    background-color: #1f1f1f;
+}
+.h2w-dark .h2w__table .h2w__tr:nth-child(2n) {
+    background-color: #090909;
+}
+.h2w-dark .h2w__th,
+.h2w-dark .h2w__td {
+    border-color: #333;
+}
+
+/**代码块**/
+.h2w-dark .h2w__pre,
+.h2w-dark .h2w__pre .h2w__code {
+    background-color: #1b1b1b;
+    border-color: #262626;
+}
+
+.h2w-dark .h2w__code {
+    background-color: #272822;
+    border-color: #1b1c18;
+}
+
+/**块元素**/
+.h2w-dark .h2w__blockquote {
+    border-left-color: #10230f;
+}
+
+/**内连元素**/
+.h2w-dark .h2w__a {
+    color: #1aad16;
+    border-color: #4d804b;
+}
+
+.h2w-dark .h2w__hr {
+    background-color: #242424;
+}
+
+.h2w-dark .h2w__mark {
+    background: yellow;
+    color: black;
+}
+
+.h2w-dark .h2w__todoCheckbox .wx-checkbox-input {
+    background: #2e2e2e;
+    border-color: #494949;
+}
+.h2w-dark .h2w__todoCheckbox .wx-checkbox-input.wx-checkbox-input-checked {
+    background: green;
+    border-color: #4d804b;
+}
+.h2w-dark .h2w__todoCheckbox .wx-checkbox-input.wx-checkbox-input-checked::before {
+    color: white;
+}
+.h2w-dark .h2w__lineNum {
+    color: #494949;
+}
+
+/**代码高亮样式**/

+ 60 - 0
components/agent-ui/markdownPreview/towxml/style/theme/light.css

@@ -0,0 +1,60 @@
+@import '../../parse/highlight/style/github.css'; /*正文样式*/
+.h2w-light {
+    color: #333;
+    background-color: white;
+}
+
+/**标题**/
+.h2w-light .h2w__h1,
+.h2w-light .h2w__h2 {
+    border-color: #eee;
+}
+
+/**表格**/
+.h2w-light .h2w__thead .h2w__tr {
+    background-color: #f6f8fa;
+}
+.h2w-light .h2w__table .h2w__tr:nth-child(2n) {
+    background-color: #fbfcfd;
+}
+.h2w-light .h2w__th,
+.h2w-light .h2w__td {
+    border-color: #dfe2e5;
+}
+
+/**代码块**/
+.h2w-light .h2w__pre {
+    background-color: #f6f8fa;
+    border-color: #eaedf0;
+}
+
+.h2w-light .h2w__code {
+    background-color: #f6f8fa;
+    border-color: #eaedf0;
+}
+
+/**块元素**/
+.h2w-light .h2w__blockquote {
+    border-left-color: #dfe2e5;
+}
+
+/**内连元素**/
+.h2w-light .h2w__a {
+    color: #1aad16;
+    border-color: #b9d9b8;
+}
+
+.h2w-light .h2w__hr {
+    background-color: #eee;
+}
+
+.h2w-light .h2w__mark {
+    background: yellow;
+    color: black;
+}
+
+.h2w-light .h2w__lineNum {
+    color: #ccc;
+}
+
+/**代码高亮样式**/

+ 52 - 0
components/agent-ui/markdownPreview/towxml/table/table.vue

@@ -0,0 +1,52 @@
+<template>
+    <view>
+        <!-- table -->
+        <block v-if="data.tag === 'table'">
+            <view class="h2w__tableParent">
+                <view :class="data.attrs.class" :width="data.attrs.width" :style="data.attrs.style">
+                    <!-- thead、tbody、tfoot -->
+                    <block v-if="data.children" v-for="(item, index) in data.children" :key="index">
+                        <view v-if="item.tag" :class="item.attrs.class">
+                            <!-- tr -->
+                            <block v-if="item.children" v-for="(item, index1) in item.children" :key="index1">
+                                <view v-if="item.tag" :class="item.attrs.class">
+                                    <!-- td -->
+                                    <block v-if="item.children" v-for="(item, index2) in item.children" :key="index2">
+                                        <view v-if="item.tag" :class="item.attrs.class" :width="data.attrs.width" :style="data.attrs.style">
+                                            <!-- content -->
+                                            <decode v-if="item.children" :nodes="item" />
+                                        </view>
+                                    </block>
+                                </view>
+                            </block>
+                        </view>
+                    </block>
+                </view>
+            </view>
+        </block>
+    </view>
+</template>
+
+<script>
+import decode from '../decode';
+export default {
+    components: {
+        decode
+    },
+    data() {
+        return {};
+    },
+    options: {
+        styleIsolation: 'shared'
+    },
+    props: {
+        data: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    methods: {},
+    created: function () {}
+};
+</script>
+<style></style>

+ 46 - 0
components/agent-ui/markdownPreview/towxml/towxml.vue

@@ -0,0 +1,46 @@
+<template>
+    <view :class="'h2w h2w-' + nodes.theme">
+        <view class="h2w__main">
+            <decode :nodes="nodes" />
+        </view>
+    </view>
+</template>
+
+<script>
+import decode from './decode';
+export default {
+    components: {
+        decode
+    },
+    data() {
+        return {
+            someData: {}
+        };
+    },
+    options: {
+        styleIsolation: 'shared'
+    },
+    props: {
+        nodes: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    methods: {},
+    created: function () {}
+};
+</script>
+<style>
+@import './style/main.css';
+@import './style/theme/light.css';
+@import './style/theme/dark.css'; /**基础风格样式**/
+
+/**主题配色(浅色样式)**/
+
+/**主题配色(深色样式)**/
+
+.h2w__main {
+    margin: 0px;
+    padding: 0px;
+}
+</style>

+ 16 - 0
components/agent-ui/markdownPreview/utils.js

@@ -0,0 +1,16 @@
+const towxml = require('./towxml/index');
+export const markdownToWxml = (markdown) => {
+    let wxml = towxml(markdown, 'markdown', {
+        base: '',
+        // 相对资源的base路径
+        theme: 'light',
+        // 主题,默认`light`
+        events: {
+            // 为元素绑定的事件方法
+            tap: (e) => {
+                // console.log('tap', e);
+            }
+        }
+    });
+    return wxml;
+};

+ 120 - 0
components/agent-ui/tools.js

@@ -0,0 +1,120 @@
+export const guide = `agent ui组件配置不正确,请参照使用说明进行配置。
+
+## 使用说明
+
+### 1、前置条件
+
+#### 1.1、开通微信云开发
+agent ui 小程序组件依赖微信云开发 AI 服务,需要开通微信云开发服务。
+
+开通方式
+
+![](https://qcloudimg.tencent-cloud.cn/raw/f06ca4761f54ecc8ed8d9644229c92f9.png)
+
+如已开通微信云开发服务,请跳转至云开发平台(\`https://tcb.cloud.tencent.com/dev\`)创建AI服务。
+
+#### 1.2、创建AI服务
+- 方式一:直接使用agent智能体服务
+ ![](https://qcloudimg.tencent-cloud.cn/raw/97786aaaa15aa1f23e9bbd39a7a6762f.png)
+
+- 方式二:接入大模型
+ ![](https://qcloudimg.tencent-cloud.cn/raw/876d2238b5331a7bdcbd91a1b38b8248.png)
+
+### 2、配置 agent ui 小程序组件
+#### 2.1、配置云开发环境ID
+打开\`miniprogram/app.js\`文件,配置云开发环境ID。
+\`\`\`js
+App({
+  onLaunch: function () {
+    if (!wx.cloud) {
+      console.error("请使用 2.2.3 或以上的基础库以使用云能力");
+    } else {
+      wx.cloud.init({
+        env: "",// 环境id
+        traceUser: true,
+      });
+    }
+
+    this.globalData = {};
+  },
+});
+\`\`\`
+#### 2.1、 agent ui 小程序组件配置
+打开小程序\`miniprogram/pages/index/index.js\`文件,配置 agent ui 小程序组件。
+
+组件参数说明如下:
+
+| 参数名称  | 参数说明         | 参数类型 | 是否必填 | 默认值 |
+| --------- | ---------------- | -------- | -------- | ------ |
+| type      | 对接ai服务类型   | String   | 是       | -      |
+| botId     | agent ID         | String   | 否       | -      |
+| modelName | ai大模型服务商   | String   | 否       | -      |
+| model     | 具体使用的大模型 | String   | 否       | -      |
+| logo     | 图标 | String   | 否       | -      |
+| welcomeMessage     | 欢迎语 | String   | 否       | -      |
+
+对接 agent 服务时,type 为 bot,botId 必填,配置如下:
+\`\`\`js
+agentConfig: {
+      type: "bot",
+      botId: "bot-e7d1e736", 
+      modelName: "", 
+      model:"",
+      logo:"",
+      welcomeMessage:""
+    } 
+\`\`\`
+对接 ai 大模型服务时,type 为 model,modelName 和 modelName必填,配置如下:
+\`\`\`js
+agentConfig: {
+      type: "model",
+      botId: "", 
+      modelName: "hunyuan", 
+      model:"hunyuan-lite",
+      logo:"",
+      welcomeMessage:"" 
+    } 
+\`\`\`
+`;
+export const checkConfig = (config) => {
+    const { type, botId, modelName, model } = config;
+    // 检测AI能力,不存在提示用户
+    if (!wx.cloud.extend || !wx.cloud.extend.AI) {
+        return [false, '使用AI能力需基础库为3.7.7及以上,请升级基础库版本或微信客户端'];
+    }
+    if (!['bot', 'model'].includes(type)) {
+        return [false, 'type 不正确,值应为“bot”或“model”'];
+    }
+    if (type === 'bot' && !botId) {
+        return [false, '当前type值为bot,请配置botId'];
+    }
+    if (type === 'model' && (!modelName || !model)) {
+        return [false, '当前type值为model,请配置modelNam和model'];
+    }
+    return [true, ''];
+};
+// 随机选取三个问题
+export function randomSelectInitquestion(question = [], num = 3) {
+    if (question.length <= num) {
+        return [...question];
+    }
+    const set = new Set();
+    while (set.size < num) {
+        const randomIndex = Math.floor(Math.random() * question.length);
+        set.add(question[randomIndex]);
+    }
+    return Array.from(set);
+}
+function Throttle() {
+    let timer = null;
+    return function (fn) {
+        if (!timer) {
+            timer = setTimeout(() => {
+                fn();
+                timer = null;
+            }, 50);
+        }
+    };
+}
+// 频繁渲染会阻塞UI线程,这里节流一下
+export const ThrottleFn = Throttle();

+ 383 - 0
components/agent-ui/wd-markdown/index.vue

@@ -0,0 +1,383 @@
+<template>
+    <view class="wd-markdown" :style="'font-size: ' + fontSize + 'rpx;'">
+        <rich-text :nodes="_html_var" />
+    </view>
+</template>
+
+<script>
+import MarkdownIt from './utils/markdown-it.min.js';
+import highlight from './utils/highlight.min.js';
+import hljsJs from './utils/hljs_javascript.min.js';
+import hljsCss from './utils/hljs_css.min.js';
+import { addCustomClassPlugin } from './utils/plugin';
+export default {
+    data() {
+        return {
+            _html_var: '',
+            mdInstance: null
+        };
+    },
+    options: {
+        virtualHost: true
+    },
+    props: {
+        className: {
+            type: String,
+            default: ''
+        },
+        style: {
+            type: String,
+            default: ''
+        },
+        id: {
+            type: String,
+            default: ''
+        },
+        markdown: {
+            type: String,
+            default: ''
+        },
+        fontSize: {
+            type: Number,
+            default: 32
+        },
+        options: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    methods: {
+        attached() {
+            this.init();
+            this.updateWidgetAPI();
+        },
+
+        init() {
+            const { options } = this;
+            const hljs = highlight();
+            const javascript = hljsJs();
+            const css = hljsCss();
+            hljs.registerLanguage('javascript', javascript);
+            hljs.registerLanguage('css', css);
+            const md = new MarkdownIt({
+                // 默认开启高亮
+                highlight: function (str, lang) {
+                    if (lang && hljs.getLanguage(lang)) {
+                        try {
+                            return (
+                                '<pre class="_pre"><code class="hljs">' +
+                                hljs.highlight(str, {
+                                    language: lang,
+                                    ignoreIllegals: true
+                                }).value +
+                                '</code></pre>'
+                            );
+                        } catch (__) {
+                            console.log('CatchClause', __);
+                            console.log('CatchClause', __);
+                        }
+                    }
+                    return '<pre class="_pre"><code class="hljs">' + str + '</code></pre>';
+                },
+                ...options
+            });
+            // console.log(md.renderer.rules)
+            addCustomClassPlugin(md);
+            this.setData({
+                mdInstance: md
+            });
+            this.$emit('onReady', {
+                detail: {
+                    markdownInstance: md
+                }
+            });
+            this.setData({
+                _html_var: md.render(this.markdown)
+            });
+        },
+
+        updateWidgetAPI() {
+            if (this.setReadonlyAttributes) {
+                this.setReadonlyAttributes({
+                    value: this.markdown,
+                    markdownInstance: this.mdInstance,
+                    updateMarkdownInstance: ({ markdownInstance }) =>
+                        this.setData({
+                            mdInstance: markdownInstance
+                        })
+                });
+            }
+        }
+    },
+    watch: {
+        markdown: function () {
+            const { mdInstance } = this;
+            if (!mdInstance) {
+                return;
+            }
+            const html = mdInstance.render(this.markdown);
+            // console.log(html)
+            this.setData({
+                _html_var: html
+            });
+        },
+        options: function () {
+            this.init();
+        },
+        markdown_mdInstance: {
+            deep: true,
+            immediate: true,
+
+            handler: function (newValue, oldValue) {
+                this.updateWidgetAPI();
+            }
+        }
+    },
+    mounted() {
+        // 处理小程序 attached 生命周期
+        this.attached();
+    },
+    created: function () {},
+    computed: {
+        markdown_mdInstance() {
+            const { markdown, mdInstance } = this;
+
+            return {
+                markdown,
+                mdInstance
+            };
+        }
+    }
+};
+</script>
+<style>
+/*
+ markdown 样式
+*/
+.wd-markdown {
+    word-wrap: break-word;
+    word-break: normal;
+    text-align: justify;
+}
+.wd-markdown ._p {
+    margin-bottom: 10rpx;
+    line-height: 1.8;
+}
+.wd-markdown ._ol {
+    margin-bottom: 30rpx;
+    padding-left: 1.2em;
+}
+.wd-markdown ._ul {
+    margin-bottom: 30rpx;
+    padding-left: 1.2em;
+}
+.wd-markdown ._hr {
+    border: none;
+    border-top: 3px solid #eee;
+    margin-bottom: 10rpx;
+}
+.wd-markdown ._pre {
+    max-width: 100%;
+    padding: 32rpx;
+    overflow-x: auto;
+    background-color: rgb(246, 248, 250);
+    border-radius: 12rpx;
+    font-family: monospace;
+    font-size: 1em;
+    line-height: 1.14285em;
+    border-radius: 12rpx;
+    margin-bottom: 10rpx;
+}
+.wd-markdown ._h1 {
+    border-bottom-style: double;
+    border-bottom-width: 6rpx;
+    font-size: 42rpx;
+    padding-bottom: 10rpx;
+    margin-bottom: 20rpx;
+}
+
+.wd-markdown ._h2 {
+    border-bottom-style: solid;
+    border-bottom-width: 1rpx;
+    font-size: 40rpx;
+    padding-bottom: 8rpx;
+    margin-bottom: 18rpx;
+}
+
+.wd-markdown ._h3 {
+    font-size: 38rpx;
+    padding-bottom: 6rpx;
+    margin-bottom: 12rpx;
+}
+
+.wd-markdown ._h4 {
+    font-size: 36rpx;
+    padding-bottom: 4rpx;
+    margin-bottom: 12rpx;
+}
+
+.wd-markdown ._h5 {
+    font-size: 34rpx;
+    padding-bottom: 2rpx;
+    margin-bottom: 12rpx;
+}
+.wd-markdown ._h6 {
+    margin-bottom: 12rpx;
+}
+.wd-markdown ._a {
+    margin: 0 8rpx;
+    border-bottom-width: 1rpx;
+    border-bottom-style: solid;
+    line-height: 1;
+    color: #0000ee;
+}
+.wd-markdown ._blockquote {
+    margin: 0 0 10px;
+    padding: 15px 20px;
+    background-color: #f1f2f3;
+    border-left: 5px solid #ccc;
+    color: #666;
+    font-style: italic;
+}
+.wd-markdown ._tableParent {
+    width: 100%;
+    overflow-x: auto;
+}
+
+.wd-markdown ._table {
+    min-width: fit-content;
+    border-collapse: collapse;
+    margin: 0;
+    overflow: hidden;
+}
+.wd-markdown ._table ._th,
+.wd-markdown ._table ._td {
+    box-sizing: border-box;
+    position: relative;
+    min-width: 70px;
+    padding: 0px 5px;
+    border: 1px solid #e1e6f0;
+    vertical-align: top;
+    background-clip: padding-box;
+}
+.wd-markdown ._table ._th {
+    font-weight: bold;
+    background-color: #f5f7fa;
+}
+.wd-markdown ._table ._td {
+    background-color: white;
+}
+.wd-markdown ._table ._th > ._p,
+.wd-markdown ._table ._td > ._p {
+    min-height: 1em;
+}
+/*!
+    Theme: GitHub
+    Description: Light theme as seen on github.com
+    Author: github.com
+    Maintainer: @Hirse
+    Updated: 2021-05-15
+
+    Outdated base version: https://github.com/primer/github-syntax-light
+    Current colors taken from GitHub's CSS
+  */
+.hljs {
+    color: #24292e;
+    /* background: #ffffff; */
+}
+.hljs-doctag,
+.hljs-keyword,
+.hljs-meta .hljs-keyword,
+.hljs-template-tag,
+.hljs-template-variable,
+.hljs-type,
+.hljs-variable.language_ {
+    /* prettylights-syntax-keyword */
+    color: #d73a49;
+}
+.hljs-title,
+.hljs-title.class_,
+.hljs-title.class_.inherited__,
+.hljs-title.function_ {
+    /* prettylights-syntax-entity */
+    color: #6f42c1;
+}
+.hljs-attr,
+.hljs-attribute,
+.hljs-literal,
+.hljs-meta,
+.hljs-number,
+.hljs-operator,
+.hljs-variable,
+.hljs-selector-attr,
+.hljs-selector-class,
+.hljs-selector-id {
+    /* prettylights-syntax-constant */
+    color: #005cc5;
+}
+.hljs-regexp,
+.hljs-string,
+.hljs-meta .hljs-string {
+    /* prettylights-syntax-string */
+    color: #032f62;
+}
+.hljs-built_in,
+.hljs-symbol {
+    /* prettylights-syntax-variable */
+    color: #e36209;
+}
+.hljs-comment,
+.hljs-code,
+.hljs-formula {
+    /* prettylights-syntax-comment */
+    color: #6a737d;
+}
+.hljs-name,
+.hljs-quote,
+.hljs-selector-tag,
+.hljs-selector-pseudo {
+    /* prettylights-syntax-entity-tag */
+    color: #22863a;
+}
+.hljs-subst {
+    /* prettylights-syntax-storage-modifier-import */
+    color: #24292e;
+}
+.hljs-section {
+    /* prettylights-syntax-markup-heading */
+    color: #005cc5;
+    font-weight: bold;
+}
+.hljs-bullet {
+    /* prettylights-syntax-markup-list */
+    color: #735c0f;
+}
+.hljs-emphasis {
+    /* prettylights-syntax-markup-italic */
+    color: #24292e;
+    font-style: italic;
+}
+.hljs-strong {
+    /* prettylights-syntax-markup-bold */
+    color: #24292e;
+    font-weight: bold;
+}
+.hljs-addition {
+    /* prettylights-syntax-markup-inserted */
+    color: #22863a;
+    background-color: #f0fff4;
+}
+.hljs-deletion {
+    /* prettylights-syntax-markup-deleted */
+    color: #b31d28;
+    background-color: #ffeef0;
+}
+.hljs-char.escape_,
+.hljs-link,
+.hljs-params,
+.hljs-property,
+.hljs-punctuation,
+.hljs-tag {
+    /* purposely ignored */
+}
+</style>

File diff suppressed because it is too large
+ 854 - 0
components/agent-ui/wd-markdown/utils/highlight.min.js


File diff suppressed because it is too large
+ 119 - 0
components/agent-ui/wd-markdown/utils/hljs_css.min.js


File diff suppressed because it is too large
+ 331 - 0
components/agent-ui/wd-markdown/utils/hljs_javascript.min.js


File diff suppressed because it is too large
+ 2328 - 0
components/agent-ui/wd-markdown/utils/markdown-it.min.js


+ 32 - 0
components/agent-ui/wd-markdown/utils/plugin.js

@@ -0,0 +1,32 @@
+const options = {
+    paragraph_open: '_p',
+    bullet_list_open: '_ul',
+    ordered_list_open: '_ol',
+    hr: '_hr',
+    link_open: '_a',
+    blockquote_open: '_blockquote',
+    table_open: '_table',
+    thead_open: '_thead',
+    tr_open: '_tr',
+    th_open: '_th',
+    td_open: '_td'
+};
+export function addCustomClassPlugin(md) {
+    md.renderer.rules.heading_open = (tokens, idx, options, env, self) => {
+        const token = tokens[idx];
+        // console.log(token)
+        // 判断当前标签是否为 h1
+        if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(token.tag)) {
+            // 给 h1 标签添加 class 属性
+            token.attrJoin('class', `_${token.tag}`);
+        }
+        return self.renderToken(tokens, idx, options);
+    };
+    Object.keys(options).forEach((key) => {
+        const className = options[key];
+        md.renderer.rules[key] = (tokens, idx, options, env, self) => {
+            tokens[idx].attrPush(['class', className]);
+            return self.renderToken(tokens, idx, options);
+        };
+    });
+}

+ 3 - 1
main.js

@@ -4,9 +4,11 @@ import storage from './utils/storage.js'
 import Vue from 'vue'
 Vue.config.productionTip = false
 Vue.prototype.$storage = storage;
+// 全局mixins,用于实现setData等功能,请勿删除!';
+import zpMixins from '@/uni_modules/zp-mixins/index.js';
 
 App.mpType = 'app'
-
+Vue.use(zpMixins);
 // 引入全局TuniaoUI
 import TuniaoUI from 'tuniao-ui'
 Vue.use(TuniaoUI)

+ 10 - 0
pages.json

@@ -133,6 +133,16 @@
 			{
 				"navigationBarTitleText" : "我有什么"
 			}
+		},
+		{
+			"path" : "pages/index/aichat",
+			"style" : 
+			{
+				"navigationBarTitleText" : "速立保AI",
+				"usingComponents": {
+					"agent-ui": "/components/agent-ui/index"
+				}
+			}
 		}
 		 
 	],

+ 0 - 240
pages/discovery/discovery.vue

@@ -1,240 +0,0 @@
-<template>
-	<view class="discovery tn-safe-area-inset-bottom" style="max-height: 100vh">
-	<tn-nav-bar customBack>
-		<view slot="back" class='tn-custom-nav-bar__back' >
-			 
-			<image style="width: 30px;height: 28px;margin-left:4px"  @click="reFetchData()" src="../../static/logo.png"></image>
-			 
-		</view>
-	
-		<view slot="default" style="display: flex;">
-			<view style="flex:1;">
-				<text :style="{fontSize:(wxFontSize)+'px'}">速立保</text>
-			</view>
-			 
-		</view>
-	</tn-nav-bar>	
-	
-	<view :style="{paddingTop: vuex_custom_bar_height + 'px'}" style="background-color: #f7f7f7;">
-		<view style="width: 100%;padding-bottom: 0;background-color: #fff;">
-			<view style="display: flex;width: 100%;background: linear-gradient(0deg, #fff, #f8f8f">
-				 
-				<view style="flex:1; margin:16px; text-align: center;border-radius: 47px;" class="bg-slogan">
-					 
-					<text style="margin-top:12px;color:#fff;font-size:17px;margin: 16px;" :style="{fontSize:(fontSize)+'px'}">生物制药产业国际产品供需平台</text>
-				</view>
-			</view>
-			
-			
-		</view>
-		
-		<view style="padding: 16px;color:#333;font-weight: bold;" :style="{fontSize:(fontSize-1)+'px'}">
-			 优质入驻企业
-		</view>
-		
-		<swiper class="swiper" circular :indicator-dots="indicatorDots" :autoplay="autoplay"  v-if="!hideComps">
-			<swiper-item v-for="(item,index) of companyList" :key="item.id" style="position:relative">
-				<text class="tn-icon-close" @click="closeComps" style="position: absolute;right: 0px;color: #fff;background: #00000066;border-top-right-radius: 0;padding: 4px;font-size: 13px;border-bottom-left-radius: 8px;"></text>
-				<image :src="item.picUrl?item.picUrl:'../../static/tu/needbg.png'" @click="showImgs(index,companyList)"  mode="aspectFill" style="width: 100%;height: 100%;"></image>
-			</swiper-item>
-		</swiper>
-		<view v-if="hideComps" style="height: 200px;display: flex;align-items: center;justify-content: center;color: #2196f36e;">
-			<text @click="showComps()">〈恢复展示〉</text>
-		</view>
-		<view style="padding: 16px;color:#333;font-weight: bold;"  :style="{fontSize:(fontSize-1)+'px'}">
-			 优质供应
-		</view>
-		<swiper class="swiper" circular :indicator-dots="indicatorDots" :autoplay="autoplay"  v-if="!hideProds">
-			<swiper-item v-for="(item,index) of prodList" :key="item.id">
-				<text class="tn-icon-close" @click="closeProds" style="position: absolute;right: 0px;color: #fff;background: #00000066;border-top-right-radius: 0;padding: 4px;font-size: 13px;border-bottom-left-radius: 8px;"></text>
-				<image :src="item.picUrl?item.picUrl:'../../static/tu/needbg.png'" @click="showImgs(index,prodList)" style="width: 100%;height: 100%;"  mode="aspectFill"></image>
-			</swiper-item>
-			 
-		</swiper>
-		<view v-if="hideProds" style="height: 200px;display: flex;align-items: center;justify-content: center;color: #2196f36e;">
-			<text @click="showProds()">〈恢复展示〉</text>
-		</view>
-		<!-- <image style="width: 180px;height: 150px" src="../../static/logo.png"></image>
-		
-		
-		<view style="margin-top:24px"><text style="font-size:30px;">生物制药产业</text></view>
-		<view><text style="font-size:30px">国际产品展示中心</text></view>
-		<view style="margin-top:24px"><text style="font-size:20px;">生物制药产业国际产品供需平台</text></view> -->
-		 
-		<view style="display: flex;margin-top:32px;margin: 24px 16px;">
-			<view style="flex: 1;padding: 0 0 0 16px;" class="bg01" @click="showAdd">
-				<image src="../../static/tu/needi.png" style="width: 36px;height: 36px; vertical-align: middle;margin-top: -6px;margin-right: 8px;"></image>
-				<text style="line-height: 72px;font-size: 18px;" :style="{fontSize:(fontSize+1)+'px'}">我要什么</text>
-				
-			</view>
-			<view style="flex: 1;padding: 0 0 0 16px;" class="bg02" @click="showAdd2">
-				<image src="../../static/tu/sharei.png" style="width: 36px;height: 36px; vertical-align: middle;margin-top: -6px;margin-right: 8px;"></image>
-				<text style="line-height: 72px;font-size: 18px;" :style="{fontSize:(fontSize+1)+'px'}">我有什么</text>
-			</view>
-		</view>
-		
-		<view class='tn-tabbar-height'></view>
-		
-	</view>
-	</view>
-</template>
-
-<script>
-	import request from '../../utils/request'
-	export default {
-		data() {
-			return {
-				  indicatorDots: true,
-				  autoplay: false,
-				  companyList:[],
-				  prodList:[],
-				  hideComps: false,
-				  hideProds: false,
-				  fontSize:17
-			}
-		},
-		onReady() {
-			const appBaseInfo = wx.getAppBaseInfo();
-			this.fontSize = uni.getStorageSync('fontSize')||appBaseInfo.fontSizeSetting||17;
-			this.$nextTick(() => {
-				this.loadData()
-				this.loadData2()
-			})
-		},
-		methods: {
-			//关闭banner1
-			closeComps(){
-				this.hideComps = true;
-			},
-			//关闭banner2
-			closeProds(){
-				this.hideProds = true;
-			},
-			//显示banner2
-			showProds(){
-				this.hideProds = false;
-			},
-			//显示banner1
-			showComps(){
-				this.hideComps = false;
-			},
-			fetchData(){
-				this.loadData()
-				this.loadData2()
-			},
-			loadData() {
-				let that = this;
-				request.post('/slbTopad/premiumCompanies', {
-					 
-				}).then(res => {
-					if (res&&res.success) {
-						let dataList = res.list||[];
-						let newList = [];
-						for(let i=0;i<dataList.length;i++){
-							 if(dataList[i].showFlag=='是'){
-								 newList.push(dataList[i]);
-							 }
-						}
-						that.companyList = newList; 
-					}  
-				})
-			},
-			loadData2() {
-				let that = this;
-				request.post('/slbTopad/premiumShareCompanies', {
-					 
-				}).then(res => {
-					if (res&&res.success) {
-						 let dataList = res.list||[];
-						 let newList = [];
-						 for(let i=0;i<dataList.length;i++){
-							 if(dataList[i].showFlag=='是'){
-								 newList.push(dataList[i]);
-							 }
-						 }
-						 that.prodList = newList;
-					}  
-				})
-			},
-			showImgs(index, list){
-				let urls = [];
-				for(let i=0;i<list.length;i++){
-					urls.push(list[i].picUrl);
-				}
-				
-				// 预览图片
-				uni.previewImage({
-					urls: urls,
-					current: index,
-				});
-			},
-			showAdd(){
-				if(uni.getStorageSync('userNo')){
-					uni.navigateTo({
-						url:'/circlePages/circle'
-					})
-				}else{
-					uni.setStorageSync('nextPage','/circlePages/circle');
-					uni.navigateTo({
-						url:'/pages/login/login'
-					})
-				}
-				
-			},
-			showAdd2(){
-				if(uni.getStorageSync('userNo')){
-					uni.navigateTo({
-						url:'/circlePages/addShare'
-					})
-				}else{
-					uni.setStorageSync('nextPage','/circlePages/addShare');
-					uni.navigateTo({
-						url:'/pages/login/login'
-					})
-				}
-				
-			}
-		}
-	}
-</script>
-
-<style>
-.swiper-item {
-	text-align: center;
-}
-.swiper{
-	height: 200px;
-}
-.bg01{
-	color: #fff;
-	background-image: url(./../../static/tu/needbg.png);
-	background-size: cover;
-	height: 72px;
-	border-radius: 20px;
-	margin-right: 16px;
-}
-.bg02{
-	color: #fff;
-	background-image: url(./../../static/tu/sharebg.png);
-	background-size: cover;
-	height: 72px;
-	border-radius: 20px;
-}
-
-.bg-slogan{
-    color: #fff;
-    background-image: url(./../../static/tu/slogan-min.png);
-     
-	background-size: cover;
-	    line-height: 40px;
-	    background-repeat: no-repeat;
-}
-
-/* 底部安全边距 start*/
-	.tn-tabbar-height {
-		min-height: 120rpx;
-		height: calc(140rpx + env(safe-area-inset-bottom) / 2);
-		height: calc(140rpx + constant(safe-area-inset-bottom));
-	}
-
-</style>

+ 100 - 0
pages/index/aichat.vue

@@ -0,0 +1,100 @@
+<template>
+    <view>
+		<tn-nav-bar fixed  customBack>
+			<view slot="back" class='tn-custom-nav-bar__back' @click="goBack">
+				<text class='icon tn-icon-left'></text>
+		
+			</view>
+			<view slot="default" style="display: flex;">
+				<view style="flex:1;">
+					<text :style="{fontSize:(wxFontSize)+'px'}">速立保AI</text>
+				</view>
+			</view>
+		</tn-nav-bar>
+        <!-- index.wxml -->
+		 <!-- <navigationBar></navigationBar> -->
+		 <!-- <button open-type="contact" bindcontact="handleContact" session-from="sessionFrom">111</button> -->
+        <agent-ui   :agentConfig="agentConfig" showBotAvatar="true"></agent-ui>
+    </view>
+</template>
+
+<script>
+import agentUi from '@/components/agent-ui/index';
+// index.js
+export default {
+    components: {
+        agentUi
+    },
+    data() {
+        return {
+            agentConfig: {
+                type: 'bot',
+                // 值为'bot'或'model'。当type='bot'时,botId必填;当type='model'时,modelName和model必填
+                botId: 'bot-df4c8ed6',
+                // agent id
+                showBotAvatar:true// 是否在对话框左侧显示头像
+                // 具体的模型版本
+                // logo: 'https://cloud1-6g83nk504b196aa9-1328241815.tcloudbaseapp.com/resources/2025-03/lowcode-2171303',
+                // 图标(只在model模式下生效)
+                // welcomeMessage: '' // 欢迎语(只在model模式下生效)
+            }
+        };
+    },
+    methods: {
+		goBack() {
+			const pages = getCurrentPages()
+			// 有可返回的页面则直接返回,uni.navigateBack 默认返回失败之后会自动刷新页面 ,无法继续返回
+			if (pages.length > 1) {
+				uni.navigateBack()
+				return;
+			}else{
+				uni.reLaunch({
+					url: '/pages/index/index'
+				})
+			}
+		},
+	}
+};
+</script>
+<style lang="scss" scoped>
+	/* 胶囊*/
+	.tn-custom-nav-bar__back {
+		width: 60%;
+		height: 100%;
+		position: relative;
+		display: flex;
+		justify-content: space-evenly;
+		align-items: center;
+		box-sizing: border-box;
+		 
+		border-radius: 1000rpx;
+		border: 1rpx solid rgba(255, 255, 255, 0.5);
+		 
+		font-size: 18px;
+	
+		.icon {
+			display: block;
+			flex: 1;
+			margin: auto;
+			text-align: center;
+		}
+	
+		&:before {
+			content: " ";
+			width: 1rpx;
+			height: 110%;
+			position: absolute;
+			top: 22.5%;
+			left: 0;
+			right: 0;
+			margin: auto;
+			transform: scale(0.5);
+			transform-origin: 0 0;
+			pointer-events: none;
+			box-sizing: border-box;
+			opacity: 0.7;
+			background-color: #FFFFFF;
+		}
+	}
+	
+</style>

+ 177 - 2
pages/index/index.vue

@@ -77,6 +77,35 @@
 		 	<view class='tn-tabbar-height'></view>
 		 	
 		 </view>
+		 <view class="edit tnxuanfu" @tap="showLandscape">
+		 	<view class="bg0 pa">
+		 		<view class="bg1" style="background-size: cover;border-radius: 50%;background-image: url(https://oss.lx-device.com/userFeedback/1741316243096Hwk.gif);">
+		 		</view>
+		 	</view>
+		 	<view class="hx-box pa">
+		 		<view class="pr">
+		 			<view class="hx-k1 pa0">
+		 				<view class="span"></view>
+		 			</view>
+		 			<view class="hx-k2 pa0">
+		 				<view class="span"></view>
+		 			</view>
+		 			<view class="hx-k3 pa0">
+		 				<view class="span"></view>
+		 			</view>
+		 			<view class="hx-k4 pa0">
+		 				<view class="span"></view>
+		 			</view>
+		 			<view class="hx-k5 pa0">
+		 				<view class="span"></view>
+		 			</view>
+		 			<view class="hx-k6 pa0">
+		 				<view class="span"></view>
+		 			</view>
+		 		</view>
+		 	</view>
+		 </view>
+		 
 		 <Auth ref="authRef"></Auth>
 		 </view>
 		
@@ -87,7 +116,6 @@
 	import Auth from '../index/autoLogin.vue'
 	import Home from '../home/home.vue'
 	import Comm from '../comm/comm.vue'
-	import Discovery from '../discovery/discovery.vue'
 	import Mine from '../mine/mine.vue'
     import request from '../../utils/request'
 	export default {
@@ -95,7 +123,6 @@
 			Auth,
 			Home,
 			Comm,
-			Discovery,
 			Mine
 		},
 		data() {
@@ -223,6 +250,11 @@
 					current: index,
 				});
 			},
+			showLandscape(){
+				uni.navigateTo({
+					url:'/pages/index/aichat'
+				})
+			},
 			showAdd(){
 				if(uni.getStorageSync('userNo')){
 					uni.navigateTo({
@@ -291,4 +323,147 @@
 		height: calc(140rpx + constant(safe-area-inset-bottom));
 	}
 	
+	
+	/* 悬浮 */
+	.tnxuanfu {
+		animation: suspension 3s ease-in-out infinite;
+	}
+	
+	@keyframes suspension {
+	
+		0%,
+		100% {
+			transform: translateY(-0.8rem);
+		}
+	
+		50% {
+			transform: translateY(-0.8rem);
+		}
+	}
+	
+	/* 悬浮按钮 */
+	.button-shop {
+		width: 90rpx;
+		height: 90rpx;
+		display: flex;
+		flex-direction: row;
+		position: fixed;
+		/* bottom:200rpx;
+	    right: 20rpx; */
+		left: 5rpx;
+		top: 5rpx;
+		z-index: 1001;
+		border-radius: 100px;
+		opacity: 0.9;
+	}
+	
+	
+	/* 按钮 */
+	.edit {
+		bottom: 300rpx;
+		right: 75rpx;
+		position: fixed;
+		z-index: 9999;
+	}
+	
+	
+	.pa,
+	.pa0 {
+		position: absolute
+	}
+	
+	.pa0 {
+		left: 0;
+		top: 0
+	}
+	
+	
+	.bg0 {
+		width: 100rpx;
+		height: 100rpx;
+		top: 50%;
+		left: 50%;
+		transform: translate(-50%, -50%);
+		border-radius: 50%;
+		font-size: 32px;
+		color: #fff;
+		text-align: center;
+		line-height: 50px;
+	}
+	
+	.bg1 {
+		width: 100%;
+		height: 100%;
+	}
+	
+	
+	
+	
+	.hx-box {
+		top: 50%;
+		left: 50%;
+		width: 100rpx;
+		height: 100rpx;
+		transform-style: preserve-3d;
+		transform: translate(-50%, -50%) rotateY(75deg) rotateZ(10deg);
+	}
+	
+	.hx-box .pr {
+		width: 100rpx;
+		height: 100rpx;
+		transform-style: preserve-3d;
+		animation: hxz 20s linear infinite;
+	}
+	
+	@keyframes hxz {
+		0% {
+			transform: rotateX(0deg);
+		}
+	
+		100% {
+			transform: rotateX(-360deg);
+		}
+	}
+	
+	
+	
+	.hx-box .pr .pa0 {
+		width: 100rpx;
+		height: 100rpx;
+		/* border: 4px solid #5ec0ff; */
+		border-radius: 1000px;
+	}
+	
+	
+	
+	@keyframes hx {
+		to {
+			transform: rotate(360deg);
+		}
+	}
+	
+	.hx-k1 {
+		transform: rotateX(-60deg) rotateZ(-60deg)
+	}
+	
+	.hx-k2 {
+		transform: rotateX(-30deg) rotateZ(-30deg)
+	}
+	
+	.hx-k3 {
+		transform: rotateX(0deg) rotateZ(0deg)
+	}
+	
+	.hx-k4 {
+		transform: rotateX(30deg) rotateZ(30deg)
+	}
+	
+	.hx-k5 {
+		transform: rotateX(60deg) rotateZ(60deg)
+	}
+	
+	.hx-k6 {
+		transform: rotateX(90deg) rotateZ(90deg)
+	}
+	
 </style>

+ 2 - 0
static/components/agent-ui/imgs/arrow.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.5001 8.08575L12.0002 13.5858L6.50015 8.08576L5.08594 9.49997L12.0002 16.4142L18.9144 9.49997L17.5001 8.08575Z"    fill="black" />
+</svg>

File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/camera.svg


+ 2 - 0
static/components/agent-ui/imgs/clear.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 1L15 1L15 9.5L21 9.5L21 23L3 23L3 9.5L9 9.5L9 1ZM11 3L11 11.5L5 11.5V14L19 14L19 11.5H13L13 3L11 3ZM19 16L5 16L5 21H14V18L16 18V21H19V16Z"    fill="black" />
+</svg>

BIN
static/components/agent-ui/imgs/close-filled.png


+ 2 - 0
static/components/agent-ui/imgs/close.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.0502 5.63611L11.9999 10.5859L16.9497 5.63611L18.3639 7.05032L13.4142 12.0001L18.3639 16.9498L16.9497 18.364L11.9999 13.4143L7.0502 18.364L5.63599 16.9498L10.5857 12.0001L5.63599 7.05032L7.0502 5.63611Z"    fill="black" />
+</svg>

+ 2 - 0
static/components/agent-ui/imgs/copy.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 2H15V7.5H13V4H4V13H7.5V15H2V2ZM9 9H22V22H9V9ZM11 11V20H20V11H11Z" fill="#8b8b8b" />
+</svg>

File diff suppressed because it is too large
+ 1 - 0
static/components/agent-ui/imgs/excel.svg


+ 2 - 0
static/components/agent-ui/imgs/file.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3 1H15.4142L21 6.58579V23H3V1ZM5 3V21H19V9H13V3H5ZM15 3.41421V7H18.5858L15 3.41421Z" fill="black" />
+</svg>

File diff suppressed because it is too large
+ 1 - 0
static/components/agent-ui/imgs/image.svg


File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/internet.svg


File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/internetUse.svg


+ 12 - 0
static/components/agent-ui/imgs/loading.svg

@@ -0,0 +1,12 @@
+    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+        <path d="M11 1H12C18.0751 1 23 5.92487 23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12V11H3V12C3 16.9706 7.02944 21 12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3H11V1Z" fill="rgb(95, 114, 146)">
+            <animateTransform
+                attributeName="transform"
+                attributeType="XML"
+                type="rotate"
+                from="0 12 12"
+                to="360 12 12"
+                dur="2s"
+                repeatCount="indefinite" />
+        </path>
+    </svg>

File diff suppressed because it is too large
+ 1 - 0
static/components/agent-ui/imgs/pdf.svg


File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/search.svg


+ 2 - 0
static/components/agent-ui/imgs/send.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_100396_60187)">    <path     d="M0.291748 1.66449L24.0026 12L0.291748 22.3355L3.93958 12L0.291748 1.66449ZM5.70755 13L3.70832 18.6645L18.9974 12L3.70832 5.33551L5.70755 11H11V13H5.70755Z"        fill="#3b63ef" /></g><defs>    <clipPath id="clip0_100396_60187">        <rect width="24" height="24" fill="white" style="fill:white;fill-opacity:1;" />    </clipPath></defs>
+</svg>

File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/set.svg


File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/share.svg


+ 2 - 0
static/components/agent-ui/imgs/star-highlight.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12.0003 0.630371L14.9029 8.98093L23.7417 9.16105L16.6969 14.5021L19.2569 22.964L12.0003 17.9144L4.74363 22.964L7.30367 14.5021L0.258789 9.16105L9.09761 8.98093L12.0003 0.630371ZM12.0003 6.72181L10.5298 10.9522L6.05209 11.0434L9.62099 13.7492L8.32409 18.0359L12.0003 15.4778L15.6764 18.0359L14.3795 13.7492L17.9484 11.0434L13.4707 10.9522L12.0003 6.72181Z" fill="#f2db4a" />
+</svg>

+ 2 - 0
static/components/agent-ui/imgs/star.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12.0003 0.630371L14.9029 8.98093L23.7417 9.16105L16.6969 14.5021L19.2569 22.964L12.0003 17.9144L4.74363 22.964L7.30367 14.5021L0.258789 9.16105L9.09761 8.98093L12.0003 0.630371ZM12.0003 6.72181L10.5298 10.9522L6.05209 11.0434L9.62099 13.7492L8.32409 18.0359L12.0003 15.4778L15.6764 18.0359L14.3795 13.7492L17.9484 11.0434L13.4707 10.9522L12.0003 6.72181Z" fill="black" />
+</svg>

+ 2 - 0
static/components/agent-ui/imgs/stop.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3ZM1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12Z"    fill="#d54941" /><path d="M8 8H16V16H8V8Z" fill="#d54941" />
+</svg>

File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/system-sum.svg


File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/thumb-down.svg


File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/thumb-up.svg


+ 2 - 0
static/components/agent-ui/imgs/toBottom.svg

@@ -0,0 +1,2 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3ZM1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12ZM13 6.5V14.0858L16 11.0858L17.4142 12.5L12 17.9142L6.58579 12.5L8 11.0858L11 14.0858V6.5H13Z"    fill="black" />
+</svg>

File diff suppressed because it is too large
+ 2 - 0
static/components/agent-ui/imgs/uploadImg.svg


File diff suppressed because it is too large
+ 1 - 0
static/components/agent-ui/imgs/word.svg


+ 0 - 0
static/components/agent-ui/markdownPreview/towxml/audio-player/loading.svg


Some files were not shown because too many files changed in this diff