@core-pilot/client-vue 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/client-vue.css +1 -1
- package/dist/cjs/components/x-markdown/composables/useFormHandler.js +2 -0
- package/dist/cjs/components/x-markdown/composables/useFormHandler.js.map +1 -0
- package/dist/cjs/components/x-markdown/composables/useImageLoader.js +2 -0
- package/dist/cjs/components/x-markdown/composables/useImageLoader.js.map +1 -0
- package/dist/cjs/components/x-markdown/composables/useMarkdownProcessor.js +2 -0
- package/dist/cjs/components/x-markdown/composables/useMarkdownProcessor.js.map +1 -0
- package/dist/cjs/components/x-markdown/composables/useRefHandler.js +2 -0
- package/dist/cjs/components/x-markdown/composables/useRefHandler.js.map +1 -0
- package/dist/cjs/components/x-markdown/composables/useStreamHandler.js +2 -0
- package/dist/cjs/components/x-markdown/composables/useStreamHandler.js.map +1 -0
- package/dist/cjs/components/x-markdown/index.js +1 -1
- package/dist/cjs/components/x-markdown/index.js.map +1 -1
- package/dist/cjs/components/x-markdown/renderers/hastRenderer.js +2 -0
- package/dist/cjs/components/x-markdown/renderers/hastRenderer.js.map +1 -0
- package/dist/cjs/components/x-markdown/utils/disabledUtils.js +2 -0
- package/dist/cjs/components/x-markdown/utils/disabledUtils.js.map +1 -0
- package/dist/cjs/components/x-markdown/utils/formUtils.js +2 -0
- package/dist/cjs/components/x-markdown/utils/formUtils.js.map +1 -0
- package/dist/cjs/components/x-markdown/utils/jsonUtils.js +2 -0
- package/dist/cjs/components/x-markdown/utils/jsonUtils.js.map +1 -0
- package/dist/cjs/components/x-markdown/utils/refUtils.js +2 -0
- package/dist/cjs/components/x-markdown/utils/refUtils.js.map +1 -0
- package/dist/cjs/components/x-markdown/utils/textFormatUtils.js +2 -0
- package/dist/cjs/components/x-markdown/utils/textFormatUtils.js.map +1 -0
- package/dist/es/client-vue.css +1 -1
- package/dist/es/components/x-markdown/composables/useFormHandler.js +66 -0
- package/dist/es/components/x-markdown/composables/useFormHandler.js.map +1 -0
- package/dist/es/components/x-markdown/composables/useImageLoader.js +58 -0
- package/dist/es/components/x-markdown/composables/useImageLoader.js.map +1 -0
- package/dist/es/components/x-markdown/composables/useMarkdownProcessor.js +48 -0
- package/dist/es/components/x-markdown/composables/useMarkdownProcessor.js.map +1 -0
- package/dist/es/components/x-markdown/composables/useRefHandler.js +80 -0
- package/dist/es/components/x-markdown/composables/useRefHandler.js.map +1 -0
- package/dist/es/components/x-markdown/composables/useStreamHandler.js +45 -0
- package/dist/es/components/x-markdown/composables/useStreamHandler.js.map +1 -0
- package/dist/es/components/x-markdown/index.js +73 -681
- package/dist/es/components/x-markdown/index.js.map +1 -1
- package/dist/es/components/x-markdown/renderers/hastRenderer.js +427 -0
- package/dist/es/components/x-markdown/renderers/hastRenderer.js.map +1 -0
- package/dist/es/components/x-markdown/utils/disabledUtils.js +15 -0
- package/dist/es/components/x-markdown/utils/disabledUtils.js.map +1 -0
- package/dist/es/components/x-markdown/utils/formUtils.js +82 -0
- package/dist/es/components/x-markdown/utils/formUtils.js.map +1 -0
- package/dist/es/components/x-markdown/utils/jsonUtils.js +20 -0
- package/dist/es/components/x-markdown/utils/jsonUtils.js.map +1 -0
- package/dist/es/components/x-markdown/utils/refUtils.js +18 -0
- package/dist/es/components/x-markdown/utils/refUtils.js.map +1 -0
- package/dist/es/components/x-markdown/utils/textFormatUtils.js +46 -0
- package/dist/es/components/x-markdown/utils/textFormatUtils.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hastRenderer.js","sources":["../../../../../src/components/x-markdown/renderers/hastRenderer.ts"],"sourcesContent":["/**\n * HAST (HTML AST) 渲染器\n * 将 HAST 节点转换为 Vue VNode\n * 优化了复杂表单的性能问题\n */\n\nimport { h } from 'vue';\nimport {\n ElMessage,\n ElForm,\n ElFormItem,\n ElInput,\n ElCard,\n ElButton,\n ElSelect,\n ElDatePicker,\n ElTableColumn,\n ElTimeline,\n ElRow,\n ElCol,\n ElRadioGroup,\n ElRadio,\n ElConfigProvider,\n ElTag,\n} from 'element-plus';\nimport zhCN from 'element-plus/es/locale/lang/zh-cn';\nimport CoreText from '../../core-text';\nimport CoreTips from '../../core-tips';\nimport CoreResult from '../../core-result';\nimport CoreTable from '../../core-table';\nimport CoreChart from '../../core-chart';\nimport CoreCard from '../../core-card';\nimport CoreUpload from '../../core-upload';\nimport { parseCorePilot } from '../utils/parseCorePilotSchema';\nimport { isCompleteJSON } from '../utils/jsonUtils';\nimport { checkDisabled, DisabledCheckContext } from '../utils/disabledUtils';\nimport { InputSchema } from '@/types/index.ts';\n\n/**\n * 渲染骨架屏组件\n */\nconst renderSkeleton = () => {\n return h(\"div\", {\n class: \"hitl-skeleton\",\n }, [\n // 头部骨架\n h(\"div\", {\n class: \"skeleton-header\",\n }, [\n h(\"div\", { class: \"skeleton-avatar\" }),\n h(\"div\", { class: \"skeleton-title\" }),\n ]),\n // 内容骨架\n h(\"div\", { class: \"skeleton-item skeleton-item-long\" }),\n h(\"div\", { class: \"skeleton-item skeleton-item-medium\" }),\n h(\"div\", { class: \"skeleton-item skeleton-item-short\" }),\n h(\"div\", { class: \"skeleton-item skeleton-item-long\" }),\n h(\"div\", { class: \"skeleton-item skeleton-item-medium\" }),\n ]);\n};\n\n/**\n * 渲染器配置接口\n */\nexport interface RendererConfig {\n hitlData: Array<Record<string, any>>;\n formRefs: any;\n curIndex: number;\n getCurInit: () => number;\n btnClick: (index: number, action: string, payload: any, parentScope?: 'form' | 'table') => void;\n uploadHeaders: Record<string, string>;\n uploadExtendData: Record<string, any>;\n disabledContext: DisabledCheckContext;\n}\n\n/**\n * 将hast(HTML AST)转换为Vue VNode\n * 性能优化:\n * 1. 使用缓存避免重复计算\n * 2. 延迟子节点渲染(仅在需要时渲染)\n * 3. 优化递归深度\n * \n * @param node - hast节点\n * @param config - 渲染器配置\n * @param index - 表单索引\n * @param row - 表格行数据\n * @returns Vue虚拟节点\n */\nexport const hastToVNode = (\n node: any,\n config: RendererConfig,\n index?: number,\n row?: any\n): any => {\n if (!node) return null;\n\n const {\n hitlData,\n formRefs,\n curIndex,\n getCurInit,\n btnClick,\n uploadHeaders,\n uploadExtendData,\n disabledContext,\n } = config;\n\n // 缓存子节点渲染函数,避免重复计算\n const renderChildren = (children: any[], formIndex?: number) => {\n if (!children || children.length === 0) return [];\n \n // 对于复杂表单,使用批量渲染优化\n // 优先使用传入的 formIndex,如果没有则使用当前的 index\n return children.map((child, idx) => {\n return hastToVNode(child, config, formIndex !== undefined ? formIndex : index, row);\n });\n };\n\n const blackTagNames = ['sub', 'pre', 'text', 'ElForm'];\n let children: any[] = [];\n\n if (!blackTagNames.includes(node.tagName)) {\n // 如果当前节点在表单中(index 是数字),继续传递这个 index 给子节点\n // 这样可以确保表单内的所有子节点(包括按钮)都能获取到正确的表单索引\n children = renderChildren(node.children || [], index);\n }\n\n switch (node.type) {\n case \"root\":\n return h(\n \"div\",\n { class: \"markdown-body\" },\n h(ElConfigProvider, {\n locale: zhCN,\n }, children)\n );\n\n case \"element\":\n // 处理 sub 标签(引用标记)\n if (node.tagName === \"sub\") {\n const formatChildren = [\n {\n type: \"element\",\n tagName: \"span\",\n properties: {\n class: \"x-markdown-split\",\n },\n },\n ...(node.children || [])\n ];\n const subChildren = formatChildren.map(child => hastToVNode(child, config, index));\n return h(\"span\", {\n ...node.properties,\n class: \"x-markdown-sub\",\n }, subChildren);\n }\n\n if (node.tagName === \"span\") {\n return h(\"span\", {\n ...node.properties,\n }, children);\n }\n\n // 处理特殊元素:图片、链接、代码块等\n if (node.tagName === \"img\") {\n return h(\"img\", {\n ...node.properties,\n class: \"markdown-image\",\n \"data-processed\": \"false\"\n });\n }\n\n if (node.tagName === \"a\") {\n const href = node.properties?.href || '';\n const fileType = href ? href.split('.').pop() : null;\n return h(\n \"a\",\n {\n ...node.properties,\n class: 'file-link',\n 'data-file-type': fileType,\n },\n children\n );\n }\n\n if (node.tagName === 'ElTimeline') {\n return h(ElTimeline, {\n ...node.properties,\n }, children);\n }\n\n if (node.tagName === 'table') {\n return h(\n \"div\",\n { class: 'custom-table-container' },\n [h(\"table\", children)]\n );\n }\n\n if (node.tagName === 'view') {\n return h(\n 'div',\n { class: 'custom-view-container' },\n [children[curIndex]]\n );\n }\n\n if (node.tagName === 'ElRow') {\n return h(ElRow, {\n ...node.properties,\n }, children);\n }\n\n if (node.tagName === 'ElCol') {\n return h(ElCol, {\n ...node.properties,\n }, children);\n }\n\n if (node.tagName === 'ElCard') {\n return h(ElCard, {\n ...node.properties,\n }, children);\n }\n\n if (node.tagName === 'ElTag') {\n return h(\n ElTag,\n {\n ...node.properties,\n },\n children\n )\n }\n\n if (node.tagName === 'CoreCard') {\n const slots: any = {};\n \n if (node.slots?.header) {\n slots.header = () => {\n return node.slots.header.map((slotItem: any) => {\n return hastToVNode(slotItem, config, index);\n });\n };\n }\n \n if (children && children.length > 0) {\n slots.default = () => children;\n }\n \n return h(CoreCard, {\n ...node.properties,\n }, slots);\n }\n\n // 表单相关元素\n if (node.tagName === 'ElForm') {\n const formIndex = getCurInit();\n const formChildren = (node.children || []).map((child: any) => \n hastToVNode(child, config, formIndex)\n );\n \n return h(\n ElForm,\n {\n ref: formRefs.set,\n model: hitlData[formIndex],\n ...node.properties,\n disabled: checkDisabled(node as InputSchema, disabledContext),\n },\n formChildren\n );\n }\n\n if (node.tagName === 'ElFormItem') {\n return h(ElFormItem, {\n ...node.properties,\n }, children);\n }\n\n // 表单控件\n if (node.tagName === 'ElButton') {\n let payload = node.properties?.payload;\n if (node.parentScope === 'table') {\n payload = row;\n }\n // 确保按钮在表单中使用正确的表单索引\n // 当 parentScope 是 'form' 时,index 应该是表单索引(从表单渲染时传递下来的)\n // 当 parentScope 不是 'form' 时,index 可能是 undefined 或其他值,但不会用于表单验证\n const buttonFormIndex = node.parentScope === 'form' ? index : undefined;\n return h(\n ElButton,\n {\n ...node.properties,\n disabled: checkDisabled(node as InputSchema, disabledContext),\n onClick: () => {\n // 如果按钮在表单中(parentScope === 'form'),必须使用正确的表单索引进行验证\n // 如果不在表单中,使用 0 作为默认值(但不会触发表单验证,因为 btnClick 会检查 parentScope)\n // 关键:index 在表单渲染时已经正确传递,所以 buttonFormIndex 应该是正确的表单索引\n const validateIndex = buttonFormIndex !== undefined ? buttonFormIndex : (index !== undefined ? index : 0);\n btnClick(validateIndex, node.properties?.action, payload, node.parentScope);\n },\n },\n children\n );\n }\n\n if (node.tagName === 'ElSelect') {\n return h(\n ElSelect,\n {\n ...node.properties,\n disabled: checkDisabled(node as InputSchema, disabledContext),\n modelValue: hitlData[index!]?.[node.properties?.formProp],\n 'onUpdate:modelValue': (value) => {\n if (hitlData[index!]) {\n hitlData[index!][node.properties?.formProp] = value;\n }\n },\n },\n children\n );\n }\n\n if (node.tagName === 'ElDatePicker') {\n return h(\n ElDatePicker,\n {\n ...node.properties,\n disabled: checkDisabled(node as InputSchema, disabledContext),\n modelValue: hitlData[index!]?.[node.properties?.formProp],\n 'onUpdate:modelValue': (value) => {\n if (hitlData[index!]) {\n hitlData[index!][node.properties?.formProp] = value;\n }\n },\n },\n children\n );\n }\n\n if (node.tagName === 'ElInput') {\n return h(\n ElInput,\n {\n ...node.properties,\n disabled: checkDisabled(node as InputSchema, disabledContext),\n modelValue: hitlData[index!]?.[node.properties?.formProp],\n 'onUpdate:modelValue': (value) => {\n if (hitlData[index!]) {\n hitlData[index!][node.properties?.formProp] = value;\n }\n },\n },\n children\n );\n }\n\n if (node.tagName === 'ElRadioGroup') {\n return h(\n ElRadioGroup,\n {\n ...node.properties,\n disabled: checkDisabled(node as InputSchema, disabledContext),\n modelValue: hitlData[index!]?.[node.properties?.formProp],\n 'onUpdate:modelValue': (value) => {\n if (hitlData[index!]) {\n hitlData[index!][node.properties?.formProp] = value as string;\n }\n }\n },\n children\n );\n }\n\n if (node.tagName === 'ElRadio') {\n return h(\n ElRadio,\n {\n ...node.properties,\n disabled: checkDisabled(node as InputSchema, disabledContext),\n },\n children\n );\n }\n\n // 表格相关\n if (node.tagName === 'ElTable') {\n return h(\n CoreTable,\n {\n ...node.properties,\n },\n children\n );\n }\n\n if (node.tagName === 'ElTableColumn') {\n return h(\n ElTableColumn,\n {\n ...node.properties,\n },\n {\n default: (scope: any) => {\n const columnChildren = (node.children || []).map((child: any) => \n hastToVNode(child, config, -Infinity, scope.row)\n );\n const childIndex = (node.children || []).findIndex(\n (child: any) => child.value === scope.row[node.properties?.prop] && child.value !== undefined\n );\n return childIndex === -1 ? columnChildren : columnChildren?.[childIndex];\n },\n }\n );\n }\n\n // 自定义组件\n if (node.tagName === 'CoreText') {\n return h(CoreText, {\n ...node.properties,\n });\n }\n\n if (node.tagName === 'CoreTips') {\n return h(CoreTips, {\n ...node.properties,\n });\n }\n\n if (node.tagName === 'CoreResult') {\n return h(CoreResult, {\n ...node.properties,\n });\n }\n\n if (node.tagName === 'CoreChart') {\n return h(CoreChart, {\n ...node.properties,\n });\n }\n\n if (node.tagName === 'CoreUpload') {\n // 如果在表单中,需要处理 formProp 和双向绑定\n if (node.parentScope === 'form' && node.properties?.formProp) {\n const formProp = node.properties.formProp;\n return h(\n CoreUpload,\n {\n headers: uploadHeaders,\n extendData: uploadExtendData,\n ...node.properties,\n disabled: checkDisabled(node as InputSchema, disabledContext),\n fileList: hitlData[index!]?.[formProp] || [],\n 'onUpdate:fileList': (value: any) => {\n if (!hitlData[index!]) {\n hitlData[index!] = {};\n }\n // 针对目前上传的文件解析,CA 这边必须得放在files 属性中,故被迫需要进行兼容\n // 这里将基于 __files__ 去识别,后续在coreagent 的 adapter 中进行处理\n if (!hitlData[index!].__files__) {\n hitlData[index!].__files__ = {};\n }\n hitlData[index!].__files__[formProp] = value;\n hitlData[index!][formProp] = value;\n },\n }\n );\n }\n // 非表单场景,直接渲染\n return h(\n CoreUpload,\n {\n ...node.properties,\n disabled: checkDisabled(node as InputSchema, disabledContext),\n }\n );\n }\n\n // 处理CorePilot代码块\n if (node.tagName === \"pre\") {\n const codeNode = node.children?.find((child: any) => child.tagName === \"code\");\n if (codeNode) {\n if (codeNode.properties?.className?.includes(\"language-CorePilot\")) {\n const code = codeNode.children?.[0]?.value || '';\n // 检查 JSON 是否完整\n if (!isCompleteJSON(code)) {\n // JSON 不完整,显示骨架屏\n return renderSkeleton();\n }\n try {\n const schema = JSON.parse(code);\n const viewTree = parseCorePilot(schema);\n const corePilotChildren = hastToVNode(viewTree, config);\n return h(\"div\", {\n class: \"hitl-wrapper\",\n }, [corePilotChildren]);\n } catch (error) {\n // JSON 解析失败,可能是格式错误,显示骨架屏\n return renderSkeleton();\n }\n }\n }\n }\n\n // 其他普通元素\n return h(\n node.tagName,\n node.properties,\n children\n );\n\n case \"text\":\n return node.value.trim();\n\n default:\n return null;\n }\n};\n\n"],"names":["children","zhCN","_a"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const checkDisabled = (node, context) => {
|
|
2
|
+
const { properties = {}, parentScope } = node;
|
|
3
|
+
const { disabled } = properties;
|
|
4
|
+
if (disabled) {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
if (parentScope === "form") {
|
|
8
|
+
return context.isHistoryMessage && !context.isRewrite;
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
checkDisabled
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=disabledUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disabledUtils.js","sources":["../../../../../src/components/x-markdown/utils/disabledUtils.ts"],"sourcesContent":["/**\n * 禁用状态相关工具函数\n * 规范了组件禁用状态的判断逻辑\n */\n\nimport { InputSchema } from '@/types/index.ts';\n\nexport interface DisabledCheckContext {\n isHistoryMessage: boolean;\n isRewrite: boolean;\n}\n\n/**\n * 检查节点是否应该被禁用\n * \n * 规范说明:\n * - 如果节点本身设置了 disabled 属性,则禁用\n * - 如果节点在 form 作用域内,且是历史消息且未处于重写状态,则禁用\n * - 其他情况不禁用\n * \n * @param node - 输入节点 schema\n * @param context - 禁用检查上下文\n * @returns 是否应该禁用\n */\nexport const checkDisabled = (\n node: InputSchema,\n context: DisabledCheckContext\n): boolean => {\n const { properties = {}, parentScope } = node;\n const { disabled } = properties;\n \n // 如果节点本身设置了 disabled,则禁用\n if (disabled) {\n return true;\n }\n \n // 如果当前是历史消息,且父级作用域为 form,且未处于重写状态,则禁用\n if (parentScope === 'form') {\n return context.isHistoryMessage && !context.isRewrite;\n }\n \n return false;\n};\n\n"],"names":[],"mappings":"AAwBO,MAAM,gBAAgB,CAC3B,MACA,YACY;AACZ,QAAM,EAAE,aAAa,IAAI,gBAAgB;AACzC,QAAM,EAAE,aAAa;AAGrB,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AAGA,MAAI,gBAAgB,QAAQ;AAC1B,WAAO,QAAQ,oBAAoB,CAAC,QAAQ;AAAA,EAC9C;AAEA,SAAO;AACT;"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const collectFormsFromSchema = (schema, formDataList, formIndex = 0, historyInputsMap) => {
|
|
2
|
+
var _a;
|
|
3
|
+
if (!schema || typeof schema !== "object") return formIndex;
|
|
4
|
+
if (schema.type === "form") {
|
|
5
|
+
const formData = {
|
|
6
|
+
...((_a = schema.properties) == null ? void 0 : _a.data) || {},
|
|
7
|
+
// 支持多表单场景:根据表单索引获取对应的 historyInputs
|
|
8
|
+
...(historyInputsMap == null ? void 0 : historyInputsMap[formIndex]) || {}
|
|
9
|
+
};
|
|
10
|
+
formDataList.push(formData);
|
|
11
|
+
return formIndex + 1;
|
|
12
|
+
}
|
|
13
|
+
if (Array.isArray(schema.children)) {
|
|
14
|
+
let currentFormIndex = formIndex;
|
|
15
|
+
schema.children.forEach((child) => {
|
|
16
|
+
currentFormIndex = collectFormsFromSchema(
|
|
17
|
+
child,
|
|
18
|
+
formDataList,
|
|
19
|
+
currentFormIndex,
|
|
20
|
+
historyInputsMap
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
return currentFormIndex;
|
|
24
|
+
}
|
|
25
|
+
return formIndex;
|
|
26
|
+
};
|
|
27
|
+
const computedForm = (mdAst, historyInputsMap) => {
|
|
28
|
+
const formDataList = [];
|
|
29
|
+
const preNodes = [];
|
|
30
|
+
const findPreNodes = (node) => {
|
|
31
|
+
if (!node) return;
|
|
32
|
+
if (node.tagName === "pre") {
|
|
33
|
+
preNodes.push(node);
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(node.children)) {
|
|
36
|
+
node.children.forEach(findPreNodes);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
if (Array.isArray(mdAst.children)) {
|
|
40
|
+
mdAst.children.forEach(findPreNodes);
|
|
41
|
+
}
|
|
42
|
+
preNodes.forEach((preNode) => {
|
|
43
|
+
var _a, _b, _c, _d, _e;
|
|
44
|
+
const codeNode = (_a = preNode.children) == null ? void 0 : _a.find((child) => child.tagName === "code");
|
|
45
|
+
if ((_c = (_b = codeNode == null ? void 0 : codeNode.properties) == null ? void 0 : _b.className) == null ? void 0 : _c.includes("language-CorePilot")) {
|
|
46
|
+
try {
|
|
47
|
+
const code = ((_e = (_d = codeNode.children) == null ? void 0 : _d[0]) == null ? void 0 : _e.value) || "";
|
|
48
|
+
if (code) {
|
|
49
|
+
const schema = JSON.parse(code);
|
|
50
|
+
collectFormsFromSchema(schema, formDataList, 0, historyInputsMap);
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error("Failed to parse CorePilot schema:", error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return formDataList;
|
|
58
|
+
};
|
|
59
|
+
const normalizeHistoryInputs = (historyInputs) => {
|
|
60
|
+
if (!historyInputs) return void 0;
|
|
61
|
+
if (typeof historyInputs === "object" && !Array.isArray(historyInputs)) {
|
|
62
|
+
const keys = Object.keys(historyInputs);
|
|
63
|
+
const isFormDataMap = keys.some((key) => /^\d+$/.test(key));
|
|
64
|
+
if (isFormDataMap) {
|
|
65
|
+
const result = {};
|
|
66
|
+
keys.forEach((key) => {
|
|
67
|
+
const numKey = parseInt(key, 10);
|
|
68
|
+
if (!isNaN(numKey)) {
|
|
69
|
+
result[numKey] = historyInputs[key];
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { 0: historyInputs };
|
|
76
|
+
};
|
|
77
|
+
export {
|
|
78
|
+
collectFormsFromSchema,
|
|
79
|
+
computedForm,
|
|
80
|
+
normalizeHistoryInputs
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=formUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formUtils.js","sources":["../../../../../src/components/x-markdown/utils/formUtils.ts"],"sourcesContent":["/**\n * 表单相关工具函数\n */\n\n/**\n * 表单数据映射接口\n * 用于支持多表单场景,每个表单可以有独立的 historyInputs\n */\nexport interface FormDataMap {\n [formIndex: number]: Record<string, any>;\n}\n\n/**\n * 递归遍历 schema,收集所有 form 表单及其 data 属性\n * 支持多表单场景:每个表单可以有独立的 historyInputs\n * \n * @param schema - CorePilot schema 对象\n * @param formDataList - 用于存储收集到的 form data 的数组\n * @param formIndex - 当前表单索引(用于多表单场景)\n * @param historyInputsMap - 历史输入映射,支持多表单场景\n * @returns void\n */\nexport const collectFormsFromSchema = (\n schema: any,\n formDataList: Array<Record<string, any>>,\n formIndex: number = 0,\n historyInputsMap?: FormDataMap\n): number => {\n if (!schema || typeof schema !== 'object') return formIndex;\n \n // 如果当前节点是 form,收集其 data 属性\n if (schema.type === 'form') {\n const formData = {\n ...schema.properties?.data || {},\n // 支持多表单场景:根据表单索引获取对应的 historyInputs\n ...(historyInputsMap?.[formIndex] || {}),\n };\n formDataList.push(formData);\n return formIndex + 1; // 返回下一个表单索引\n }\n \n // 递归遍历 children 数组\n if (Array.isArray(schema.children)) {\n let currentFormIndex = formIndex;\n schema.children.forEach((child) => {\n currentFormIndex = collectFormsFromSchema(\n child,\n formDataList,\n currentFormIndex,\n historyInputsMap\n );\n });\n return currentFormIndex;\n }\n \n return formIndex;\n};\n\n/**\n * 计算 markdown AST 中所有 form 表单的数量,并提取每个 form 的预定义数据\n * 支持多表单场景\n * \n * @param mdAst - markdown AST 对象\n * @param historyInputsMap - 历史输入映射,支持多表单场景\n * @returns form data 列表\n */\nexport const computedForm = (\n mdAst: any,\n historyInputsMap?: FormDataMap\n): Array<Record<string, any>> => {\n const formDataList: Array<Record<string, any>> = [];\n \n // 高效检索:直接查找所有 pre 标签\n const preNodes: any[] = [];\n const findPreNodes = (node: any) => {\n if (!node) return;\n if (node.tagName === \"pre\") {\n preNodes.push(node);\n }\n if (Array.isArray(node.children)) {\n node.children.forEach(findPreNodes);\n }\n };\n \n // 遍历 mdAst 查找所有 pre 节点\n if (Array.isArray(mdAst.children)) {\n mdAst.children.forEach(findPreNodes);\n }\n \n // 处理每个 pre 节点中的 CorePilot 代码块\n preNodes.forEach((preNode: any) => {\n const codeNode = preNode.children?.find((child: any) => child.tagName === \"code\");\n if (codeNode?.properties?.className?.includes(\"language-CorePilot\")) {\n try {\n const code = codeNode.children?.[0]?.value || '';\n if (code) {\n const schema = JSON.parse(code);\n // 递归收集所有 form,支持多表单场景\n collectFormsFromSchema(schema, formDataList, 0, historyInputsMap);\n }\n } catch (error) {\n console.error('Failed to parse CorePilot schema:', error);\n }\n }\n });\n \n return formDataList;\n};\n\n/**\n * 将单个 historyInputs 对象转换为表单索引映射\n * 用于向后兼容:如果传入的是单个对象,则将其映射到第一个表单\n * \n * @param historyInputs - 历史输入对象(单个或多个)\n * @returns 表单数据映射\n */\nexport const normalizeHistoryInputs = (\n historyInputs?: Record<string, any> | FormDataMap\n): FormDataMap | undefined => {\n if (!historyInputs) return undefined;\n \n // 如果已经是 FormDataMap 格式,直接返回\n if (typeof historyInputs === 'object' && !Array.isArray(historyInputs)) {\n // 检查是否是 FormDataMap 格式(键是数字字符串)\n const keys = Object.keys(historyInputs);\n const isFormDataMap = keys.some(key => /^\\d+$/.test(key));\n \n if (isFormDataMap) {\n // 转换为数字键\n const result: FormDataMap = {};\n keys.forEach(key => {\n const numKey = parseInt(key, 10);\n if (!isNaN(numKey)) {\n result[numKey] = historyInputs[key];\n }\n });\n return result;\n }\n }\n \n // 向后兼容:单个对象映射到第一个表单\n return { 0: historyInputs as Record<string, any> };\n};\n\n"],"names":[],"mappings":"AAsBO,MAAM,yBAAyB,CACpC,QACA,cACA,YAAoB,GACpB,qBACW;AALN;AAML,MAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAGlD,MAAI,OAAO,SAAS,QAAQ;AAC1B,UAAM,WAAW;AAAA,MACf,KAAG,YAAO,eAAP,mBAAmB,SAAQ,CAAA;AAAA;AAAA,MAE9B,IAAI,qDAAmB,eAAc,CAAA;AAAA,IAAC;AAExC,iBAAa,KAAK,QAAQ;AAC1B,WAAO,YAAY;AAAA,EACrB;AAGA,MAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG;AAClC,QAAI,mBAAmB;AACvB,WAAO,SAAS,QAAQ,CAAC,UAAU;AACjC,yBAAmB;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,CAAC;AACD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAUO,MAAM,eAAe,CAC1B,OACA,qBAC+B;AAC/B,QAAM,eAA2C,CAAA;AAGjD,QAAM,WAAkB,CAAA;AACxB,QAAM,eAAe,CAAC,SAAc;AAClC,QAAI,CAAC,KAAM;AACX,QAAI,KAAK,YAAY,OAAO;AAC1B,eAAS,KAAK,IAAI;AAAA,IACpB;AACA,QAAI,MAAM,QAAQ,KAAK,QAAQ,GAAG;AAChC,WAAK,SAAS,QAAQ,YAAY;AAAA,IACpC;AAAA,EACF;AAGA,MAAI,MAAM,QAAQ,MAAM,QAAQ,GAAG;AACjC,UAAM,SAAS,QAAQ,YAAY;AAAA,EACrC;AAGA,WAAS,QAAQ,CAAC,YAAiB;AApE9B;AAqEH,UAAM,YAAW,aAAQ,aAAR,mBAAkB,KAAK,CAAC,UAAe,MAAM,YAAY;AAC1E,SAAI,gDAAU,eAAV,mBAAsB,cAAtB,mBAAiC,SAAS,uBAAuB;AACnE,UAAI;AACF,cAAM,SAAO,oBAAS,aAAT,mBAAoB,OAApB,mBAAwB,UAAS;AAC9C,YAAI,MAAM;AACR,gBAAM,SAAS,KAAK,MAAM,IAAI;AAE9B,iCAAuB,QAAQ,cAAc,GAAG,gBAAgB;AAAA,QAClE;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,qCAAqC,KAAK;AAAA,MAC1D;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AASO,MAAM,yBAAyB,CACpC,kBAC4B;AAC5B,MAAI,CAAC,cAAe,QAAO;AAG3B,MAAI,OAAO,kBAAkB,YAAY,CAAC,MAAM,QAAQ,aAAa,GAAG;AAEtE,UAAM,OAAO,OAAO,KAAK,aAAa;AACtC,UAAM,gBAAgB,KAAK,KAAK,SAAO,QAAQ,KAAK,GAAG,CAAC;AAExD,QAAI,eAAe;AAEjB,YAAM,SAAsB,CAAA;AAC5B,WAAK,QAAQ,CAAA,QAAO;AAClB,cAAM,SAAS,SAAS,KAAK,EAAE;AAC/B,YAAI,CAAC,MAAM,MAAM,GAAG;AAClB,iBAAO,MAAM,IAAI,cAAc,GAAG;AAAA,QACpC;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAGA,SAAO,EAAE,GAAG,cAAA;AACd;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const isCompleteJSON = (jsonStr) => {
|
|
2
|
+
if (!jsonStr || jsonStr.trim().length === 0) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
const trimmed = jsonStr.trim();
|
|
6
|
+
const firstChar = trimmed[0];
|
|
7
|
+
if (firstChar !== "{" && firstChar !== "[") {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
JSON.parse(trimmed);
|
|
12
|
+
return true;
|
|
13
|
+
} catch (error) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
isCompleteJSON
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=jsonUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonUtils.js","sources":["../../../../../src/components/x-markdown/utils/jsonUtils.ts"],"sourcesContent":["/**\n * JSON 相关工具函数\n */\n\n/**\n * 检测 JSON 字符串是否完整\n * 使用最高效的方式:快速检查基本结构后直接尝试解析\n */\nexport const isCompleteJSON = (jsonStr: string): boolean => {\n if (!jsonStr || jsonStr.trim().length === 0) {\n return false;\n }\n \n const trimmed = jsonStr.trim();\n \n // 快速检查:必须以 { 或 [ 开头\n const firstChar = trimmed[0];\n if (firstChar !== '{' && firstChar !== '[') {\n return false;\n }\n \n // 直接尝试解析,如果成功就是完整的 JSON\n try {\n JSON.parse(trimmed);\n return true;\n } catch (error) {\n // 解析失败,说明 JSON 不完整或格式错误\n return false;\n }\n};\n\n"],"names":[],"mappings":"AAQO,MAAM,iBAAiB,CAAC,YAA6B;AAC1D,MAAI,CAAC,WAAW,QAAQ,KAAA,EAAO,WAAW,GAAG;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,QAAQ,KAAA;AAGxB,QAAM,YAAY,QAAQ,CAAC;AAC3B,MAAI,cAAc,OAAO,cAAc,KAAK;AAC1C,WAAO;AAAA,EACT;AAGA,MAAI;AACF,SAAK,MAAM,OAAO;AAClB,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,WAAO;AAAA,EACT;AACF;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const checkAndReturnRefList = (text) => {
|
|
2
|
+
const reg = /<div hidden>([\s\S]*?)<\/div>/g;
|
|
3
|
+
const match = reg.exec(text);
|
|
4
|
+
if (!match) {
|
|
5
|
+
return [];
|
|
6
|
+
}
|
|
7
|
+
const refListStr = match[1];
|
|
8
|
+
try {
|
|
9
|
+
const refList = JSON.parse(refListStr);
|
|
10
|
+
return refList;
|
|
11
|
+
} catch (error) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
checkAndReturnRefList
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=refUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refUtils.js","sources":["../../../../../src/components/x-markdown/utils/refUtils.ts"],"sourcesContent":["/**\n * 引用相关工具函数\n */\n\nexport interface RefConfig {\n title: string;\n link: string;\n time: string;\n author: string;\n}\n\n/**\n * 从文本中提取引用列表\n */\nexport const checkAndReturnRefList = (text: string): RefConfig[] => {\n const reg = /<div hidden>([\\s\\S]*?)<\\/div>/g;\n const match = reg.exec(text);\n if (!match) {\n return [];\n }\n const refListStr = match[1];\n try {\n const refList = JSON.parse(refListStr);\n return refList;\n } catch (error) {\n return [];\n }\n};\n\n"],"names":[],"mappings":"AAcO,MAAM,wBAAwB,CAAC,SAA8B;AAClE,QAAM,MAAM;AACZ,QAAM,QAAQ,IAAI,KAAK,IAAI;AAC3B,MAAI,CAAC,OAAO;AACV,WAAO,CAAA;AAAA,EACT;AACA,QAAM,aAAa,MAAM,CAAC;AAC1B,MAAI;AACF,UAAM,UAAU,KAAK,MAAM,UAAU;AACrC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,CAAA;AAAA,EACT;AACF;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { checkAndReturnRefList } from "./refUtils.js";
|
|
2
|
+
const updateSummaryClasses = (mdText) => {
|
|
3
|
+
const summaryDivReg = /(<summary[^>]*>[\s\S]*?<\/summary>)\s*(<div>[\s\S]*?)(<\/div>|$)/g;
|
|
4
|
+
let isFirstSummary = true;
|
|
5
|
+
return mdText.replace(summaryDivReg, (match, summaryTag, divContent, divEnd) => {
|
|
6
|
+
const isDivComplete = divEnd === "</div>";
|
|
7
|
+
const updatedSummary = summaryTag.replace(
|
|
8
|
+
/(<summary)/g,
|
|
9
|
+
(match2) => {
|
|
10
|
+
if (isFirstSummary) {
|
|
11
|
+
isFirstSummary = false;
|
|
12
|
+
return match2;
|
|
13
|
+
}
|
|
14
|
+
return `<summary class="${isDivComplete ? "loaded" : "loading"}"`;
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
return `${updatedSummary}
|
|
18
|
+
${divContent}${divEnd}`;
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
const formatMarkdownText = (content, autoHideThinking, startTime, endTime) => {
|
|
22
|
+
if (!autoHideThinking) return content;
|
|
23
|
+
let formatted = content;
|
|
24
|
+
formatted = updateSummaryClasses(formatted);
|
|
25
|
+
formatted = formatted.replace(/[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g, " ");
|
|
26
|
+
if (formatted.includes("</details>")) {
|
|
27
|
+
const res = checkAndReturnRefList(formatted);
|
|
28
|
+
const text = formatted.replace(/<details open>([\s\S]*?)<\/details>/g, (match, content2) => {
|
|
29
|
+
content2 = content2.replace(/<summary>([\s\S]*?)<\/summary>/, (match2, content3) => {
|
|
30
|
+
const duration = ((endTime - startTime) / 1e3).toFixed(0);
|
|
31
|
+
return `<summary style="color: #8D90A0;font-weight: 300; font-size: 16px;">
|
|
32
|
+
已完成思考 ${duration > "0" ? duration + "s" : ""} ${res.length ? `<span style="display: inline-block;margin: 0 8px;border-left: 1px solid #CDCFD7;width: 1px;height: 16px;"></span> 引用文档:${res == null ? void 0 : res.length} 个` : ""}
|
|
33
|
+
</summary>`;
|
|
34
|
+
});
|
|
35
|
+
content2 = content2.replace(/<summary>完成<\/summary>/, '<summary class="loaded">完成</summary>');
|
|
36
|
+
return `<details>${content2}</details>`;
|
|
37
|
+
});
|
|
38
|
+
return text;
|
|
39
|
+
}
|
|
40
|
+
return formatted;
|
|
41
|
+
};
|
|
42
|
+
export {
|
|
43
|
+
formatMarkdownText,
|
|
44
|
+
updateSummaryClasses
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=textFormatUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textFormatUtils.js","sources":["../../../../../src/components/x-markdown/utils/textFormatUtils.ts"],"sourcesContent":["/**\n * 文本格式化相关工具函数\n */\n\nimport { checkAndReturnRefList } from './refUtils';\n\n/**\n * 更新 summary 标签的 class\n */\nexport const updateSummaryClasses = (mdText: string): string => {\n const summaryDivReg = /(<summary[^>]*>[\\s\\S]*?<\\/summary>)\\s*(<div>[\\s\\S]*?)(<\\/div>|$)/g;\n let isFirstSummary = true;\n\n return mdText.replace(summaryDivReg, (match, summaryTag, divContent, divEnd) => {\n const isDivComplete = divEnd === '</div>'; // 直接判断闭合标签是否存在\n const updatedSummary = summaryTag.replace(\n /(<summary)/g,\n (match) => {\n if (isFirstSummary) {\n isFirstSummary = false;\n return match;\n }\n return `<summary class=\"${isDivComplete ? 'loaded' : 'loading'}\"`\n }\n );\n return `${updatedSummary}\\n${divContent}${divEnd}`; // 重组时拼接闭合部分\n });\n};\n\n/**\n * 格式化文本,处理思考过程、引用等\n */\nexport const formatMarkdownText = (\n content: string,\n autoHideThinking: boolean,\n startTime: number,\n endTime: number\n): string => {\n if (!autoHideThinking) return content;\n \n let formatted = content;\n formatted = updateSummaryClasses(formatted);\n formatted = formatted.replace(/[\\u00A0\\u1680\\u2000-\\u200A\\u202F\\u205F\\u3000]/g, ' ');\n \n if (formatted.includes('</details>')) {\n const res = checkAndReturnRefList(formatted);\n\n const text = formatted.replace(/<details open>([\\s\\S]*?)<\\/details>/g, (match, content) => {\n // 将 content 中的第一个 <summary> 中的内容替换为 具体的秒数\n content = content.replace(/<summary>([\\s\\S]*?)<\\/summary>/, (match, content) => {\n const duration = ((endTime - startTime) / 1000).toFixed(0);\n return `<summary style=\"color: #8D90A0;font-weight: 300; font-size: 16px;\">\n 已完成思考 ${duration > '0' ? duration + 's' : ''} ${res.length ? `<span style=\"display: inline-block;margin: 0 8px;border-left: 1px solid #CDCFD7;width: 1px;height: 16px;\"></span> 引用文档:${res?.length} 个` : ''}\n </summary>`;\n })\n\n content = content.replace(/<summary>完成<\\/summary>/, '<summary class=\"loaded\">完成</summary>')\n\n return `<details>${content}</details>`;\n });\n \n return text;\n }\n \n return formatted;\n};\n\n"],"names":["match","content"],"mappings":";AASO,MAAM,uBAAuB,CAAC,WAA2B;AAC9D,QAAM,gBAAgB;AACtB,MAAI,iBAAiB;AAErB,SAAO,OAAO,QAAQ,eAAe,CAAC,OAAO,YAAY,YAAY,WAAW;AAC9E,UAAM,gBAAgB,WAAW;AACjC,UAAM,iBAAiB,WAAW;AAAA,MAChC;AAAA,MACA,CAACA,WAAU;AACT,YAAI,gBAAgB;AAClB,2BAAiB;AACjB,iBAAOA;AAAAA,QACT;AACA,eAAO,mBAAmB,gBAAgB,WAAW,SAAS;AAAA,MAChE;AAAA,IAAA;AAEF,WAAO,GAAG,cAAc;AAAA,EAAK,UAAU,GAAG,MAAM;AAAA,EAClD,CAAC;AACH;AAKO,MAAM,qBAAqB,CAChC,SACA,kBACA,WACA,YACW;AACX,MAAI,CAAC,iBAAkB,QAAO;AAE9B,MAAI,YAAY;AAChB,cAAY,qBAAqB,SAAS;AAC1C,cAAY,UAAU,QAAQ,kDAAkD,GAAG;AAEnF,MAAI,UAAU,SAAS,YAAY,GAAG;AACpC,UAAM,MAAM,sBAAsB,SAAS;AAE3C,UAAM,OAAO,UAAU,QAAQ,wCAAwC,CAAC,OAAOC,aAAY;AAEzFA,iBAAUA,SAAQ,QAAQ,kCAAkC,CAACD,QAAOC,aAAY;AAC9E,cAAM,aAAa,UAAU,aAAa,KAAM,QAAQ,CAAC;AACzD,eAAO;AAAA,kBACG,WAAW,MAAM,WAAW,MAAM,EAAE,IAAI,IAAI,SAAS,0HAA0H,2BAAK,MAAM,OAAO,EAAE;AAAA;AAAA,MAE/M,CAAC;AAEDA,iBAAUA,SAAQ,QAAQ,0BAA0B,sCAAsC;AAE1F,aAAO,YAAYA,QAAO;AAAA,IAC5B,CAAC;AAED,WAAO;AAAA,EACT;AAEA,SAAO;AACT;"}
|