54 lines
1.7 KiB
Vue
54 lines
1.7 KiB
Vue
<script setup lang="ts">
|
|
import MarkdownIt from "markdown-it";
|
|
import { computed } from "vue";
|
|
|
|
const props = defineProps<{
|
|
content: string;
|
|
streaming?: boolean;
|
|
}>();
|
|
|
|
const markdown = new MarkdownIt({ breaks: true, html: false, linkify: true });
|
|
const answer = computed(() => stripStreamingReasoning(props.content).replace(/^\s+/, ""));
|
|
const renderedContent = computed(() => answer.value.trim() ? markdown.render(answer.value) : "");
|
|
|
|
function stripStreamingReasoning(content: string) {
|
|
const lower = content.toLowerCase();
|
|
let visible = "";
|
|
let cursor = 0;
|
|
let reasoningDepth = 0;
|
|
while (cursor < content.length) {
|
|
const tagStart = content.indexOf("<", cursor);
|
|
if (tagStart === -1) {
|
|
if (reasoningDepth === 0) visible += content.slice(cursor);
|
|
break;
|
|
}
|
|
if (reasoningDepth === 0) visible += content.slice(cursor, tagStart);
|
|
const tail = lower.slice(tagStart);
|
|
const openTag = tail.match(/^<think(?:\s[^>]*)?>/);
|
|
if (openTag) {
|
|
reasoningDepth += 1;
|
|
cursor = tagStart + openTag[0].length;
|
|
continue;
|
|
}
|
|
const closeTag = tail.match(/^<\/think\s*>/);
|
|
if (closeTag) {
|
|
reasoningDepth = Math.max(0, reasoningDepth - 1);
|
|
cursor = tagStart + closeTag[0].length;
|
|
continue;
|
|
}
|
|
if ("<think".startsWith(tail) || "</think>".startsWith(tail)) break;
|
|
if (reasoningDepth === 0) visible += "<";
|
|
cursor = tagStart + 1;
|
|
}
|
|
return visible;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div v-if="renderedContent" class="agent-preview-markdown" v-html="renderedContent"></div>
|
|
<div v-else-if="streaming" class="agent-preview-generation-state">
|
|
<span></span><span></span><span></span>
|
|
思考中
|
|
</div>
|
|
</template>
|