@freecallai/pro 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +23 -17
  2. package/dist/FkpKnowledgeTypePicker.vue_vue_type_script_setup_true_lang-xR8ZhhdJ.js +187 -0
  3. package/dist/FkpRichText.vue_vue_type_script_setup_true_lang-CaHRIHab.js +4864 -0
  4. package/dist/KnowledgeArea-_rsydhnt.js +1438 -0
  5. package/dist/{ToolForm-CWpUIVTl.js → ToolForm-Czg67cDT.js} +1 -1
  6. package/dist/{choice-DDg5gNtS.js → choice-Bt2xhoN_.js} +1 -1
  7. package/dist/edition-info/index.js +4 -0
  8. package/dist/filters/index.js +7 -0
  9. package/dist/guard-B7U3S4F1.js +1163 -0
  10. package/dist/{index-D8bcFtWR.js → index-9NM1SHoR.js} +1 -1
  11. package/dist/index-B4-2_sJI.js +10 -0
  12. package/dist/{index-DOEijEGU.js → index-BBv72oZe.js} +10 -10
  13. package/dist/index-BF6MRSMb.js +6 -0
  14. package/dist/index-BQrYBmwR.js +5 -0
  15. package/dist/index-CS2xQQ8W.js +168 -0
  16. package/dist/index-D0bJAQSN.js +327 -0
  17. package/dist/index-D9yqpH_4.js +57 -0
  18. package/dist/index-DCmHHi07.js +71 -0
  19. package/dist/index-DYeJRJY1.js +6 -0
  20. package/dist/{index-CJlAseSN.js → index-DnaEbb6l.js} +1 -1
  21. package/dist/{index-DSgEWJGP.js → index-Dy2Gy3bL.js} +1 -1
  22. package/dist/index-lNhA3N9x.js +379 -0
  23. package/dist/{index-5a9mHHzg.js → index-sjDmbR5o.js} +1 -1
  24. package/dist/index-trxE5T0w.js +6 -0
  25. package/dist/index-uCVrA6xK.js +5 -0
  26. package/dist/index.js +36 -11
  27. package/dist/inline-KPGqYMIR.js +19 -0
  28. package/dist/knowledge-CupkY2rK.js +6 -0
  29. package/dist/{knowledge-DnYGicjn.js → knowledge-DzwXQR-q.js} +1 -1
  30. package/dist/knowledge-type-picker/index.js +5 -0
  31. package/dist/media-extensions-DhRlLKYM.js +321 -0
  32. package/dist/{media-migration-CGOFwdYm.js → media-migration-CbMT2wS0.js} +1 -1
  33. package/dist/{media-upload-Dx45yv6a.js → media-upload-P9WeUHHr.js} +1 -1
  34. package/dist/navigation/index.js +4 -0
  35. package/dist/operations-D8pn-_iW.js +20 -0
  36. package/dist/{question-DGC6JHy5.js → question-C7akkjHn.js} +1 -1
  37. package/dist/{question-D1--acV8.js → question-DXZ8R-34.js} +1 -1
  38. package/dist/rich-text/index.js +57 -53
  39. package/dist/rich-text/legacy-converter/index.js +1271 -340
  40. package/dist/style.css +1 -1
  41. package/dist/switcher/index.js +4 -0
  42. package/dist/types/edition-info/FkpEditionInfo.vue.d.ts +5 -0
  43. package/dist/types/edition-info/index.d.ts +2 -0
  44. package/dist/types/edition-info/types.d.ts +5 -0
  45. package/dist/types/filters/FkpFilter.vue.d.ts +20 -0
  46. package/dist/types/filters/FkpFilterDateRange.vue.d.ts +13 -0
  47. package/dist/types/filters/FkpFilterPeriod.vue.d.ts +17 -0
  48. package/dist/types/filters/FkpSearchableMultiSelect.vue.d.ts +44 -0
  49. package/dist/types/filters/index.d.ts +5 -0
  50. package/dist/types/filters/selection.d.ts +5 -0
  51. package/dist/types/filters/types.d.ts +30 -0
  52. package/dist/types/index.d.ts +7 -1
  53. package/dist/types/knowledge-type-picker/index.d.ts +3 -0
  54. package/dist/types/navigation/FkpNavigation.vue.d.ts +51 -0
  55. package/dist/types/navigation/index.d.ts +2 -0
  56. package/dist/types/navigation/types.d.ts +15 -0
  57. package/dist/types/rich-text/FkpRichText.vue.d.ts +31 -7
  58. package/dist/types/rich-text/__demo__/conversion-fixtures.d.ts +2 -2
  59. package/dist/types/rich-text/__demo__/reasoning-template-examples.d.ts +11 -0
  60. package/dist/types/rich-text/config/descriptor.d.ts +25 -2
  61. package/dist/types/rich-text/config/resolve.d.ts +2 -0
  62. package/dist/types/rich-text/index.d.ts +3 -1
  63. package/dist/types/rich-text/legacy-converter/agent-prompt-preview.d.ts +2 -0
  64. package/dist/types/rich-text/legacy-converter/business-attribute.d.ts +12 -0
  65. package/dist/types/rich-text/legacy-converter/index.d.ts +8 -0
  66. package/dist/types/rich-text/legacy-converter/tool-contract.d.ts +1 -0
  67. package/dist/types/rich-text/model/guard.d.ts +2 -1
  68. package/dist/types/rich-text/model/node-contract.d.ts +3 -5
  69. package/dist/types/rich-text/model/node-identity.d.ts +7 -1
  70. package/dist/types/rich-text/model/question-text.d.ts +2 -4
  71. package/dist/types/rich-text/plugins/attribute/token.d.ts +9 -0
  72. package/dist/types/rich-text/plugins/operations.d.ts +9 -0
  73. package/dist/types/rich-text/plugins/reasoningTemplate/defaults.d.ts +14 -0
  74. package/dist/types/rich-text/plugins/reasoningTemplate/examples.d.ts +9 -0
  75. package/dist/types/rich-text/plugins/separator/token.d.ts +2 -0
  76. package/dist/types/rich-text/plugins/tableKnowledge/descriptor.d.ts +2 -0
  77. package/dist/types/rich-text/plugins/tableKnowledge/index.d.ts +2 -0
  78. package/dist/types/rich-text/plugins/tableKnowledge/token.d.ts +9 -0
  79. package/dist/types/rich-text/plugins/ticket/protocol.d.ts +8 -0
  80. package/dist/types/rich-text/plugins/ticket/token.d.ts +9 -0
  81. package/dist/types/rich-text/plugins/todo/token.d.ts +3 -0
  82. package/dist/types/rich-text/plugins/token-catalog.d.ts +46 -0
  83. package/dist/types/rich-text/plugins/token-definition.d.ts +24 -0
  84. package/dist/types/rich-text/plugins/tool/presentation.d.ts +2 -1
  85. package/dist/types/rich-text/plugins/tool/protocol.d.ts +5 -0
  86. package/dist/types/rich-text/plugins/tool/rules.d.ts +35 -0
  87. package/dist/types/rich-text/plugins/tool/token.d.ts +2 -0
  88. package/dist/types/rich-text/plugins/variable/token.d.ts +2 -0
  89. package/dist/types/rich-text/public/types.d.ts +73 -6
  90. package/dist/types/rich-text/runtime/action-ports.d.ts +6 -1
  91. package/dist/types/rich-text/runtime/file-drop-guard.d.ts +2 -0
  92. package/dist/types/rich-text/runtime/knowledge-clipboard.d.ts +16 -0
  93. package/dist/types/rich-text/runtime/media-policy.d.ts +15 -0
  94. package/dist/types/rich-text/runtime/media-target.d.ts +3 -0
  95. package/dist/types/rich-text/runtime/media-upload-session.d.ts +5 -1
  96. package/dist/types/rich-text/runtime/media-upload-slots.d.ts +4 -0
  97. package/dist/types/rich-text/runtime/schema-plan.d.ts +1 -0
  98. package/dist/types/rich-text/types.d.ts +3 -40
  99. package/dist/types/rich-text/ui/FkpKnowledgeTypePicker.vue.d.ts +38 -0
  100. package/dist/types/rich-text/ui/KnowledgeArea.vue.d.ts +12 -1
  101. package/dist/types/rich-text/ui/knowledge-type-picker-types.d.ts +14 -0
  102. package/dist/types/rich-text/ui/token-renderer.d.ts +5 -0
  103. package/dist/types/switcher/FkpSwitcher.vue.d.ts +52 -0
  104. package/dist/types/switcher/index.d.ts +2 -0
  105. package/dist/types/switcher/types.d.ts +7 -0
  106. package/package.json +26 -6
  107. package/dist/FkpRichText.vue_vue_type_script_setup_true_lang-DnknqQTh.js +0 -4115
  108. package/dist/KnowledgeArea-OPR7smbt.js +0 -923
  109. package/dist/guard-BCatAeT4.js +0 -749
  110. package/dist/index-BsQLwz91.js +0 -5
  111. package/dist/index-CzpY61Qj.js +0 -6
  112. package/dist/index-DxxX09iY.js +0 -6
  113. package/dist/index-nnvfy5q0.js +0 -31
  114. package/dist/index-urNonkMH.js +0 -6
  115. package/dist/index-xAjlBylT.js +0 -5
  116. package/dist/inline-TT_dl8Y3.js +0 -17
  117. package/dist/knowledge-BZCmalF_.js +0 -6
  118. package/dist/media-extensions-ZoxmhIhH.js +0 -276
  119. package/dist/operations-JgnjGx3H.js +0 -19
@@ -1,87 +1,368 @@
1
- import { h as et, b as tt, j as nt } from "../../guard-BCatAeT4.js";
2
- import { a as at } from "../../media-migration-CGOFwdYm.js";
3
- function a(t, u, i) {
4
- return { ok: !1, issues: [{ path: u, message: i }], raw: t };
1
+ import { b as wt, h as Mt, c as Et, d as zt, e as Nt, j as It, k as St, l as Ht } from "../../guard-B7U3S4F1.js";
2
+ import { a as jt } from "../../media-migration-CbMT2wS0.js";
3
+ const Pt = [
4
+ { id: 1, key: "focus_goods_name", name: "焦点商品名称" },
5
+ { id: 2, key: "focus_goods_info", name: "焦点商品信息" },
6
+ { id: 3, key: "focus_goods_sku", name: "焦点商品sku信息" },
7
+ { id: 4, key: "focus_order_amount", name: "焦点订单实付金额" },
8
+ { id: 5, key: "focus_order_status", name: "焦点订单状态" },
9
+ { id: 6, key: "shop_name", name: "店铺名称" }
10
+ ];
11
+ function Ot(t) {
12
+ if (!Array.isArray(t)) return !1;
13
+ const o = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set(), S = /* @__PURE__ */ new Set();
14
+ return t.every((a) => !a || !(typeof a.id == "string" && a.id.trim() === a.id && a.id || typeof a.id == "number" && Number.isSafeInteger(a.id) && a.id > 0) || typeof a.key != "string" || !a.key || a.key.trim() !== a.key || typeof a.name != "string" || !a.name || a.name.trim() !== a.name || /[{}<>\r\n]/u.test(a.name) || o.has(String(a.id)) || d.has(a.key) || S.has(a.name) ? !1 : (o.add(String(a.id)), d.add(a.key), S.add(a.name), !0));
5
15
  }
6
- function T(t) {
16
+ const _t = Object.freeze(Pt.map((t) => Object.freeze({ ...t })));
17
+ function Dt(t, o = _t) {
18
+ return o.find((d) => d.name === t);
19
+ }
20
+ function Kt(t, o = _t) {
21
+ return o.find((d) => d.key === t);
22
+ }
23
+ function Lt(t) {
24
+ return `{业务属性@${t}}`;
25
+ }
26
+ const Ft = /* @__PURE__ */ new Set([
27
+ "todo",
28
+ "cdp_tag",
29
+ "separator",
30
+ "original_repeat",
31
+ "size_chart",
32
+ "table_knowledge",
33
+ "biz_attribute",
34
+ "variable",
35
+ "custom_agent",
36
+ "reasoning",
37
+ "memory_trigger",
38
+ "no_send_follow_order",
39
+ "small_payment",
40
+ "order_remark",
41
+ "external_method",
42
+ "ticket",
43
+ "tool"
44
+ ]), Jt = /#@[^#\n]+?@#|##[^#\n]+?##|\$\$小额打款@[^$\n]+?\$\$|\^\^订单备注[^\n]+?\^\^|\{自定义Agent\}@[^^\s\n{}]+|\{(?:业务属性|属性|外部方法|智能建单|智能工单|待办|记忆触发点|分隔符|原话复述|顾客标签|意图标签|工具|推理)@?[^}\n]*\}|#[^#\n]+?#/gu;
45
+ function Ut(t) {
46
+ return t.replace(
47
+ /<video\b((?:[^"'<>]|"[^"]*"|'[^']*')*)\/>/giu,
48
+ "<video$1></video>"
49
+ );
50
+ }
51
+ function Vt(t) {
52
+ return t.startsWith("#@") ? "size_chart" : t.startsWith("##") ? "table_knowledge" : t.startsWith("$$") ? "small_payment" : t.startsWith("^^") ? "order_remark" : t.startsWith("{自定义Agent}") ? "custom_agent" : t.startsWith("#") ? "variable" : t.startsWith("{业务属性@") || t.startsWith("{属性@") ? "biz_attribute" : t.startsWith("{外部方法@") ? "external_method" : t.startsWith("{智能建单@") || t.startsWith("{智能工单@") ? "ticket" : t.startsWith("{待办") ? "todo" : t.startsWith("{记忆触发点") ? "memory_trigger" : t.startsWith("{分隔符") ? "separator" : t.startsWith("{原话复述") ? "original_repeat" : t.startsWith("{推理") ? "reasoning" : t.startsWith("{顾客标签") || t.startsWith("{意图标签") ? "cdp_tag" : "tool";
53
+ }
54
+ function te(t, o) {
55
+ var i;
56
+ const d = [], S = () => {
57
+ d.length && d[d.length - 1].type !== "break" && d.push({ type: "break" });
58
+ }, a = (g) => {
59
+ let f = 0;
60
+ for (const p of g.matchAll(Jt))
61
+ p.index > f && d.push({ type: "text", text: g.slice(f, p.index) }), d.push({ type: "tag", kind: Vt(p[0]), label: p[0] }), f = p.index + p[0].length;
62
+ f < g.length && d.push({ type: "text", text: g.slice(f) });
63
+ };
64
+ if (t != null && t.trim() && typeof DOMParser < "u") {
65
+ const g = new DOMParser().parseFromString(
66
+ Ut(t),
67
+ "text/html"
68
+ ), f = (p) => {
69
+ var n, r;
70
+ if (p.nodeType === Node.TEXT_NODE) {
71
+ a(p.textContent || "");
72
+ return;
73
+ }
74
+ if (!(p instanceof Element)) return;
75
+ const y = p.tagName.toLowerCase();
76
+ if (["script", "style", "svg", "iframe", "object"].includes(y))
77
+ return;
78
+ if (y === "br") {
79
+ S();
80
+ return;
81
+ }
82
+ if (y === "img" && p.getAttribute("data-tag-icon") === "true")
83
+ return;
84
+ if (y === "img" || y === "video") {
85
+ const u = p.getAttribute("src") || (y === "video" ? (n = p.querySelector("source[src]")) == null ? void 0 : n.getAttribute("src") : null);
86
+ wt(u) && d.push({
87
+ type: "media",
88
+ kind: y === "img" ? "image" : "video",
89
+ url: u
90
+ });
91
+ return;
92
+ }
93
+ const m = p.getAttribute("data-tag-type") || (p.getAttribute("data-size") === "true" ? "size_chart" : "") || (p.getAttribute("data-tableKnowledge") === "true" ? "table_knowledge" : "") || (p.getAttribute("data-variable") === "true" ? "variable" : "") || (p.getAttribute("data-divider") === "true" ? "separator" : "");
94
+ if (Ft.has(m)) {
95
+ const u = (r = p.textContent) == null ? void 0 : r.trim();
96
+ u && d.push({ type: "tag", kind: m, label: u });
97
+ return;
98
+ }
99
+ const s = [
100
+ "div",
101
+ "p",
102
+ "li",
103
+ "h1",
104
+ "h2",
105
+ "h3",
106
+ "blockquote",
107
+ "pre"
108
+ ].includes(y);
109
+ s && d.length && S(), p.childNodes.forEach(f), s && S();
110
+ };
111
+ for (g.body.childNodes.forEach(f); ((i = d[d.length - 1]) == null ? void 0 : i.type) === "break"; ) d.pop();
112
+ }
113
+ return d.some(
114
+ (g) => g.type === "tag" || g.type === "media" || g.type === "text" && !!g.text.trim()
115
+ ) || (d.length = 0, o != null && o.trim() && a(o)), d;
116
+ }
117
+ function c(t, o, d) {
118
+ return { ok: !1, issues: [{ path: o, message: d }], raw: t };
119
+ }
120
+ function w(t) {
7
121
  return t.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
8
122
  }
9
- function rt(t) {
123
+ function pt(t) {
124
+ return t.getAttribute("data-tag-type") || (t.getAttribute("data-tag") === "no_send_follow_order" ? "no_send_follow_order" : "") || (t.getAttribute("data-divider") === "true" ? "separator" : "") || (t.getAttribute("data-retelling") === "true" ? "original_repeat" : "") || (t.getAttribute("data-size") === "true" ? "size_chart" : "") || (t.getAttribute("data-tableKnowledge") === "true" ? "table_knowledge" : "") || (t.getAttribute("data-variable") === "true" ? "variable" : "") || (t.getAttribute("data-agent") === "true" ? "custom_agent" : "") || (t.getAttribute("data-reasoning") === "true" ? "reasoning" : "") || (t.getAttribute("data-memory-trigger") === "true" ? "memory_trigger" : "") || (/^\{(?:智能建单|智能工单)@/u.test((t.textContent || "").trim()) ? "ticket" : "") || ((t.textContent || "").trim().startsWith("{外部方法@") ? "external_method" : "") || (t.getAttribute("data-tag") === "true" ? "todo" : "");
125
+ }
126
+ function Ct(t) {
127
+ const o = /<\{原话复述\}((?:<(?:img|video)\b[^>]*>|[^<>])*)>|<(?:img|video)\b[^>]*>/gu;
128
+ let d = "", S = 0;
129
+ for (const a of t.matchAll(o)) {
130
+ const i = a.index || 0;
131
+ d += w(t.slice(S, i)), d += a[1] === void 0 ? a[0] : `<span data-tag-type="original_repeat" data-original-repeat-template="true"><span data-original-repeat-input="true">${Ct(
132
+ a[1]
133
+ )}</span></span>`, S = i + a[0].length;
134
+ }
135
+ return d + w(t.slice(S));
136
+ }
137
+ function ht(t, o = !1, d = _t) {
10
138
  if (typeof DOMParser > "u")
11
- return a(t, "web_content", "当前环境不支持 HTML 解析");
12
- const u = new DOMParser().parseFromString(t, "text/html"), i = [[]];
13
- let p = null;
14
- const g = (d) => i[i.length - 1].push(d), l = (d = !1) => {
15
- (d || i[i.length - 1].length) && i.push([]);
16
- }, c = (d, s) => {
17
- var C, b, E, j;
18
- if (p) return;
19
- if (d.nodeType === 3) {
20
- (d.textContent || "").replace(/\r\n?/g, `
21
- `).split(`
22
- `).forEach((f, x) => {
23
- x && l(!0), f && g({ kind: "text", value: f });
139
+ return c(t, "web_content", "当前环境不支持 HTML 解析");
140
+ const S = new DOMParser().parseFromString(t, "text/html"), a = [[]];
141
+ let i = null, g = [];
142
+ const f = (m) => a[a.length - 1].push(
143
+ m.kind === "text" && g.length ? { ...m, marks: [...g] } : m
144
+ ), p = (m = !1) => {
145
+ (m || a[a.length - 1].length) && a.push([]);
146
+ }, y = (m, s) => {
147
+ var O, P, M, _, B, K, Y, at, rt, D, et, H, Z, W, it;
148
+ if (i) return;
149
+ if (m.nodeType === 3) {
150
+ (m.textContent || "").replace(/\r\n?/g, `
151
+ `).replace(
152
+ /\^\^订单备注-[\s\S]*?\^\^|<\{原话复述\}[^<>]*>/gu,
153
+ (j) => j.replace(/\n/g, "")
154
+ ).split(`
155
+ `).forEach((j, U) => {
156
+ U && p(!0), j = j.replace(/\uE000/g, `
157
+ `);
158
+ let $ = 0;
159
+ for (const b of j.matchAll(
160
+ /<\{原话复述\}([^<>]*)>|\{待办(?:@([^{}]+))?\}/gu
161
+ )) {
162
+ if (b[1] === void 0 && !o) continue;
163
+ const x = b.index || 0;
164
+ x > $ && f({ kind: "text", value: j.slice($, x) }), f(
165
+ b[1] !== void 0 ? { kind: "originalReply", html: w(b[1]) } : { kind: "todo", value: b[0] }
166
+ ), $ = x + b[0].length;
167
+ }
168
+ $ < j.length && f({ kind: "text", value: j.slice($) });
24
169
  });
25
170
  return;
26
171
  }
27
- if (d.nodeType !== 1) return;
28
- const n = d, r = n.tagName.toLowerCase(), m = n.getAttribute("data-tag-type") || (n.getAttribute("data-tag") === "true" ? "todo" : "") || (n.getAttribute("data-divider") === "true" ? "separator" : "") || (n.getAttribute("data-retelling") === "true" ? "original_repeat" : "") || (n.getAttribute("data-variable") === "true" ? "variable" : "") || (n.getAttribute("data-agent") === "true" ? "custom_agent" : "") || (n.getAttribute("data-reasoning") === "true" ? "reasoning" : "") || (n.getAttribute("data-memory-trigger") === "true" ? "memory_trigger" : "");
29
- if (r === "span" && m) {
30
- const y = n.getAttribute("data-tag-name") || n.getAttribute("data-variable-name") || "", f = n.textContent || "", x = {
31
- todo: ((C = f.match(/\{待办@[^{}]+\}/u)) == null ? void 0 : C[0]) || (y ? `{待办@${y}}` : ""),
32
- cdp_tag: ((b = f.match(/\{(?:顾客标签|意图标签)@[^{}]+\}/u)) == null ? void 0 : b[0]) || (y ? `{顾客标签@${y}}` : ""),
172
+ if (m.nodeType !== 1) return;
173
+ const n = m, r = n.tagName.toLowerCase(), u = pt(n);
174
+ if (r === "span" && u === "original_repeat" && n.getAttribute("data-original-repeat-template") === "true") {
175
+ const L = n.querySelectorAll('[data-original-repeat-input="true"]');
176
+ if (L.length !== 1) {
177
+ i = { path: s, message: "原话模板缺少唯一的回复输入区" };
178
+ return;
179
+ }
180
+ f({ kind: "originalReply", html: L[0].innerHTML });
181
+ return;
182
+ }
183
+ if (r === "span" && u) {
184
+ if (u === "ticket") {
185
+ const $ = (n.textContent || "").trim(), b = Nt($);
186
+ !b || n.hasAttribute("data-ticket-id") && n.getAttribute("data-ticket-id") !== b.key || n.hasAttribute("data-ticket-name") && n.getAttribute("data-ticket-name") !== b.label || n.hasAttribute("data-ticket-protocol") && n.getAttribute("data-ticket-protocol") !== (((O = b.params) == null ? void 0 : O.protocol) || "current") || n.getAttribute("data-invalid") === "true" ? i = {
187
+ path: s,
188
+ message: "工单标签格式无效、引用已失效或属性与内容不一致"
189
+ } : f({ kind: "text", value: $ });
190
+ return;
191
+ }
192
+ if (u === "external_method") {
193
+ const $ = (n.textContent || "").trim(), b = St($);
194
+ !b || ((P = b.attrs) == null ? void 0 : P.key) !== "external_method" || n.hasAttribute("data-scene-id") && n.getAttribute("data-scene-id") !== b.attrs.params.sceneId || n.hasAttribute("data-scene-name") && n.getAttribute("data-scene-name") !== b.attrs.params.sceneName || n.getAttribute("data-invalid") === "true" ? i = { path: s, message: "外部方法引用无效或属性与内容不一致" } : f({ kind: "text", value: $ });
195
+ return;
196
+ }
197
+ if (u === "no_send_follow_order") {
198
+ i = { path: s, message: "旧不发送跟单标签尚无新知识节点承载" };
199
+ return;
200
+ }
201
+ if (u === "table_knowledge") {
202
+ const $ = (n.textContent || "").trim(), b = n.getAttribute("data-table-name") || ((M = $.match(/^##([^#\r\n]+)##$/u)) == null ? void 0 : M[1]) || "";
203
+ !b.trim() || /[#\r\n]/u.test(b) || $ && $ !== `##${b}##` || n.getAttribute("data-invalid") === "true" ? i = {
204
+ path: s,
205
+ message: "表格知识名称无效、与标签不一致或引用已失效"
206
+ } : f({
207
+ kind: "tableKnowledge",
208
+ name: b,
209
+ key: n.getAttribute("data-table-id") || b
210
+ });
211
+ return;
212
+ }
213
+ if (u === "size_chart") {
214
+ i = { path: s, message: `旧${u}标签尚无新知识节点承载` };
215
+ return;
216
+ }
217
+ if (u === "biz_attribute") {
218
+ const $ = (n.textContent || "").trim(), b = (_ = $.match(
219
+ /^\{业务属性@([^{}<>\r\n]+)\}$/u
220
+ )) == null ? void 0 : _[1], x = ((B = n.getAttribute("data-attr-name")) == null ? void 0 : B.trim()) || b, V = x && Dt(x, d);
221
+ !V || $ !== x && $ !== Lt(x) || n.hasAttribute("data-attr-key") && n.getAttribute("data-attr-key") !== V.key || n.hasAttribute("data-attr-id") && n.getAttribute("data-attr-id") !== String(V.id) ? i = { path: s, message: "业务属性标签名称、ID 或 key 无效" } : f({ kind: "attribute", name: x, key: V.key });
222
+ return;
223
+ }
224
+ if (u === "small_payment" || u === "order_remark") {
225
+ if (u === "order_remark" && n.hasAttribute("data-order-remark")) {
226
+ const ot = Ht(
227
+ n.getAttribute("data-order-remark") || ""
228
+ ), st = ot && It(ot);
229
+ st ? f({ kind: "text", value: st }) : i = { path: s, message: "旧订单备注数据无效" };
230
+ return;
231
+ }
232
+ const $ = n.textContent || "", b = St($), x = (K = b == null ? void 0 : b.attrs) == null ? void 0 : K.params;
233
+ (u === "small_payment" ? ((Y = b == null ? void 0 : b.attrs) == null ? void 0 : Y.key) === "small_payment" && n.getAttribute("data-max-amount-cent") === String(Number(x == null ? void 0 : x.amount) * 100) : ((at = b == null ? void 0 : b.attrs) == null ? void 0 : at.key) === "order_note" && n.getAttribute("data-remark-id") === (x == null ? void 0 : x.id) && n.getAttribute("data-remark-mode") === ((x == null ? void 0 : x.contentMode) === "fixed" ? "fixed" : "extract") && n.getAttribute("data-remark-flag") === (x == null ? void 0 : x.flag) && n.getAttribute("data-remark-keep-flag") === (x != null && x.preserveFlag ? "1" : "0") && n.getAttribute("data-remark-position") === (x == null ? void 0 : x.position) && n.getAttribute("data-remark-content") === (x == null ? void 0 : x.content)) ? f({ kind: "text", value: $ }) : i = { path: s, message: `${u} 标签属性与内容不一致` };
234
+ return;
235
+ }
236
+ if (u === "variable") {
237
+ const $ = (n.textContent || "").trim(), b = (D = (rt = $.match(/^#([^#\r\n]+)#$/u)) == null ? void 0 : rt[1]) == null ? void 0 : D.trim(), V = ((et = n.getAttribute("data-variable-name")) == null ? void 0 : et.trim()) || b;
238
+ !V || !b || b !== V ? i = { path: s, message: "变量标签名称与显示内容不一致" } : f({
239
+ kind: "text",
240
+ value: V === "订单链接" ? "{订单链接}" : $
241
+ });
242
+ return;
243
+ }
244
+ const L = n.getAttribute("data-tag-name") || n.getAttribute("data-variable-name") || n.getAttribute("data-agent-name") || "", j = n.textContent || "";
245
+ if (u === "cdp_tag" && (!n.getAttribute("data-tag-id") || /已失效/u.test(j))) {
246
+ i = { path: s, message: "失效顾客标签需要只读保全" };
247
+ return;
248
+ }
249
+ if (u === "todo" || u === "cdp_tag") {
250
+ const $ = (H = j.match(
251
+ u === "todo" ? /\{待办@([^{}]+)\}/u : /\{(?:顾客标签|意图标签)@([^{}]+)\}/u
252
+ )) == null ? void 0 : H[1], b = n.getAttribute("data-tag-name");
253
+ if ($ && b && $ !== b) {
254
+ i = { path: s, message: `${u} 标签名称与显示内容不一致` };
255
+ return;
256
+ }
257
+ }
258
+ const U = {
259
+ todo: ((Z = j.match(/\{待办(?:@[^{}]+)?\}/u)) == null ? void 0 : Z[0]) || (L ? `{待办@${L}}` : ""),
260
+ cdp_tag: ((W = j.match(/\{(?:顾客标签|意图标签)@[^{}]+\}/u)) == null ? void 0 : W[0]) || (L ? `{顾客标签@${L}}` : ""),
33
261
  separator: "{分隔符}",
34
262
  original_repeat: "{原话复述}",
35
- variable: ((E = f.match(/#[^#\s]+#/u)) == null ? void 0 : E[0]) || (y ? `#${y}#` : ""),
36
- custom_agent: ((j = f.match(/\{自定义Agent\}@[\s\S]+/u)) == null ? void 0 : j[0]) || (y ? `{自定义Agent}@${y}` : ""),
263
+ custom_agent: ((it = j.match(/\{自定义Agent\}@[\s\S]+/u)) == null ? void 0 : it[0]) || (L ? `{自定义Agent}@${L}` : ""),
37
264
  reasoning: "{推理}",
38
265
  memory_trigger: "{记忆触发点}"
39
266
  };
40
- x[m] ? g({ kind: "text", value: x[m] }) : p = { path: s, message: `旧标签 ${m} 无法映射到新模型` };
267
+ U[u] ? f({
268
+ kind: u === "todo" ? "todo" : "text",
269
+ value: U[u]
270
+ }) : i = { path: s, message: `旧标签 ${u} 无法映射到新模型` };
41
271
  return;
42
272
  }
43
273
  if (r === "img" && n.getAttribute("data-tag-icon") === "true") return;
44
274
  if (r === "img" || r === "video") {
45
- const y = n.getAttribute("src") || "";
46
- nt(y) ? g({
275
+ const L = n.getAttribute("src") || "";
276
+ wt(L) ? f({
47
277
  kind: "media",
48
278
  media: r === "img" ? "image" : "video",
49
- src: y,
279
+ src: L,
50
280
  path: s
51
- }) : p = { path: s, message: "媒体地址无效" };
281
+ }) : i = { path: s, message: "媒体地址无效" };
282
+ return;
283
+ }
284
+ const q = {
285
+ b: "bold",
286
+ strong: "bold",
287
+ i: "italic",
288
+ em: "italic",
289
+ u: "underline",
290
+ s: "strike",
291
+ strike: "strike",
292
+ del: "strike",
293
+ code: "code"
294
+ }[r];
295
+ if (q || r === "a") {
296
+ const L = g, j = n.getAttribute("href");
297
+ if (r === "a" && j && !wt(j)) {
298
+ i = { path: s, message: "链接地址无效" };
299
+ return;
300
+ }
301
+ const U = q ? { type: q } : j ? {
302
+ type: "link",
303
+ attrs: Object.fromEntries(
304
+ ["href", "target", "rel", "title", "class"].filter(($) => n.hasAttribute($)).map(($) => [$, n.getAttribute($)])
305
+ )
306
+ } : null;
307
+ U && !g.some(($) => $.type === U.type) && (g = [...g, U]), Array.from(n.childNodes).forEach(
308
+ ($, b) => y($, `${s}.childNodes[${b}]`)
309
+ ), g = L;
310
+ return;
311
+ }
312
+ if (["ul", "ol", "blockquote", "pre"].includes(r)) {
313
+ p(), f({ kind: "block", tag: r, html: n.outerHTML }), p(!0);
52
314
  return;
53
315
  }
54
316
  if (r === "br") {
55
- l(!0);
317
+ p(!0);
56
318
  return;
57
319
  }
58
320
  if (!["p", "div", "span"].includes(r) || r === "span" && n.attributes.length > 0) {
59
- p = { path: s, message: `HTML 标签 ${r} 无法无损转换` };
321
+ i = { path: s, message: `HTML 标签 ${r} 无法无损转换` };
60
322
  return;
61
323
  }
62
- (r === "p" || r === "div") && l();
63
- const $ = i.length;
324
+ (r === "p" || r === "div") && p();
325
+ const z = a.length;
64
326
  Array.from(n.childNodes).forEach(
65
- (y, f) => c(y, `${s}.childNodes[${f}]`)
66
- ), (r === "p" || r === "div") && (i.length === $ || i[i.length - 1].length) && l(!0);
327
+ (L, j) => y(L, `${s}.childNodes[${j}]`)
328
+ ), (r === "p" || r === "div") && (a.length === z || a[a.length - 1].length) && p(!0);
67
329
  };
68
- return Array.from(u.body.childNodes).forEach(
69
- (d, s) => c(d, `web_content.childNodes[${s}]`)
70
- ), p ? { ok: !1, issues: [p], raw: t } : (i.length > 1 && !i[i.length - 1].length && i.pop(), { ok: !0, value: i });
330
+ return Array.from(S.body.childNodes).forEach(
331
+ (m, s) => y(m, `web_content.childNodes[${s}]`)
332
+ ), i ? { ok: !1, issues: [i], raw: t } : (a.length > 1 && !a[a.length - 1].length && a.pop(), { ok: !0, value: a });
71
333
  }
72
- function W(t) {
73
- return t.every((u) => u.kind === "text") ? t.map((u) => u.value).join("") : null;
334
+ function bt(t) {
335
+ return t.every(
336
+ (o) => o.kind === "text" || o.kind === "todo" || o.kind === "attribute" || o.kind === "tableKnowledge"
337
+ ) ? t.map(
338
+ (o) => o.kind === "tableKnowledge" ? `##${o.name}##` : o.kind === "attribute" ? Lt(o.name) : o.value
339
+ ).join("") : null;
74
340
  }
75
- function K(t, u, i) {
76
- var c;
77
- const p = [], g = /(#@[^#]+@#|##[^#]+##|#[^#\s]+#|\{[^{}]+\}|\[sep\])/gu;
78
- let l = 0;
79
- for (const d of t.matchAll(g)) {
80
- const s = d.index || 0;
81
- s > l && p.push({ type: "text", text: t.slice(l, s) });
82
- const n = d[0];
83
- if (n === "{分隔符}" || n === "[sep]")
84
- p.push({
341
+ function Qt(t, o, d, S) {
342
+ var f, p;
343
+ const a = [], i = /(#@[^#]+@#|##[^#]+##|#[^#\r\n]+#|\{[^{}]+\}|\[sep\]|\$\$小额打款@[^$\r\n]*\$\$|\^\^订单备注-[\s\S]*?\^\^)/gu;
344
+ let g = 0;
345
+ for (const y of t.matchAll(i)) {
346
+ const m = y.index || 0;
347
+ if (m > g) {
348
+ const n = t.slice(g, m);
349
+ if (/\$\$小额打款|\^\^订单备注-|\{业务属性@|\{(?:智能建单|智能工单|外部方法)@|<不发送跟单>/u.test(
350
+ n
351
+ ))
352
+ return c(t, o, "工具、业务属性或不发送跟单标记格式错误");
353
+ a.push({ type: "text", text: n });
354
+ }
355
+ const s = y[0];
356
+ if (/^\{智能(?:建单|工单)/u.test(s)) {
357
+ const n = Nt(s);
358
+ if (!n) return c(t, o, `工单标记 ${s} 格式错误`);
359
+ a.push({ type: "businessToken", attrs: { kind: "ticket", ...n } });
360
+ } else if (s.startsWith("$$小额打款@") || s.startsWith("^^订单备注-") || s.startsWith("{外部方法")) {
361
+ const n = St(s);
362
+ if (!n) return c(t, o, `工具标记 ${s} 格式错误`);
363
+ a.push(n);
364
+ } else if (s === "{分隔符}" || s === "[sep]")
365
+ a.push({
85
366
  type: "businessToken",
86
367
  attrs: {
87
368
  kind: "separator",
@@ -90,105 +371,256 @@ function K(t, u, i) {
90
371
  token: "{分隔符}"
91
372
  }
92
373
  });
93
- else if (/^#[^#\s]+#$/u.test(n)) {
94
- const r = n.slice(1, -1), m = (c = i.variable) == null ? void 0 : c.call(i, r);
95
- if (!(m != null && m.key) || !m.label)
96
- return a(t, u, `变量 ${r} 缺少可解析的引用`);
97
- p.push({
374
+ else if (/^##[^#\r\n]+##$/u.test(s)) {
375
+ const n = s.slice(2, -2);
376
+ if (!n.trim()) return c(t, o, "表格知识名称不能为空");
377
+ a.push({
98
378
  type: "businessToken",
99
- attrs: { kind: "variable", key: m.key, label: m.label, token: n }
379
+ attrs: { kind: "tableKnowledge", key: n, label: n }
100
380
  });
101
- } else return a(t, u, `正文标记 ${n} 无法在当前位置转换`);
102
- l = s + n.length;
381
+ } else if (s === "{订单链接}" || /^#[^#\r\n]+#$/u.test(s)) {
382
+ const n = s === "{订单链接}" ? "订单链接" : s.slice(1, -1).trim(), r = (f = d.variable) == null ? void 0 : f.call(d, n);
383
+ if (!n || !(r != null && r.key) || r.label !== n)
384
+ return c(t, o, `变量 ${n} 缺少可解析的引用`);
385
+ a.push({
386
+ type: "businessToken",
387
+ attrs: { kind: "variable", key: r.key, label: r.label, token: s }
388
+ });
389
+ } else if (s.startsWith("{业务属性@")) {
390
+ const n = (p = s.match(/^\{业务属性@([^{}<>\r\n]+)\}$/u)) == null ? void 0 : p[1], r = n && Dt(n, S);
391
+ if (!r)
392
+ return c(t, o, `业务属性 ${n || s} 不在旧目录中`);
393
+ a.push({
394
+ type: "businessToken",
395
+ attrs: { kind: "attribute", key: r.key, label: r.name }
396
+ });
397
+ } else {
398
+ if (/^\{(?:待办|原话复述|推理|记忆触发点|顾客标签|意图标签|自定义Agent)/u.test(
399
+ s
400
+ ) || s.startsWith("#@"))
401
+ return c(t, o, `正文标记 ${s} 无法在当前位置转换`);
402
+ a.push({ type: "text", text: s });
403
+ }
404
+ g = m + s.length;
103
405
  }
104
- return l < t.length && p.push({ type: "text", text: t.slice(l) }), { ok: !0, value: p };
406
+ if (g < t.length) {
407
+ const y = t.slice(g);
408
+ if (/\$\$小额打款|\^\^订单备注-|\{业务属性@|\{(?:智能建单|智能工单|外部方法)@|<不发送跟单>/u.test(
409
+ y
410
+ ))
411
+ return c(t, o, "工具、业务属性或不发送跟单标记格式错误");
412
+ a.push({ type: "text", text: y });
413
+ }
414
+ return { ok: !0, value: a };
415
+ }
416
+ function Rt(t, o) {
417
+ const d = /* @__PURE__ */ new Set();
418
+ let S = 0, a = null;
419
+ const i = (g, f) => {
420
+ var p, y, m;
421
+ if (g.type === "businessToken" && ((p = g.attrs) == null ? void 0 : p.kind) === "tool" && (g.attrs.key === "small_payment" && ++S > 1 && (a = f), g.attrs.key === "order_note")) {
422
+ const s = String(((y = g.attrs.params) == null ? void 0 : y.id) || "");
423
+ d.has(s) && (a = f), d.add(s);
424
+ }
425
+ (m = g.content) == null || m.forEach(
426
+ (s, n) => i(s, `${f}.content[${n}]`)
427
+ );
428
+ };
429
+ return t.forEach((g, f) => i(g, `${o}[${f}]`)), a;
105
430
  }
106
- function it(t) {
107
- var u, i, p, g, l;
108
- for (let c = 0; c < t.length; c++) {
109
- const d = t[c], s = (u = d.content) == null ? void 0 : u[0];
110
- if (d.type !== "paragraph" || ((i = d.content) == null ? void 0 : i.length) !== 1 || (s == null ? void 0 : s.type) !== "businessToken" || ((p = s.attrs) == null ? void 0 : p.kind) !== "separator")
431
+ function Xt(t) {
432
+ var o, d, S, a, i;
433
+ for (let g = 0; g < t.length; g++) {
434
+ const f = t[g], p = (o = f.content) == null ? void 0 : o[0];
435
+ if (f.type !== "paragraph" || ((d = f.content) == null ? void 0 : d.length) !== 1 || (p == null ? void 0 : p.type) !== "businessToken" || ((S = p.attrs) == null ? void 0 : S.kind) !== "separator")
111
436
  continue;
112
- const n = t[c - 1], r = t[c + 1];
113
- if ((n == null ? void 0 : n.type) === "paragraph" && ((g = n.content) != null && g.length))
114
- n.content.push(s);
115
- else if ((r == null ? void 0 : r.type) === "paragraph" && ((l = r.content) != null && l.length))
116
- r.content.unshift(s);
437
+ const y = t[g - 1], m = t[g + 1];
438
+ if ((y == null ? void 0 : y.type) === "paragraph" && ((a = y.content) != null && a.length))
439
+ y.content.push(p);
440
+ else if ((m == null ? void 0 : m.type) === "paragraph" && ((i = m.content) != null && i.length))
441
+ m.content.unshift(p);
117
442
  else continue;
118
- t.splice(c--, 1);
443
+ t.splice(g--, 1);
119
444
  }
120
445
  }
121
- function lt(t, u, i = {}, p = {}) {
122
- var B, F, J, U, Q;
446
+ function qt(t, o, d = {}, S = {}) {
447
+ var yt, v, A, N, J, G, nt, lt, kt;
123
448
  if (!t || typeof t != "object" || Array.isArray(t))
124
- return a(t, "item", "旧知识记录格式不正确");
125
- if (!(u != null && u.trim()))
126
- return a(t, "sourceRecordKey", "需要稳定的来源记录键");
127
- const g = typeof t.web_content == "string" && t.web_content ? "web_content" : "content", l = t[g];
128
- if (typeof l != "string") return a(t, g, "旧知识缺少内容");
129
- const c = rt(l);
130
- if (!c.ok) return { ...c, raw: t };
131
- const d = c.value, s = W(d[0] || []), n = s == null ? void 0 : s.match(/^\s*【([^【】\r\n]+)】([\s\S]*)$/u), r = n ? n[1] : p.questionText ?? "";
132
- if (et(r))
133
- return a(t, "questionText", "顾客问法包含保留分隔符");
134
- const m = new DOMParser().parseFromString(l, "text/html"), $ = Array.from(
135
- m.querySelectorAll('span[data-tag-type="todo"], span[data-tag="true"]')
136
- ).filter((e) => e.getAttribute("data-tag-type") !== "cdp_tag").map(
449
+ return c(t, "item", "旧知识记录格式不正确");
450
+ if (!(o != null && o.trim()))
451
+ return c(t, "sourceRecordKey", "需要稳定的来源记录键");
452
+ const a = S.businessAttributes ?? _t;
453
+ if (!Ot(a))
454
+ return c(
455
+ t,
456
+ "businessAttributes",
457
+ "业务属性目录格式无效或存在重复引用"
458
+ );
459
+ const i = typeof t.web_content == "string" && t.web_content ? "web_content" : "content", g = t[i];
460
+ if (typeof g != "string") return c(t, i, "旧知识缺少内容");
461
+ const f = !!String(t.todo_plan_id || "").trim() || !!t.todo_tag_metas, p = i === "content" ? Ct(g) : g, y = ht(p, f, a);
462
+ if (!y.ok) return { ...y, raw: t };
463
+ const m = y.value, s = m[0] || [], n = s.findIndex(
464
+ (e) => e.kind === "originalReply" || e.kind === "media" || e.kind === "tableKnowledge"
465
+ ), r = bt(
466
+ n >= 0 ? s.slice(0, n) : s
467
+ ), u = r == null ? void 0 : r.match(/^\s*【([^【】\r\n]*)】([\s\S]*)$/u), q = u ? u[1] : S.questionText ?? "";
468
+ if (Mt(q))
469
+ return c(t, "questionText", "顾客问法包含保留分隔符");
470
+ const z = new DOMParser().parseFromString(p, "text/html"), O = Array.from(
471
+ z.querySelectorAll('span[data-tag-type="todo"], span[data-tag="true"]')
472
+ ).filter((e) => pt(e) === "todo").map(
137
473
  (e) => {
138
- var o;
139
- return ((o = (e.textContent || "").match(/\{待办@([^{}]+)\}/u)) == null ? void 0 : o[1]) || e.getAttribute("data-tag-name") || "";
474
+ var l;
475
+ return ((l = (e.textContent || "").match(/\{待办@([^{}]+)\}/u)) == null ? void 0 : l[1]) || e.getAttribute("data-tag-name") || "";
140
476
  }
141
- ), C = Array.from(
142
- m.querySelectorAll('span[data-tag-type="cdp_tag"]')
477
+ );
478
+ f && O.push(
479
+ ...Array.from(g.matchAll(/\{待办@([^{}]+)\}/gu), (e) => e[1])
480
+ );
481
+ const P = Array.from(
482
+ z.querySelectorAll('span[data-tag-type="cdp_tag"]')
143
483
  ).map((e) => {
144
- var o;
484
+ var l;
145
485
  return {
146
- name: ((o = (e.textContent || "").match(
486
+ name: ((l = (e.textContent || "").match(
147
487
  /\{(?:顾客标签|意图标签)@([^{}]+)\}/u
148
- )) == null ? void 0 : o[1]) || e.getAttribute("data-tag-name") || "",
488
+ )) == null ? void 0 : l[1]) || e.getAttribute("data-tag-name") || "",
149
489
  id: e.getAttribute("data-tag-id") || ""
150
490
  };
151
491
  });
152
- if ($.length > 1)
153
- return a(t, g, "新模型每条问法只能选择一个待办方案");
154
- if (C.length > 1)
155
- return a(t, g, "新模型每条问法只能选择一个顾客标签");
156
- const b = {}, E = !n && s && /^(?:\{(?:待办|顾客标签|意图标签)@[^{}]+\})+$/u.test(s.trim());
157
- let j = (n == null ? void 0 : n[2].trim()) || (E ? s.trim() : "");
158
- for (; j; ) {
159
- const e = j.match(
160
- /^\{(待办|顾客标签|意图标签)@([^{}]+)\}|^\{(原话复述|记忆触发点)\}/u
492
+ if ((yt = z.body.textContent) != null && yt.includes("{待办}") && O.push("默认"), i === "content" && Array.isArray(t.tag_meta))
493
+ for (const e of t.tag_meta) {
494
+ const l = e;
495
+ (l == null ? void 0 : l.type) === "cdp_tag" && typeof l.name == "string" && /\{(?:顾客标签|意图标签)@[^{}]+\}/u.test(g) && (g.includes(`{顾客标签@${l.name}}`) || g.includes(`{意图标签@${l.name}}`)) && P.push({ name: l.name, id: String(l.value || "") });
496
+ }
497
+ if (P.length > 1)
498
+ return c(t, i, "新模型每条问法只能选择一个顾客标签");
499
+ const M = /* @__PURE__ */ new Map();
500
+ for (const [e, l] of Array.from(
501
+ z.querySelectorAll('span[data-tag-type="todo"], span[data-tag="true"]')
502
+ ).entries()) {
503
+ if (pt(l) !== "todo") continue;
504
+ const k = (v = l.getAttribute("plan_id")) == null ? void 0 : v.trim();
505
+ if (!k) continue;
506
+ const h = ((A = (l.textContent || "").match(/\{待办@([^{}]+)\}/u)) == null ? void 0 : A[1]) || l.getAttribute("data-tag-name") || "";
507
+ if (!h)
508
+ return c(t, `${i}.todo[${e}]`, "待办标签缺少方案名称");
509
+ const T = M.get(h);
510
+ if (T && T.id !== k)
511
+ return c(
512
+ t,
513
+ `${i}.todo[${e}]`,
514
+ "同名待办对应多个方案 ID"
515
+ );
516
+ M.set(h, { id: k, label: h });
517
+ }
518
+ if (t.todo_tag_metas !== void 0 && t.todo_tag_metas !== "") {
519
+ let e = t.todo_tag_metas;
520
+ if (typeof e == "string")
521
+ try {
522
+ e = JSON.parse(e);
523
+ } catch {
524
+ return c(t, "todo_tag_metas", "待办方案元数据不是有效 JSON");
525
+ }
526
+ if (!Array.isArray(e))
527
+ return c(t, "todo_tag_metas", "待办方案元数据必须为数组");
528
+ for (const [l, k] of e.entries()) {
529
+ if (!k || typeof k != "object" || typeof k.plan_id != "string" || !k.plan_id.trim() || typeof k.plan_name != "string" || !k.plan_name.trim() || k.tag_type !== void 0 && k.tag_type !== 2)
530
+ return c(
531
+ t,
532
+ `todo_tag_metas[${l}]`,
533
+ "待办方案缺少有效 ID、名称或已失效"
534
+ );
535
+ const h = M.get(k.plan_name);
536
+ if (h && h.id !== k.plan_id)
537
+ return c(
538
+ t,
539
+ `todo_tag_metas[${l}]`,
540
+ "待办方案元数据与富文本标签的 plan_id 不一致"
541
+ );
542
+ M.set(k.plan_name, {
543
+ id: k.plan_id,
544
+ label: k.plan_name
545
+ });
546
+ }
547
+ }
548
+ if (String(t.todo_plan_id || "").trim() && typeof t.todo_plan_name == "string") {
549
+ const e = M.get(t.todo_plan_name);
550
+ if (e && e.id !== String(t.todo_plan_id))
551
+ return c(t, "todo_plan_id", "待办方案字段与多方案元数据不一致");
552
+ M.set(t.todo_plan_name, {
553
+ id: String(t.todo_plan_id),
554
+ label: t.todo_plan_name
555
+ });
556
+ }
557
+ const _ = {}, B = !u && r && /^(?:\{(?:待办|顾客标签|意图标签)@[^{}]+\}|\{(?:原话复述|记忆触发点|推理)\})+$/u.test(
558
+ r.trim()
559
+ ), K = [];
560
+ let Y = !1, at = "", rt = "", D = (u == null ? void 0 : u[2].trim()) || (B ? r.trim() : "");
561
+ for (; D; ) {
562
+ if (D.startsWith("{待办}")) {
563
+ K.push({ kind: "todo", value: "{待办}" }), D = D.slice(4).trimStart();
564
+ continue;
565
+ }
566
+ if (/^\{(?:智能建单|智能工单|外部方法)@/u.test(D)) {
567
+ at = D;
568
+ break;
569
+ }
570
+ if (D.startsWith("{自定义Agent}@")) {
571
+ if (rt) return c(t, i, "Agent 标记重复");
572
+ const l = D, h = Array.from(z.querySelectorAll("span")).filter((T) => pt(T) === "custom_agent").map((T) => (T.textContent || "").trim()).find(
573
+ (T) => T.startsWith("{自定义Agent}@") && l.startsWith(T)
574
+ ) || ((N = D.match(/^\{自定义Agent\}@[^{}]+/u)) == null ? void 0 : N[0]);
575
+ if (!h) return c(t, i, "Agent 名称为空");
576
+ rt = h.trim(), D = D.slice(h.length).trimStart();
577
+ continue;
578
+ }
579
+ const e = D.match(
580
+ /^\{(待办|顾客标签|意图标签)@([^{}]+)\}|^\{(原话复述|记忆触发点|推理)\}/u
161
581
  );
162
- if (!e) return a(t, g, `问法后的标记无法转换:${j}`);
582
+ if (!e) {
583
+ if (D.startsWith("{"))
584
+ return c(t, i, `问法后的标记无法转换:${D}`);
585
+ at = D;
586
+ break;
587
+ }
163
588
  if (e[1]) {
164
- const o = e[1] === "待办" ? "todo" : "tagged", h = o === "todo" ? $.find((O) => O === e[2]) : C.find((O) => O.name === e[2]);
165
- if (!h)
166
- return a(
589
+ const l = e[1] === "待办" ? "todo" : "tagged", k = l === "todo" ? O.find((E) => E === e[2]) : P.find((E) => E.name === e[2]);
590
+ if (!k)
591
+ return c(
167
592
  t,
168
- g,
593
+ i,
169
594
  `${e[1]} ${e[2]} 不是有效的旧版富文本标签`
170
595
  );
171
- const H = o === "todo" && t.todo_plan_name === e[2] ? String(t.todo_plan_id || "") : o === "tagged" ? h.id : "", k = H ? { id: H, label: e[2] } : (B = i.selection) == null ? void 0 : B.call(i, o, e[2]);
172
- if (!(k != null && k.id) || !k.label || k.label !== e[2])
173
- return a(
596
+ const h = l === "todo" && t.todo_plan_name === e[2] ? String(t.todo_plan_id || "") : l === "tagged" ? k.id : "", T = l === "todo" && M.has(e[2]) ? M.get(e[2]) : h ? { id: h, label: e[2] } : (J = d.selection) == null ? void 0 : J.call(d, l, e[2]);
597
+ if (!(T != null && T.id) || !T.label || T.label !== e[2])
598
+ return c(
174
599
  t,
175
- g,
600
+ i,
176
601
  `${e[1]} ${e[2]} 缺少匹配的方案 ID`
177
602
  );
178
- if (b[o]) return a(t, g, `${e[1]}重复`);
179
- b[o] = { version: 1, data: { enabled: !0, tag: k } };
603
+ if (l === "todo")
604
+ K.push({ kind: "todo", value: e[0] });
605
+ else {
606
+ if (_[l]) return c(t, i, `${e[1]}重复`);
607
+ _[l] = { version: 1, data: { enabled: !0, tag: T } };
608
+ }
609
+ } else if (e[3] === "推理") {
610
+ if (Y) return c(t, i, "推理标记重复");
611
+ Y = !0;
180
612
  } else {
181
- const o = e[3] === "原话复述" ? "originalReply" : "memory";
182
- if (b[o]) return a(t, g, `${e[3]}重复`);
183
- b[o] = { version: 1, data: { enabled: !0 } };
613
+ const l = e[3] === "原话复述" ? "originalReply" : "memory";
614
+ if (_[l]) return c(t, i, `${e[3]}重复`);
615
+ _[l] = { version: 1, data: { enabled: !0 } };
184
616
  }
185
- j = j.slice(e[0].length).trimStart();
617
+ D = D.slice(e[0].length).trimStart();
186
618
  }
187
619
  if (Array.isArray(t.tag_meta))
188
- for (const [e, o] of t.tag_meta.entries()) {
189
- if (!o || typeof o != "object")
190
- return a(t, `tag_meta[${e}]`, "标签元数据格式错误");
191
- const h = o;
620
+ for (const [e, l] of t.tag_meta.entries()) {
621
+ if (!l || typeof l != "object")
622
+ return c(t, `tag_meta[${e}]`, "标签元数据格式错误");
623
+ const k = l;
192
624
  if (![
193
625
  "cdp_tag",
194
626
  "todo",
@@ -197,289 +629,788 @@ function lt(t, u, i = {}, p = {}) {
197
629
  "original_repeat",
198
630
  "custom_agent",
199
631
  "memory",
200
- "separator"
201
- ].includes(String(h.type)))
202
- return a(
632
+ "separator",
633
+ "table_knowledge"
634
+ ].includes(String(k.type)))
635
+ return c(
203
636
  t,
204
637
  `tag_meta[${e}]`,
205
638
  "旧标签元数据无法映射到新模型"
206
639
  );
207
- if (h.invalid)
208
- return a(t, `tag_meta[${e}]`, "失效标签需要只读保全");
209
- if (h.type === "cdp_tag" && (!b.tagged || b.tagged.data.tag.id !== String(h.value || "") || b.tagged.data.tag.label !== String(h.name || "")))
210
- return a(
640
+ if (k.invalid)
641
+ return c(t, `tag_meta[${e}]`, "失效标签需要只读保全");
642
+ if (k.type === "cdp_tag" && (!_.tagged || _.tagged.data.tag.id !== String(k.value || "") || _.tagged.data.tag.label !== String(k.name || "")))
643
+ return c(
211
644
  t,
212
645
  `tag_meta[${e}]`,
213
646
  "顾客标签 ID 与富文本标签不一致"
214
647
  );
215
648
  }
216
- const y = t.todo_plan_id;
217
- if (y != null && String(y).trim()) {
649
+ const et = t.todo_plan_id;
650
+ if (et != null && String(et).trim()) {
218
651
  const e = t.todo_plan_name;
219
652
  if (typeof e != "string" || !e.trim())
220
- return a(t, "todo_plan_name", "待办方案 ID 存在但名称缺失");
221
- if (!$.includes(e))
222
- return a(t, "web_content", "待办方案字段缺少对应的富文本标签");
223
- const o = { id: String(y), label: e };
224
- if (b.todo && JSON.stringify(b.todo.data.tag) !== JSON.stringify(o))
225
- return a(t, "todo_plan_id", "待办字段与正文标签不一致");
226
- b.todo = { version: 1, data: { enabled: !0, tag: o } };
653
+ return c(t, "todo_plan_name", "待办方案 ID 存在但名称缺失");
654
+ if (!O.includes(e))
655
+ return c(t, "web_content", "待办方案字段缺少对应的富文本标签");
227
656
  }
228
- const f = n || E ? d.slice(1) : [...d], x = Number(t.knowledge_type || 0);
229
- let A = x === 2 ? "reasoning" : x === 3 ? "agent" : "normal";
230
- if (t.knowledge_type !== void 0 && ![0, 1, 2, 3].includes(x))
231
- return a(t, "knowledge_type", "未知的旧知识类型");
657
+ const H = u || B ? m.slice(1) : [...m];
658
+ u && n >= 0 && H.unshift(s.slice(n)), rt && H.unshift([{ kind: "text", value: rt }]);
659
+ const Z = Number(t.knowledge_type || 0);
660
+ let W = Z === 2 ? "reasoning" : Z === 3 ? "agent" : "normal";
661
+ if (t.knowledge_type !== void 0 && ![0, 1, 2, 3].includes(Z))
662
+ return c(t, "knowledge_type", "未知的旧知识类型");
232
663
  if (Array.isArray(t.tag_meta)) {
233
664
  if (t.tag_meta.some(
234
665
  (e) => e && typeof e == "object" && e.type === "reasoning"
235
- ) && x === 1)
236
- return a(t, "tag_meta", "推理标签与知识类型不一致");
666
+ ) && Z === 1)
667
+ return c(t, "tag_meta", "推理标签与知识类型不一致");
237
668
  if (t.tag_meta.some(
238
669
  (e) => e && typeof e == "object" && e.type === "custom_agent"
239
- ) && (x === 1 || x === 2))
240
- return a(t, "tag_meta", "Agent 标签与知识类型不一致");
670
+ ) && (Z === 1 || Z === 2))
671
+ return c(t, "tag_meta", "Agent 标签与知识类型不一致");
241
672
  }
242
- let I = null;
243
- if (f.length && ((F = W(f[0])) == null ? void 0 : F.trim()) === "{推理}") {
244
- if (A === "agent")
245
- return a(t, g, "推理标记与 Agent 类型冲突");
246
- A = "reasoning", f.shift();
673
+ let it = null;
674
+ const L = (G = H[0]) == null ? void 0 : G[0], j = (L == null ? void 0 : L.kind) === "text" && /^\s*\{推理\}/u.test(L.value);
675
+ if (Y || j) {
676
+ if (W === "agent")
677
+ return c(t, i, "推理标记与 Agent 类型冲突");
678
+ if (W = "reasoning", j && (L == null ? void 0 : L.kind) === "text") {
679
+ const e = L.value.replace(/^\s*\{推理\}\s*/u, ""), l = H[0].slice(1);
680
+ for (e && l.unshift({ kind: "text", value: e }); ((nt = l[0]) == null ? void 0 : nt.kind) === "text" && !l[0].value.trim(); )
681
+ l.shift();
682
+ l.length ? H[0] = l : H.shift();
683
+ }
247
684
  }
248
- if (f.length && ((J = W(f[0])) != null && J.trim().startsWith("{自定义Agent}@"))) {
249
- if (A === "reasoning")
250
- return a(t, g, "Agent 标记与推理类型冲突");
251
- A = "agent";
252
- const e = W(f[0]).trim().slice(11), o = Array.isArray(t.tag_meta) ? t.tag_meta.find(
253
- (h) => h && typeof h == "object" && h.type === "custom_agent" && h.agent_name === e
254
- ) : void 0;
255
- if (I = typeof (o == null ? void 0 : o.agent_id) == "string" && o.agent_id ? { id: o.agent_id, name: e } : ((U = i.agent) == null ? void 0 : U.call(i, e)) || null, !(I != null && I.id) || I.name !== e)
256
- return a(t, g, `Agent ${e} 缺少匹配的 ID`);
257
- f.shift();
685
+ if (H.length && ((lt = bt(H[0])) != null && lt.trim().startsWith("{自定义Agent}@"))) {
686
+ if (W === "reasoning")
687
+ return c(t, i, "Agent 标记与推理类型冲突");
688
+ W = "agent";
689
+ const e = bt(H[0]).trim().slice(11), l = (I) => I.replace(/(已失效)$/u, "").trim(), k = l(e);
690
+ if (!k) return c(t, i, "Agent 名称为空");
691
+ const h = Array.isArray(t.tag_meta) ? t.tag_meta.find(
692
+ (I) => I && typeof I == "object" && I.type === "custom_agent" && typeof I.agent_name == "string" && l(
693
+ I.agent_name
694
+ ) === k
695
+ ) : void 0, T = Array.from(z.querySelectorAll("span")).find(
696
+ (I) => pt(I) === "custom_agent" && ((I.textContent || "").trim() === `{自定义Agent}@${e}` || l(I.getAttribute("data-agent-name") || "") === k || l(I.getAttribute("data-tag-name") || "") === k)
697
+ ), E = e.endsWith("(已失效)") || (T == null ? void 0 : T.getAttribute("data-invalid")) === "true", tt = (T == null ? void 0 : T.getAttribute("data-agent-id")) || "";
698
+ if (tt && (h != null && h.agent_id) && tt !== h.agent_id)
699
+ return c(t, "tag_meta", "Agent ID 与富文本标签不一致");
700
+ const F = typeof (h == null ? void 0 : h.agent_id) == "string" && h.agent_id ? { id: h.agent_id, name: k } : tt.trim() ? { id: tt, name: k } : E ? null : (kt = d.agent) == null ? void 0 : kt.call(d, k);
701
+ it = {
702
+ id: (F == null ? void 0 : F.name) === k ? F.id : "",
703
+ name: k,
704
+ ...E ? { invalid: !0 } : {}
705
+ }, H.shift();
258
706
  }
259
- if (A !== "normal" && b.todo)
260
- return a(t, g, "非常规知识的问法行不能包含待办标签");
261
- if (A !== "normal" && b.originalReply)
262
- return a(t, g, "此类型的问法行不能包含原话标签");
263
- if (A === "agent" && !I)
264
- return a(t, g, "Agent 知识缺少可解析的 Agent 标记");
265
- const L = [];
266
- for (let e = 0; e < f.length; e++) {
267
- const o = f[e], h = `${g}.line[${e + 2}]`;
268
- if (((Q = W(o)) == null ? void 0 : Q.trim()) === "{原话复述}" && A === "reasoning") {
269
- const w = f[++e];
270
- if (!w) return a(t, h, "原话块缺少内容");
271
- const N = W(w);
272
- if (N === null) return a(t, h, "原话块包含无法转换的媒体");
273
- const M = K(N, h, i);
274
- if (!M.ok) return { ...M, raw: t };
275
- L.push({
276
- type: "originalReply",
277
- content: [{ type: "paragraph", content: M.value }]
278
- });
279
- continue;
280
- }
281
- if (A === "agent") {
282
- if (o.some(
283
- (w) => w.kind === "media" || w.kind === "text" && w.value.trim()
284
- ))
285
- return a(t, h, "Agent 知识不能包含正文");
286
- continue;
707
+ if (W === "agent" && !it)
708
+ return c(t, i, "Agent 知识缺少可解析的 Agent 标记");
709
+ at && H.unshift([{ kind: "text", value: at }]);
710
+ const U = (e, l, k = !1, h = !1) => {
711
+ var tt, F;
712
+ if (e.kind === "originalReply")
713
+ return c(t, l, "原话块不可嵌套原话模板");
714
+ if (e.kind === "media" || e.kind === "block")
715
+ return c(t, l, "块级内容不能作为行内标签转换");
716
+ if (e.kind === "tableKnowledge")
717
+ return {
718
+ ok: !0,
719
+ value: [
720
+ {
721
+ type: "businessToken",
722
+ attrs: { kind: "tableKnowledge", key: e.key, label: e.name }
723
+ }
724
+ ]
725
+ };
726
+ if (e.kind === "attribute")
727
+ return W !== "agent" && (W !== "reasoning" || h) ? c(
728
+ t,
729
+ l,
730
+ "业务属性只能位于推理知识正文,不能放入原话"
731
+ ) : {
732
+ ok: !0,
733
+ value: [
734
+ {
735
+ type: "businessToken",
736
+ attrs: { kind: "attribute", key: e.key, label: e.name }
737
+ }
738
+ ]
739
+ };
740
+ if (e.kind !== "todo") {
741
+ const I = Qt(
742
+ W === "normal" ? e.value.replace(/\{(?:待办(?:@[^{}]+)?|原话复述)\}/gu, "") : e.value,
743
+ l,
744
+ d,
745
+ a
746
+ );
747
+ return I.ok ? W !== "agent" && (W !== "reasoning" || h) && I.value.some(
748
+ (Q) => {
749
+ var ct;
750
+ return Q.type === "businessToken" && ((ct = Q.attrs) == null ? void 0 : ct.kind) === "attribute";
751
+ }
752
+ ) ? c(
753
+ t,
754
+ l,
755
+ "业务属性只能位于推理知识正文,不能放入原话"
756
+ ) : I.ok && ((tt = e.marks) != null && tt.length) ? {
757
+ ok: !0,
758
+ value: I.value.map((Q) => ({
759
+ ...Q,
760
+ marks: e.marks
761
+ }))
762
+ } : I : I;
287
763
  }
288
- let k = [];
289
- const O = () => {
290
- k.length && (L.push({ type: "paragraph", content: k }), k = []);
764
+ if (W === "normal" && !k) return { ok: !0, value: [] };
765
+ const T = e.value === "{待办}" ? "默认" : e.value.slice(4, -1), E = M.get(T) || ((F = d.selection) == null ? void 0 : F.call(d, "todo", T));
766
+ return !(E != null && E.id) || E.label !== T ? c(t, l, `待办 ${T} 缺少匹配的方案 ID`) : W === "normal" && _.todo ? c(t, i, "待办重复") : W === "normal" ? (_.todo = { version: 1, data: { enabled: !0, tag: E } }, { ok: !0, value: [] }) : {
767
+ ok: !0,
768
+ value: [
769
+ {
770
+ type: "businessToken",
771
+ attrs: {
772
+ kind: "todo",
773
+ key: E.id,
774
+ label: E.label,
775
+ ...e.value === "{待办}" ? { token: "{待办}" } : {}
776
+ }
777
+ }
778
+ ]
291
779
  };
292
- for (const w of o)
293
- if (w.kind === "media")
294
- O(), L.push({
295
- type: "mediaBlock",
296
- attrs: { kind: w.media, src: w.src, status: "ready" }
780
+ };
781
+ if (W === "normal") {
782
+ !K.length && String(et || "").trim() && typeof t.todo_plan_name == "string" && (_.todo = {
783
+ version: 1,
784
+ data: {
785
+ enabled: !0,
786
+ tag: { id: String(et), label: t.todo_plan_name }
787
+ }
788
+ });
789
+ for (const e of K) {
790
+ const l = U(e, i, !0);
791
+ if (!l.ok) return { ...l, raw: t };
792
+ }
793
+ } else K.length && H.unshift(K);
794
+ W !== "normal" && _.originalReply && (delete _.originalReply, H.unshift([{ kind: "text", value: "{原话复述}" }]));
795
+ const $ = (e, l, k = !1) => {
796
+ var T;
797
+ const h = [];
798
+ for (let E = 0; E < e.length; E++) {
799
+ const tt = e[E], F = `${l}.line[${E + 2}]`, I = (T = bt(tt)) == null ? void 0 : T.trim();
800
+ if (I != null && I.startsWith("{原话复述}") && W === "reasoning" && !k) {
801
+ const R = I.slice(6), C = R ? ht(w(R), f, a) : null;
802
+ if (C && !C.ok) return C;
803
+ const X = C != null && C.ok ? C.value[0] : e[++E];
804
+ if (!X) return c(t, F, "原话块缺少内容");
805
+ if (bt(X) === null)
806
+ return c(t, F, "原话块包含无法转换的媒体");
807
+ const dt = [];
808
+ for (const $t of X) {
809
+ const gt = U($t, F, !1, !0);
810
+ if (!gt.ok) return { ...gt, raw: t };
811
+ dt.push(...gt.value);
812
+ }
813
+ h.push({
814
+ type: "originalReply",
815
+ content: [{ type: "paragraph", content: dt }]
297
816
  });
298
- else {
299
- const N = K(w.value, h, i);
300
- if (!N.ok) return { ...N, raw: t };
301
- k.push(...N.value);
817
+ continue;
302
818
  }
303
- (k.length || !o.length) && L.push({ type: "paragraph", content: k });
304
- }
305
- it(L);
306
- const V = {
819
+ let Q = [];
820
+ const ct = () => {
821
+ Q.length && (h.push({ type: "paragraph", content: Q }), Q = []);
822
+ };
823
+ for (const R of tt)
824
+ if (R.kind === "originalReply") {
825
+ Q.every((ut) => {
826
+ var dt;
827
+ return ut.type === "text" && !((dt = ut.text) != null && dt.trim());
828
+ }) && (Q = []), ct();
829
+ const C = ht(R.html, f, a);
830
+ if (!C.ok) return { ...C, raw: t };
831
+ if (k) return c(t, F, "原话块不可嵌套原话模板");
832
+ const X = $(
833
+ C.value,
834
+ `${F}.originalReply`,
835
+ !0
836
+ );
837
+ if (!X.ok) return X;
838
+ W === "normal" ? h.push(...X.value) : h.push({
839
+ type: "originalReply",
840
+ content: X.value.length ? X.value : [{ type: "paragraph" }]
841
+ });
842
+ } else if (R.kind === "media")
843
+ ct(), h.push({
844
+ type: "mediaBlock",
845
+ attrs: { kind: R.media, src: R.src, status: "ready" }
846
+ });
847
+ else if (R.kind === "block") {
848
+ if (ct(), k)
849
+ return c(t, F, "原话块不支持嵌套列表或引用");
850
+ const C = new DOMParser().parseFromString(R.html, "text/html").body.firstElementChild;
851
+ if (R.tag === "pre") {
852
+ h.push({
853
+ type: "codeBlock",
854
+ ...C.hasAttribute("data-language") ? { attrs: { language: C.getAttribute("data-language") } } : {},
855
+ content: C.textContent ? [{ type: "text", text: C.textContent }] : []
856
+ });
857
+ continue;
858
+ }
859
+ const X = R.tag === "ul" || R.tag === "ol", ut = [], dt = X ? Array.from(C.children) : [C];
860
+ for (const $t of dt) {
861
+ if (X && $t.tagName.toLowerCase() !== "li")
862
+ return c(t, F, "列表包含非列表项节点");
863
+ const gt = ht(
864
+ $t.innerHTML,
865
+ f,
866
+ a
867
+ );
868
+ if (!gt.ok) return { ...gt, raw: t };
869
+ const At = $(gt.value, F);
870
+ if (!At.ok) return At;
871
+ const Wt = At.value.length ? At.value : [{ type: "paragraph" }];
872
+ X ? ut.push({ type: "listItem", content: Wt }) : ut.push(...Wt);
873
+ }
874
+ h.push({
875
+ type: R.tag === "ul" ? "bulletList" : R.tag === "ol" ? "orderedList" : "blockquote",
876
+ ...R.tag === "ol" && C.hasAttribute("start") ? { attrs: { start: Number(C.getAttribute("start")) } } : {},
877
+ content: ut
878
+ });
879
+ } else {
880
+ const C = U(R, F, !1, k);
881
+ if (!C.ok) return { ...C, raw: t };
882
+ Q.push(...C.value);
883
+ }
884
+ tt.some((R) => R.kind === "originalReply") && Q.every((R) => {
885
+ var C;
886
+ return R.type === "text" && !((C = R.text) != null && C.trim());
887
+ }) && (Q = []), (Q.length || !tt.length) && h.push({ type: "paragraph", content: Q });
888
+ }
889
+ return { ok: !0, value: h };
890
+ }, b = $(H, i);
891
+ if (!b.ok) return { ...b, raw: t };
892
+ const x = b.value;
893
+ Xt(x);
894
+ const V = Rt(x, `${i}.block`);
895
+ if (V) return c(t, V, "工具标签重复");
896
+ const ot = {
307
897
  type: "doc",
308
- content: L.length ? L : [{ type: "paragraph" }]
309
- }, z = A === "agent" ? null : at(V, u).doc, D = {
898
+ content: x.length ? x : [{ type: "paragraph" }]
899
+ }, st = W === "agent" ? null : jt(ot, o).doc, vt = x.some(
900
+ (e) => {
901
+ var l;
902
+ return e.type !== "paragraph" || ((l = e.content) == null ? void 0 : l.some(
903
+ (k) => {
904
+ var h;
905
+ return k.type !== "text" || !!((h = k.text) != null && h.trim());
906
+ }
907
+ ));
908
+ }
909
+ ), ft = {
310
910
  schemaVersion: 1,
311
- type: A,
312
- question: { text: r },
313
- knowledge: { doc: z, agentRef: I },
314
- extensionState: b
315
- }, P = tt(D);
316
- return P ? a(t, P, "转换后的场景未通过新模型校验") : { ok: !0, value: D };
911
+ type: W,
912
+ question: { text: q },
913
+ knowledge: {
914
+ doc: st,
915
+ agentRef: it,
916
+ ...W === "agent" && vt ? {
917
+ agentBody: jt(ot, o).doc
918
+ } : {}
919
+ },
920
+ extensionState: _
921
+ }, mt = Et(ft);
922
+ return mt ? c(t, mt, "转换后的场景未通过新模型校验") : { ok: !0, value: ft };
317
923
  }
318
- function ot(t, u) {
319
- var i, p, g;
320
- if (t.type === "text" && !((i = t.marks) != null && i.length))
924
+ function Bt(t, o, d) {
925
+ var S, a, i, g, f, p, y, m, s, n;
926
+ if ((S = t.marks) != null && S.length) {
927
+ const r = Bt(
928
+ { ...t, marks: void 0 },
929
+ o,
930
+ d
931
+ );
932
+ if (!r.ok) return r;
933
+ let { html: u } = r.value;
934
+ for (const q of [...t.marks].reverse()) {
935
+ const z = {
936
+ bold: "b",
937
+ italic: "i",
938
+ underline: "u",
939
+ strike: "s",
940
+ code: "code",
941
+ link: "a"
942
+ }[q.type];
943
+ if (!z) return c(t, o, "文字格式无法映射到旧格式");
944
+ u = `<${z}${q.type === "link" ? ["href", "target", "rel", "title", "class"].filter((O) => {
945
+ var P;
946
+ return typeof ((P = q.attrs) == null ? void 0 : P[O]) == "string";
947
+ }).map((O) => ` ${O}="${w(q.attrs[O])}"`).join("") : ""}>${u}</${z}>`;
948
+ }
949
+ return { ok: !0, value: { html: u, text: r.value.text } };
950
+ }
951
+ if (t.type === "text" && !((a = t.marks) != null && a.length))
321
952
  return {
322
953
  ok: !0,
323
- value: { html: T(t.text || ""), text: t.text || "" }
954
+ value: { html: w(t.text || ""), text: t.text || "" }
324
955
  };
325
- if (t.type === "businessToken" && ((p = t.attrs) == null ? void 0 : p.kind) === "variable") {
326
- const l = `#${String(t.attrs.label || t.attrs.key)}#`;
956
+ if (t.type === "businessToken" && ((i = t.attrs) == null ? void 0 : i.kind) === "ticket") {
957
+ const r = String(t.attrs.key), u = String(t.attrs.label), q = zt(r, u, t.attrs.params);
958
+ return Nt(q) ? {
959
+ ok: !0,
960
+ value: {
961
+ html: `<span contenteditable="false" data-tag-type="ticket" data-ticket-id="${w(
962
+ r
963
+ )}" data-ticket-name="${w(u)}"${((g = t.attrs.params) == null ? void 0 : g.protocol) === "legacy" ? ' data-ticket-protocol="legacy"' : ""}>${w(q)}</span>`,
964
+ text: q
965
+ }
966
+ } : c(t, o, "工单引用无法映射到旧格式");
967
+ }
968
+ if (t.type === "businessToken" && ((f = t.attrs) == null ? void 0 : f.kind) === "tableKnowledge") {
969
+ const r = String(t.attrs.label);
970
+ return {
971
+ ok: !0,
972
+ value: {
973
+ html: `<span contenteditable="false" data-tableknowledge="true" data-tag-type="table_knowledge" data-table-name="${w(
974
+ r
975
+ )}" data-table-id="${w(
976
+ String(t.attrs.key)
977
+ )}">##${w(r)}##</span>`,
978
+ text: `##${r}##`
979
+ }
980
+ };
981
+ }
982
+ if (t.type === "businessToken" && ((p = t.attrs) == null ? void 0 : p.kind) === "todo") {
983
+ const r = String(t.attrs.label), u = r === "默认" && t.attrs.token === "{待办}" ? "{待办}" : `{待办@${r}}`;
327
984
  return {
328
985
  ok: !0,
329
986
  value: {
330
- html: `<span data-tag-type="variable" data-variable="true" data-variable-name="${T(
331
- String(t.attrs.label || t.attrs.key)
332
- )}">${T(l)}</span>`,
333
- text: l
987
+ html: `<span contenteditable="false" data-tag="true" data-tag-type="todo" data-tag-name="${w(
988
+ r
989
+ )}" plan_id="${w(String(t.attrs.key))}">${w(
990
+ u
991
+ )}</span>`,
992
+ text: u
334
993
  }
335
994
  };
336
995
  }
337
- return t.type === "businessToken" && ((g = t.attrs) == null ? void 0 : g.kind) === "separator" ? {
996
+ if (t.type === "businessToken" && ((y = t.attrs) == null ? void 0 : y.kind) === "variable") {
997
+ const r = String(t.attrs.label || t.attrs.key), u = r === "订单链接" ? "{订单链接}" : `#${r}#`, q = `#${r}#`;
998
+ return {
999
+ ok: !0,
1000
+ value: {
1001
+ html: `<span contenteditable="false" data-tag-type="variable" data-variable="true" data-variable-name="${w(
1002
+ r
1003
+ )}"${r === "客服昵称" ? ' data-customer="true"' : ""}>${w(
1004
+ q
1005
+ )}</span>`,
1006
+ text: u
1007
+ }
1008
+ };
1009
+ }
1010
+ if (t.type === "businessToken" && ((m = t.attrs) == null ? void 0 : m.kind) === "attribute") {
1011
+ const r = Kt(
1012
+ String(t.attrs.key),
1013
+ d
1014
+ );
1015
+ if (!r || t.attrs.label !== r.name)
1016
+ return c(t, o, "业务属性不在旧目录中或名称与 key 不一致");
1017
+ const u = w(r.name);
1018
+ return {
1019
+ ok: !0,
1020
+ value: {
1021
+ html: `<span contenteditable="false" data-tag="true" data-tag-type="biz_attribute" data-attr-name="${u}" data-attr-key="${w(
1022
+ r.key
1023
+ )}" data-attr-id="${w(String(r.id))}">${u}</span>`,
1024
+ text: Lt(r.name)
1025
+ }
1026
+ };
1027
+ }
1028
+ if (t.type === "businessToken" && ((s = t.attrs) == null ? void 0 : s.kind) === "separator")
1029
+ return {
1030
+ ok: !0,
1031
+ value: {
1032
+ html: '<span data-tag-type="separator" data-divider="true" contenteditable="false">分隔符</span>',
1033
+ text: "[sep]"
1034
+ }
1035
+ };
1036
+ if (t.type === "businessToken" && ((n = t.attrs) == null ? void 0 : n.kind) === "tool") {
1037
+ const r = It(t);
1038
+ if (!r) return c(t, o, "工具参数无法映射到旧格式");
1039
+ const { params: u } = t.attrs;
1040
+ return { ok: !0, value: { html: t.attrs.key === "external_method" ? `<span contenteditable="false" data-tag-type="external_method" data-scene-id="${w(
1041
+ u.sceneId
1042
+ )}" data-scene-name="${w(u.sceneName)}">${w(
1043
+ r
1044
+ )}</span>` : t.attrs.key === "small_payment" ? `<span contenteditable="false" data-tag="true" data-tag-type="small_payment" data-max-amount-cent="${Number(u.amount) * 100}">${w(r)}</span>` : `<span contenteditable="false" data-tag="true" data-tag-type="order_remark" data-remark-id="${w(
1045
+ u.id
1046
+ )}" data-remark-mode="${u.contentMode === "fixed" ? "fixed" : "extract"}" data-remark-flag="${w(
1047
+ u.flag
1048
+ )}" data-remark-keep-flag="${u.preserveFlag ? "1" : "0"}" data-remark-position="${u.position}" data-remark-content="${w(u.content)}">${w(
1049
+ r
1050
+ )}</span>`, text: r } };
1051
+ }
1052
+ return c(t, o, `节点 ${t.type} 无法映射到旧格式`);
1053
+ }
1054
+ function Tt(t, o, d) {
1055
+ var g, f, p;
1056
+ if (t.type === "mediaBlock" && ((g = t.attrs) == null ? void 0 : g.status) === "ready") {
1057
+ const y = t.attrs.kind === "image" ? "img" : "video", m = w(String(t.attrs.src));
1058
+ return {
1059
+ ok: !0,
1060
+ value: {
1061
+ html: `<${y} src="${m}"${y === "video" ? "></video>" : ">"}`,
1062
+ text: `<${y} src="${m}"${y === "video" ? ' width="240" controls/>' : ' width="120"/>'}`
1063
+ }
1064
+ };
1065
+ }
1066
+ const a = {
1067
+ paragraph: "p",
1068
+ bulletList: "ul",
1069
+ orderedList: "ol",
1070
+ listItem: "li",
1071
+ blockquote: "blockquote",
1072
+ codeBlock: "pre"
1073
+ }[t.type || ""];
1074
+ if (!a) return c(t, o, "块级节点无法映射到旧格式");
1075
+ const i = [];
1076
+ for (const [y, m] of (t.content || []).entries()) {
1077
+ const s = `${o}.content[${y}]`, n = ["paragraph", "codeBlock"].includes(t.type || "") ? Bt(m, s, d) : Tt(m, s, d);
1078
+ if (!n.ok) return n;
1079
+ i.push(n.value);
1080
+ }
1081
+ return {
338
1082
  ok: !0,
339
1083
  value: {
340
- html: '<span data-tag-type="separator" data-divider="true" contenteditable="false">分隔符</span>',
341
- text: "[sep]"
1084
+ html: `<${a}${t.type === "orderedList" && ((f = t.attrs) == null ? void 0 : f.start) !== void 0 ? ` start="${t.attrs.start}"` : t.type === "codeBlock" && ((p = t.attrs) != null && p.language) ? ` data-language="${w(t.attrs.language)}"` : ""}>${i.map((y) => y.html).join("")}</${a}>`,
1085
+ text: i.map((y) => y.text).join(
1086
+ ["paragraph", "codeBlock"].includes(t.type || "") ? "" : `
1087
+ `
1088
+ )
1089
+ }
1090
+ };
1091
+ }
1092
+ function xt(t, o = !1) {
1093
+ const d = (a) => {
1094
+ var f, p;
1095
+ const i = { ...a.attrs };
1096
+ delete i.id, delete i.nodeVersion, o && a.type === "businessToken" && i.kind === "tableKnowledge" && (i.key = i.label);
1097
+ const g = o && a.type === "doc" ? (f = a.content) == null ? void 0 : f.filter(
1098
+ (y, m, s) => {
1099
+ var n, r;
1100
+ return !(y.type === "paragraph" && !((n = y.content) != null && n.length) && ((r = s[m + 1]) == null ? void 0 : r.type) === "originalReply");
1101
+ }
1102
+ ) : a.content;
1103
+ return {
1104
+ ...a,
1105
+ ...o ? {
1106
+ marks: void 0,
1107
+ ...a.type === "text" ? { text: (p = a.text) == null ? void 0 : p.replace(/\u00a0/g, " ") } : {}
1108
+ } : {},
1109
+ attrs: Object.keys(i).length ? i : void 0,
1110
+ content: g != null && g.length ? g.map(d) : void 0
1111
+ };
1112
+ }, S = (a) => Array.isArray(a) ? a.map(S) : a && typeof a == "object" ? Object.fromEntries(
1113
+ Object.entries(a).sort(([i], [g]) => i.localeCompare(g)).map(([i, g]) => [i, S(g)])
1114
+ ) : a;
1115
+ return JSON.stringify(
1116
+ S({
1117
+ type: t.type,
1118
+ question: t.question.text,
1119
+ doc: t.knowledge.doc ? d(t.knowledge.doc) : null,
1120
+ agentRef: t.knowledge.agentRef || null,
1121
+ agentBody: t.knowledge.agentBody ? d(t.knowledge.agentBody) : null,
1122
+ retainedDoc: t.knowledge.retainedDoc ? d(t.knowledge.retainedDoc) : null,
1123
+ extensionState: t.extensionState
1124
+ })
1125
+ );
1126
+ }
1127
+ function Yt(t, o, d, S, a) {
1128
+ var q, z, O, P, M;
1129
+ if (typeof o.content != "string") return !1;
1130
+ const i = new DOMParser().parseFromString(
1131
+ String(o.web_content || d.web_content),
1132
+ "text/html"
1133
+ );
1134
+ if (Array.from(i.querySelectorAll("*")).some(
1135
+ (_) => Array.from(_.attributes).some(
1136
+ (B) => /^on/iu.test(B.name) || ["srcdoc", "srcset"].includes(B.name.toLowerCase()) || B.name.toLowerCase() === "style" && /url\s*\(|expression\s*\(|@import/iu.test(B.value)
1137
+ )
1138
+ ))
1139
+ return !1;
1140
+ const g = /^\s*【[^【】\r\n]*】/u.test(o.content);
1141
+ if (g !== (S === "inline")) return !1;
1142
+ const f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), y = (_) => {
1143
+ var B, K, Y;
1144
+ _.type === "businessToken" && ((B = _.attrs) == null ? void 0 : B.kind) === "variable" && f.set(String(_.attrs.label), {
1145
+ key: String(_.attrs.key),
1146
+ label: String(_.attrs.label)
1147
+ }), _.type === "businessToken" && ((K = _.attrs) == null ? void 0 : K.kind) === "todo" && p.set(String(_.attrs.label), {
1148
+ id: String(_.attrs.key),
1149
+ label: String(_.attrs.label)
1150
+ }), (Y = _.content) == null || Y.forEach(y);
1151
+ };
1152
+ (z = (q = t.knowledge.doc) == null ? void 0 : q.content) == null || z.forEach(y), (P = (O = t.knowledge.agentBody) == null ? void 0 : O.content) == null || P.forEach(y);
1153
+ const m = (M = t.extensionState.todo) == null ? void 0 : M.data;
1154
+ m != null && m.tag && p.set(m.tag.label, m.tag);
1155
+ const s = {
1156
+ variable: (_) => f.get(_) || null,
1157
+ selection: (_, B) => _ === "todo" && p.get(B) || null
1158
+ }, n = qt(
1159
+ { ...o, web_content: o.web_content || d.web_content },
1160
+ "layout-proof",
1161
+ s,
1162
+ {
1163
+ questionText: t.question.text,
1164
+ businessAttributes: a
342
1165
  }
343
- } : a(t, u, `节点 ${t.type} 无法映射到旧格式`);
1166
+ ), r = xt(t);
1167
+ if (!n.ok || xt(n.value) !== r)
1168
+ return !1;
1169
+ if (t.type === "normal") {
1170
+ const _ = ht(
1171
+ String(o.web_content || Ct(o.content))
1172
+ );
1173
+ if (!_.ok || _.value.slice(g ? 1 : 0).some(
1174
+ (B) => B.some(
1175
+ (K) => K.kind === "todo" || K.kind === "text" && /\{(?:待办(?:@[^{}]*)?|原话复述)\}/u.test(K.value)
1176
+ )
1177
+ ))
1178
+ return !1;
1179
+ }
1180
+ const u = qt(
1181
+ { ...d, web_content: "", content: o.content },
1182
+ "layout-proof",
1183
+ {
1184
+ ...s,
1185
+ agent: (_) => {
1186
+ var B;
1187
+ return ((B = t.knowledge.agentRef) == null ? void 0 : B.name) === _ ? t.knowledge.agentRef : null;
1188
+ }
1189
+ },
1190
+ { questionText: t.question.text, businessAttributes: a }
1191
+ );
1192
+ return u.ok && xt(u.value, !0) === xt(t, !0);
344
1193
  }
345
- function dt(t, u = {}, i = {}) {
346
- var C, b, E, j, y, f, x, A, I, L, V, z, D, P, B, F, J, U, Q, e, o, h, H, k, O, w, N, M;
347
- const p = tt(t);
348
- if (p) return a(t, p, "场景未通过新模型校验");
349
- const g = `【${t.question.text}】`, l = [], c = [];
350
- for (const [v, _] of [
1194
+ function ee(t, o = {}, d = {}) {
1195
+ var K, Y, at, rt, D, et, H, Z, W, it, L, j, U, $, b, x, V, ot, st, vt, ft, mt, yt;
1196
+ const S = d.businessAttributes ?? _t;
1197
+ if (!Ot(S))
1198
+ return c(
1199
+ t,
1200
+ "businessAttributes",
1201
+ "业务属性目录格式无效或存在重复引用"
1202
+ );
1203
+ const a = Et(t);
1204
+ if (a) return c(t, a, "场景未通过新模型校验");
1205
+ const i = Rt(
1206
+ ((K = t.knowledge.doc) == null ? void 0 : K.content) || [],
1207
+ "knowledge.doc.content"
1208
+ );
1209
+ if (i) return c(t, i, "工具标签重复");
1210
+ const g = `【${t.question.text}】`, f = [], p = [];
1211
+ for (const [v, A] of [
351
1212
  ["todo", "待办"],
352
1213
  ["tagged", "顾客标签"]
353
1214
  ]) {
354
- const S = (C = t.extensionState[v]) == null ? void 0 : C.data;
355
- if (S != null && S.enabled) {
356
- const R = `{${_}@${(b = S.tag) == null ? void 0 : b.label}}`;
357
- l.push(R), c.push(
358
- v === "todo" ? `<span contenteditable="false" data-tag="true" data-tag-type="todo" data-tag-name="${T(
359
- ((E = S.tag) == null ? void 0 : E.label) || ""
360
- )}">${T(R)}</span>` : `<span contenteditable="false" data-tag="true" data-tag-type="cdp_tag" data-tag-name="${T(
361
- ((j = S.tag) == null ? void 0 : j.label) || ""
362
- )}" data-tag-id="${T(((y = S.tag) == null ? void 0 : y.id) || "")}">${T(
363
- R
1215
+ const N = (Y = t.extensionState[v]) == null ? void 0 : Y.data;
1216
+ if (N != null && N.enabled) {
1217
+ const J = `{${A}@${(at = N.tag) == null ? void 0 : at.label}}`;
1218
+ f.push(J), p.push(
1219
+ v === "todo" ? `<span contenteditable="false" data-tag="true" data-tag-type="todo" data-tag-name="${w(
1220
+ ((rt = N.tag) == null ? void 0 : rt.label) || ""
1221
+ )}" plan_id="${w(((D = N.tag) == null ? void 0 : D.id) || "")}">${w(
1222
+ J
1223
+ )}</span>` : `<span contenteditable="false" data-tag="true" data-tag-type="cdp_tag" data-tag-name="${w(
1224
+ ((et = N.tag) == null ? void 0 : et.label) || ""
1225
+ )}" data-tag-id="${w(((H = N.tag) == null ? void 0 : H.id) || "")}">${w(
1226
+ J
364
1227
  )}</span>`
365
1228
  );
366
1229
  }
367
1230
  }
368
- (x = (f = t.extensionState.originalReply) == null ? void 0 : f.data) != null && x.enabled && (l.push("{原话复述}"), c.push(
1231
+ (W = (Z = t.extensionState.originalReply) == null ? void 0 : Z.data) != null && W.enabled && (f.push("{原话复述}"), p.push(
369
1232
  '<span data-tag-type="original_repeat" data-retelling="true">{原话复述}</span>'
370
- )), (I = (A = t.extensionState.memory) == null ? void 0 : A.data) != null && I.enabled && (l.push("{记忆触发点}"), c.push(
1233
+ )), (L = (it = t.extensionState.memory) == null ? void 0 : it.data) != null && L.enabled && (f.push("{记忆触发点}"), p.push(
371
1234
  '<span data-tag-type="memory_trigger" data-memory-trigger="true">{记忆触发点}</span>'
372
1235
  ));
373
1236
  for (const v of Object.keys(t.extensionState))
374
1237
  if (!["todo", "tagged", "originalReply", "memory"].includes(v))
375
- return a(
1238
+ return c(
376
1239
  t,
377
1240
  `extensionState.${v}`,
378
1241
  "旧格式无法表示此插件状态"
379
1242
  );
380
- const d = i.questionStorage || (/^\s*(?:<(?:div|p)>\s*)?【[^【】]+】/u.test(
381
- String(u.web_content || "")
382
- ) ? "inline" : "external");
383
- if (d === "external" && l.some(
384
- (v) => !v.startsWith("{待办@") && !v.startsWith("{顾客标签@")
385
- ))
386
- return a(
387
- t,
388
- "extensionState",
389
- "外部问法字段的这些标签尚无确定的旧字段映射"
390
- );
391
- const s = d === "inline" ? [`<div>${T(g)}${c.join("")}</div>`] : c.length ? [`<div>${c.join("")}</div>`] : [], n = d === "inline" ? [g + l.join("")] : l.length ? [l.join("")] : [];
392
- if (t.type === "reasoning" && (s.push("<div>{推理}</div>"), n.push("{推理}")), t.type === "agent") {
393
- if ((V = (L = t.extensionState.tagged) == null ? void 0 : L.data) != null && V.enabled)
394
- return a(
395
- t,
396
- "extensionState.tagged",
397
- "旧系统的 Agent 与顾客标签不能组合"
398
- );
399
- if (t.knowledge.retainedDoc)
400
- return a(
401
- t,
402
- "knowledge.retainedDoc",
403
- "旧格式不能保留 Agent 切换前的正文"
404
- );
1243
+ const y = d.questionStorage || (/^\s*(?:<(?:div|p)>\s*)?【[^【】\r\n]*】/u.test(
1244
+ String(o.web_content || "")
1245
+ ) ? "inline" : "external"), m = y === "inline" ? [`<div>${w(g)}${p.join("")}</div>`] : p.length ? [`<div>${p.join("")}</div>`] : [], s = y === "inline" ? [g + f.join("")] : f.length ? [f.join("")] : [];
1246
+ if (t.type === "reasoning" && (m.push("<div>{推理}</div>"), s.push("{推理}")), t.type === "agent") {
405
1247
  if (!t.knowledge.agentRef)
406
- return a(t, "knowledge.agentRef", "旧格式需要 Agent 引用");
407
- const v = `{自定义Agent}@${t.knowledge.agentRef.name}`;
408
- s.push(
409
- `<div><span data-tag-type="custom_agent" data-agent="true" data-agent-id="${T(
410
- t.knowledge.agentRef.id
411
- )}">${T(v)}</span></div>`
412
- ), n.push(v);
413
- } else
414
- for (const [v, _] of (((z = t.knowledge.doc) == null ? void 0 : z.content) || []).entries()) {
415
- const S = `knowledge.doc.content[${v}]`;
416
- if (_.type === "messageSeparator") {
417
- s.push(
418
- '<div><span data-tag-type="separator" data-divider="true">{分隔符}</span></div>'
419
- ), n.push("[sep]");
1248
+ return c(t, "knowledge.agentRef", "旧格式需要 Agent 引用");
1249
+ const v = t.knowledge.agentRef, A = `{自定义Agent}@${v.name}${v.invalid ? "(已失效)" : ""}`;
1250
+ m.push(
1251
+ `<div><span data-tag-type="custom_agent" data-agent="true" data-agent-name="${w(
1252
+ v.name
1253
+ )}"${v.id ? ` data-agent-id="${w(v.id)}"` : ""}${v.invalid ? ' data-invalid="true"' : ""}>${w(A)}</span></div>`
1254
+ ), s.push(A);
1255
+ }
1256
+ const n = t.type === "agent" ? t.knowledge.agentBody ? "agentBody" : "retainedDoc" : "doc";
1257
+ for (const [v, A] of (((j = t.knowledge[n]) == null ? void 0 : j.content) || []).entries()) {
1258
+ const N = `knowledge.${n}.content[${v}]`;
1259
+ if (A.type === "messageSeparator") {
1260
+ m.push(
1261
+ '<div><span data-tag-type="separator" data-divider="true">{分隔符}</span></div>'
1262
+ ), s.push("[sep]");
1263
+ continue;
1264
+ }
1265
+ if (A.type === "mediaBlock" && ((U = A.attrs) == null ? void 0 : U.status) === "ready") {
1266
+ const e = A.attrs.kind === "image" ? "img" : "video", l = w(String(A.attrs.src));
1267
+ m.push(
1268
+ `<div><${e} src="${l}"${e === "video" ? "></video>" : ">"}</div>`
1269
+ ), s.push(
1270
+ `<${e} src="${l}"${e === "video" ? ' width="240" controls/>' : ' width="120"/>'}`
1271
+ );
1272
+ continue;
1273
+ }
1274
+ if (["bulletList", "orderedList", "blockquote", "codeBlock"].includes(
1275
+ A.type || ""
1276
+ )) {
1277
+ const e = Tt(A, N, S);
1278
+ if (!e.ok) return { ...e, raw: t };
1279
+ m.push(e.value.html), s.push(e.value.text);
1280
+ continue;
1281
+ }
1282
+ const J = A.type === "originalReply", G = J ? A.content || [] : [A];
1283
+ if (!G.length || G.some(
1284
+ (e) => !["paragraph", "mediaBlock", "messageSeparator"].includes(
1285
+ e.type || ""
1286
+ )
1287
+ ))
1288
+ return c(t, N, `节点 ${A.type} 无法映射到旧格式`);
1289
+ const nt = [];
1290
+ for (const [e, l] of G.entries()) {
1291
+ if (l.type === "mediaBlock") {
1292
+ const h = Tt(l, N, S);
1293
+ if (!h.ok) return { ...h, raw: t };
1294
+ nt.push(h.value);
420
1295
  continue;
421
1296
  }
422
- if (_.type === "mediaBlock" && ((D = _.attrs) == null ? void 0 : D.status) === "ready") {
423
- const q = _.attrs.kind === "image" ? "img" : "video", G = T(String(_.attrs.src));
424
- s.push(
425
- `<div><${q} src="${G}"${q === "video" ? "></video>" : ">"}</div>`
426
- ), n.push(
427
- `<${q} src="${G}"${q === "video" ? ' width="240" controls/>' : ' width="120"/>'}`
428
- );
1297
+ if (l.type === "messageSeparator") {
1298
+ nt.push({
1299
+ html: '<span data-tag-type="separator" data-divider="true">分隔符</span>',
1300
+ text: "[sep]"
1301
+ });
429
1302
  continue;
430
1303
  }
431
- const R = _.type === "originalReply", X = R ? (P = _.content) == null ? void 0 : P[0] : _;
432
- if (!X || X.type !== "paragraph" || R && ((B = _.content) == null ? void 0 : B.length) !== 1)
433
- return a(t, S, `节点 ${_.type} 无法映射到旧格式`);
434
- R && (s.push(
435
- '<div><span data-tag-type="original_repeat" data-retelling="true">{原话复述}</span></div>'
436
- ), n.push("{原话复述}"));
437
- const Y = [];
438
- for (const [q, G] of (X.content || []).entries()) {
439
- const Z = ot(G, `${S}.content[${q}]`);
440
- if (!Z.ok) return { ...Z, raw: t };
441
- Y.push(Z.value);
442
- }
443
- s.push(
444
- `<div>${Y.map((q) => q.html).join("")}</div>`
445
- ), n.push(Y.map((q) => q.text).join(""));
446
- }
447
- const r = (F = t.extensionState.todo) == null ? void 0 : F.data, m = (J = t.extensionState.tagged) == null ? void 0 : J.data, $ = [];
448
- if (m != null && m.enabled) {
449
- $.push({
1304
+ const k = [];
1305
+ for (const [h, T] of (l.content || []).entries()) {
1306
+ const E = Bt(
1307
+ T,
1308
+ `${N}.content[${e}].content[${h}]`,
1309
+ S
1310
+ );
1311
+ if (!E.ok) return { ...E, raw: t };
1312
+ k.push(E.value);
1313
+ }
1314
+ nt.push({
1315
+ html: k.map((h) => h.html).join(""),
1316
+ text: k.map((h) => h.text).join("")
1317
+ });
1318
+ }
1319
+ const lt = nt.map((e) => e.html).join("<br>"), kt = nt.map((e) => e.text).join(`
1320
+ `);
1321
+ J ? (m.push(
1322
+ `<div><span contenteditable="false" class="original-repeat-template" data-retelling="true" data-tag-type="original_repeat" data-original-repeat-template="true"><span>&lt;</span><span>原话复述</span><span class="original-repeat-input" contenteditable="true" data-original-repeat-input="true">${lt}</span><span>&gt;</span></span></div>`
1323
+ ), s.push(`<{原话复述}${kt}>`)) : (m.push(`<div>${lt}</div>`), s.push(kt));
1324
+ }
1325
+ const r = ($ = t.extensionState.todo) == null ? void 0 : $.data, u = [], q = (v) => {
1326
+ var A, N;
1327
+ v.type === "businessToken" && ((A = v.attrs) == null ? void 0 : A.kind) === "todo" && u.push({
1328
+ id: String(v.attrs.key),
1329
+ label: String(v.attrs.label)
1330
+ }), (N = v.content) == null || N.forEach(q);
1331
+ };
1332
+ (x = (b = t.knowledge[n]) == null ? void 0 : b.content) == null || x.forEach(q);
1333
+ const z = r != null && r.enabled && r.tag ? [r.tag, ...u] : u, O = [
1334
+ ...new Map(
1335
+ z.map((v) => [JSON.stringify([v.id, v.label]), v])
1336
+ ).values()
1337
+ ];
1338
+ if (new Set(O.map((v) => v.label)).size !== O.length)
1339
+ return c(
1340
+ t,
1341
+ "knowledge.doc",
1342
+ "同名待办对应多个方案 ID,旧格式无法无损保存"
1343
+ );
1344
+ const P = O.length === 1 ? O[0] : void 0, M = (V = t.extensionState.tagged) == null ? void 0 : V.data, _ = [];
1345
+ if (M != null && M.enabled) {
1346
+ _.push({
450
1347
  type: "cdp_tag",
451
- name: (U = m.tag) == null ? void 0 : U.label,
452
- value: (Q = m.tag) == null ? void 0 : Q.id
453
- }), r != null && r.enabled && $.push({ type: "todo", name: (e = r.tag) == null ? void 0 : e.label }), t.type === "reasoning" && $.push({ type: "reasoning", name: "推理" }), (h = (o = t.extensionState.originalReply) == null ? void 0 : o.data) != null && h.enabled && $.push({ type: "original_repeat", name: "原话复述" }), (k = (H = t.extensionState.memory) == null ? void 0 : H.data) != null && k.enabled && $.push({ type: "memory", name: "" });
454
- const v = (_) => {
455
- var S, R;
456
- _.type === "businessToken" && ((S = _.attrs) == null ? void 0 : S.kind) === "variable" && $.push({
1348
+ name: (ot = M.tag) == null ? void 0 : ot.label,
1349
+ value: (st = M.tag) == null ? void 0 : st.id
1350
+ }), O.forEach((A) => _.push({ type: "todo", name: A.label })), t.type === "reasoning" && _.push({ type: "reasoning", name: "推理" }), (ft = (vt = t.extensionState.originalReply) == null ? void 0 : vt.data) != null && ft.enabled && _.push({ type: "original_repeat", name: "原话复述" });
1351
+ const v = (A) => {
1352
+ var N, J, G;
1353
+ A.type === "businessToken" && ((N = A.attrs) == null ? void 0 : N.kind) === "tableKnowledge" && _.push({ type: "table_knowledge", name: A.attrs.label }), A.type === "businessToken" && ((J = A.attrs) == null ? void 0 : J.kind) === "variable" && _.push({
457
1354
  type: "variable",
458
- variable_name: _.attrs.label || _.attrs.key
459
- }), _.type === "originalReply" && $.push({ type: "original_repeat", name: "原话复述" }), (R = _.content) == null || R.forEach(v);
1355
+ variable_name: A.attrs.label || A.attrs.key
1356
+ }), A.type === "originalReply" && _.push({ type: "original_repeat", name: "原话复述" }), (G = A.content) == null || G.forEach(v);
460
1357
  };
461
- (w = (O = t.knowledge.doc) == null ? void 0 : O.content) == null || w.forEach(v), t.type === "agent" && t.knowledge.agentRef && $.push({
462
- type: "custom_agent",
463
- agent_id: t.knowledge.agentRef.id,
464
- agent_name: t.knowledge.agentRef.name
465
- });
1358
+ (yt = (mt = t.knowledge[n]) == null ? void 0 : mt.content) == null || yt.forEach(v);
466
1359
  }
467
- return {
468
- ok: !0,
469
- value: {
470
- ...u,
471
- knowledge_type: t.type === "reasoning" ? 2 : t.type === "agent" ? 3 : 1,
472
- todo_plan_id: r != null && r.enabled ? (N = r.tag) == null ? void 0 : N.id : "",
473
- todo_tag_type: r != null && r.enabled ? 2 : 0,
474
- todo_plan_name: r != null && r.enabled ? (M = r.tag) == null ? void 0 : M.label : "",
475
- tag_meta: $,
476
- web_content: s.join(""),
477
- content: n.join(`
478
- `)
479
- }
1360
+ const B = {
1361
+ ...o,
1362
+ knowledge_type: t.type === "reasoning" ? 2 : t.type === "agent" ? 3 : 1,
1363
+ todo_plan_id: (P == null ? void 0 : P.id) || "",
1364
+ todo_tag_type: O.length ? 2 : 0,
1365
+ ...z.length || Object.hasOwn(o, "todo_tag_metas") ? {
1366
+ todo_tag_metas: z.length ? JSON.stringify(
1367
+ z.map((v) => ({
1368
+ plan_id: v.id,
1369
+ plan_name: v.label,
1370
+ tag_type: 2
1371
+ }))
1372
+ ) : ""
1373
+ } : {},
1374
+ todo_plan_name: (P == null ? void 0 : P.label) || "",
1375
+ tag_meta: [
1376
+ ...new Map(
1377
+ _.map((v) => [
1378
+ JSON.stringify([
1379
+ v.type,
1380
+ v.name || "",
1381
+ v.value || "",
1382
+ v.variable_name || ""
1383
+ ]),
1384
+ v
1385
+ ])
1386
+ ).values()
1387
+ ],
1388
+ web_content: m.join(""),
1389
+ content: s.join(`
1390
+ `).replace(/^\n+|\n+$/gu, "")
480
1391
  };
1392
+ if (Yt(t, o, B, y, S)) {
1393
+ const v = new DOMParser().parseFromString(
1394
+ String(o.web_content || B.web_content),
1395
+ "text/html"
1396
+ );
1397
+ if (!o.web_content && /^【[^【】\r\n]*】\{推理\}/u.test(o.content || "")) {
1398
+ const [A, N] = Array.from(v.body.children);
1399
+ A && (N == null ? void 0 : N.textContent) === "{推理}" && (A.append(...Array.from(N.childNodes)), N.remove());
1400
+ }
1401
+ v.querySelectorAll("span").forEach((A) => {
1402
+ var G, nt;
1403
+ if (pt(A) !== "todo") return;
1404
+ const N = A.getAttribute("data-tag-name") || ((nt = (G = A.textContent) == null ? void 0 : G.match(/\{待办@([^{}]+)\}/u)) == null ? void 0 : nt[1]), J = O.find((lt) => lt.label === N);
1405
+ J && (A.setAttribute("data-tag-type", "todo"), A.setAttribute("data-tag-name", J.label), A.setAttribute("plan_id", J.id));
1406
+ }), B.web_content = v.body.innerHTML, B.content = o.content;
1407
+ }
1408
+ return { ok: !0, value: B };
481
1409
  }
482
1410
  export {
483
- lt as legacyItemToScene,
484
- dt as sceneToLegacyItem
1411
+ _t as LEGACY_BUSINESS_ATTRIBUTES,
1412
+ te as agentPromptPreview,
1413
+ Ot as isLegacyBusinessAttributeCatalog,
1414
+ qt as legacyItemToScene,
1415
+ ee as sceneToLegacyItem
485
1416
  };