@freecallai/pro 0.0.0-stage → 0.0.2

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 (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +16 -2
  3. package/dist/FkpRichText.vue_vue_type_script_setup_true_lang-BuMz8Tyy.js +4416 -0
  4. package/dist/KnowledgeArea-BkRVWFrg.js +1224 -0
  5. package/dist/ToolForm-BSJxTJ7U.js +185 -0
  6. package/dist/choice-DDg5gNtS.js +29 -0
  7. package/dist/index-BVHYCLDv.js +5 -0
  8. package/dist/index-BnFTr8u9.js +49 -0
  9. package/dist/index-CG2j9Znw.js +41 -0
  10. package/dist/index-CJlAseSN.js +15 -0
  11. package/dist/index-CzpY61Qj.js +6 -0
  12. package/dist/index-D8bcFtWR.js +6 -0
  13. package/dist/index-DSgEWJGP.js +6 -0
  14. package/dist/index-DxxX09iY.js +6 -0
  15. package/dist/index-kOPLn4DD.js +5 -0
  16. package/dist/index-nnvfy5q0.js +31 -0
  17. package/dist/index-urNonkMH.js +6 -0
  18. package/dist/index.js +16 -0
  19. package/dist/inline-TT_dl8Y3.js +17 -0
  20. package/dist/knowledge-BZCmalF_.js +6 -0
  21. package/dist/knowledge-DnYGicjn.js +13 -0
  22. package/dist/media-extensions-ZoxmhIhH.js +276 -0
  23. package/dist/media-migration-Cj-3xrxd.js +59 -0
  24. package/dist/media-upload-D7DpMJYx.js +69 -0
  25. package/dist/operations-JgnjGx3H.js +19 -0
  26. package/dist/question-D1--acV8.js +10 -0
  27. package/dist/question-DGC6JHy5.js +6 -0
  28. package/dist/rich-text/index.js +224 -0
  29. package/dist/rich-text/legacy-converter/index.js +930 -0
  30. package/dist/rules-CC6NoltX.js +811 -0
  31. package/dist/selection-state-D47jhx0U.js +20 -0
  32. package/dist/state-KfOqha3d.js +16 -0
  33. package/dist/style.css +1 -0
  34. package/dist/types/index.d.ts +10 -0
  35. package/dist/types/rich-text/FkpRichText.vue.d.ts +253 -0
  36. package/dist/types/rich-text/MediaView.vue.d.ts +92 -0
  37. package/dist/types/rich-text/__demo__/conversion-fixtures.d.ts +35 -0
  38. package/dist/types/rich-text/__demo__/reasoning-template-examples.d.ts +12 -0
  39. package/dist/types/rich-text/config/catalog.d.ts +3 -0
  40. package/dist/types/rich-text/config/descriptor.d.ts +58 -0
  41. package/dist/types/rich-text/config/media-options.d.ts +6 -0
  42. package/dist/types/rich-text/config/resolve.d.ts +17 -0
  43. package/dist/types/rich-text/config/selection-options.d.ts +6 -0
  44. package/dist/types/rich-text/extensions.d.ts +6 -0
  45. package/dist/types/rich-text/index.d.ts +17 -0
  46. package/dist/types/rich-text/legacy-converter/business-attribute.d.ts +32 -0
  47. package/dist/types/rich-text/legacy-converter/index.d.ts +46 -0
  48. package/dist/types/rich-text/legacy-converter/tool-contract.d.ts +5 -0
  49. package/dist/types/rich-text/media-extensions.d.ts +4 -0
  50. package/dist/types/rich-text/media-id.d.ts +2 -0
  51. package/dist/types/rich-text/model/agent-context.d.ts +7 -0
  52. package/dist/types/rich-text/model/capability-diff.d.ts +14 -0
  53. package/dist/types/rich-text/model/condition-contract.d.ts +10 -0
  54. package/dist/types/rich-text/model/convert.d.ts +6 -0
  55. package/dist/types/rich-text/model/guard.d.ts +7 -0
  56. package/dist/types/rich-text/model/json-value.d.ts +2 -0
  57. package/dist/types/rich-text/model/media-migration.d.ts +8 -0
  58. package/dist/types/rich-text/model/node-contract.d.ts +10 -0
  59. package/dist/types/rich-text/model/node-identity.d.ts +8 -0
  60. package/dist/types/rich-text/model/persistence-contract.d.ts +25 -0
  61. package/dist/types/rich-text/model/preview.d.ts +2 -0
  62. package/dist/types/rich-text/model/question-text.d.ts +15 -0
  63. package/dist/types/rich-text/model/reasoning-context.d.ts +24 -0
  64. package/dist/types/rich-text/model/scene-snapshot.d.ts +4 -0
  65. package/dist/types/rich-text/model/validate.d.ts +19 -0
  66. package/dist/types/rich-text/model/web-url.d.ts +2 -0
  67. package/dist/types/rich-text/plugins/agentSelect/descriptor.d.ts +2 -0
  68. package/dist/types/rich-text/plugins/attribute/descriptor.d.ts +2 -0
  69. package/dist/types/rich-text/plugins/attribute/index.d.ts +2 -0
  70. package/dist/types/rich-text/plugins/block.d.ts +3 -0
  71. package/dist/types/rich-text/plugins/choice.d.ts +4 -0
  72. package/dist/types/rich-text/plugins/image/descriptor.d.ts +2 -0
  73. package/dist/types/rich-text/plugins/image/index.d.ts +2 -0
  74. package/dist/types/rich-text/plugins/inline.d.ts +3 -0
  75. package/dist/types/rich-text/plugins/media-upload.d.ts +3 -0
  76. package/dist/types/rich-text/plugins/memory/descriptor.d.ts +2 -0
  77. package/dist/types/rich-text/plugins/memory/index.d.ts +2 -0
  78. package/dist/types/rich-text/plugins/operations.d.ts +86 -0
  79. package/dist/types/rich-text/plugins/originalReply/descriptor.d.ts +2 -0
  80. package/dist/types/rich-text/plugins/originalReply/knowledge.d.ts +2 -0
  81. package/dist/types/rich-text/plugins/originalReply/question.d.ts +2 -0
  82. package/dist/types/rich-text/plugins/reasoningPolish/descriptor.d.ts +2 -0
  83. package/dist/types/rich-text/plugins/reasoningPolish/index.d.ts +3 -0
  84. package/dist/types/rich-text/plugins/reasoningTemplate/descriptor.d.ts +2 -0
  85. package/dist/types/rich-text/plugins/reasoningTemplate/index.d.ts +3 -0
  86. package/dist/types/rich-text/plugins/registry.d.ts +14 -0
  87. package/dist/types/rich-text/plugins/selection-state.d.ts +4 -0
  88. package/dist/types/rich-text/plugins/separator/descriptor.d.ts +2 -0
  89. package/dist/types/rich-text/plugins/separator/index.d.ts +2 -0
  90. package/dist/types/rich-text/plugins/state.d.ts +3 -0
  91. package/dist/types/rich-text/plugins/tagged/descriptor.d.ts +2 -0
  92. package/dist/types/rich-text/plugins/tagged/index.d.ts +2 -0
  93. package/dist/types/rich-text/plugins/ticket/descriptor.d.ts +2 -0
  94. package/dist/types/rich-text/plugins/ticket/index.d.ts +2 -0
  95. package/dist/types/rich-text/plugins/todo/descriptor.d.ts +2 -0
  96. package/dist/types/rich-text/plugins/todo/knowledge.d.ts +2 -0
  97. package/dist/types/rich-text/plugins/todo/question.d.ts +2 -0
  98. package/dist/types/rich-text/plugins/tool/descriptor.d.ts +2 -0
  99. package/dist/types/rich-text/plugins/tool/index.d.ts +2 -0
  100. package/dist/types/rich-text/plugins/tool/operations.d.ts +4 -0
  101. package/dist/types/rich-text/plugins/tool/presentation.d.ts +7 -0
  102. package/dist/types/rich-text/plugins/tool/rules.d.ts +34 -0
  103. package/dist/types/rich-text/plugins/variable/descriptor.d.ts +2 -0
  104. package/dist/types/rich-text/plugins/variable/index.d.ts +2 -0
  105. package/dist/types/rich-text/plugins/video/descriptor.d.ts +2 -0
  106. package/dist/types/rich-text/plugins/video/index.d.ts +2 -0
  107. package/dist/types/rich-text/public/types.d.ts +598 -0
  108. package/dist/types/rich-text/runtime/action-ports.d.ts +15 -0
  109. package/dist/types/rich-text/runtime/file-drop-guard.d.ts +2 -0
  110. package/dist/types/rich-text/runtime/media-policy.d.ts +15 -0
  111. package/dist/types/rich-text/runtime/media-state.d.ts +6 -0
  112. package/dist/types/rich-text/runtime/media-target.d.ts +9 -0
  113. package/dist/types/rich-text/runtime/media-upload-session.d.ts +63 -0
  114. package/dist/types/rich-text/runtime/media-upload-slots.d.ts +4 -0
  115. package/dist/types/rich-text/runtime/operations.d.ts +48 -0
  116. package/dist/types/rich-text/runtime/option-menu-session.d.ts +28 -0
  117. package/dist/types/rich-text/runtime/option-source.d.ts +10 -0
  118. package/dist/types/rich-text/runtime/port-result.d.ts +21 -0
  119. package/dist/types/rich-text/runtime/schema-plan.d.ts +17 -0
  120. package/dist/types/rich-text/runtime/tool-form-session.d.ts +39 -0
  121. package/dist/types/rich-text/runtime/tool-params.d.ts +5 -0
  122. package/dist/types/rich-text/types.d.ts +40 -0
  123. package/dist/types/rich-text/ui/CapabilityHelp.vue.d.ts +9 -0
  124. package/dist/types/rich-text/ui/KnowledgeArea.vue.d.ts +124 -0
  125. package/dist/types/rich-text/ui/ToolForm.vue.d.ts +14 -0
  126. package/dist/types/rich-text/ui/VariableOptionList.vue.d.ts +15 -0
  127. package/package.json +70 -3
@@ -0,0 +1,930 @@
1
+ import { q as $t, r as dt, t as ut, h as vt, b as ft, j as xt } from "../../rules-CC6NoltX.js";
2
+ import { a as At } from "../../media-migration-Cj-3xrxd.js";
3
+ function mt(t) {
4
+ const r = /^\$\$小额打款@([1-9]\d*)\$\$$/u.exec(t);
5
+ if (r) {
6
+ const p = Number(r[1]);
7
+ return p < 100 || p > 9900 || p % 100 !== 0 ? null : {
8
+ type: "businessToken",
9
+ attrs: {
10
+ kind: "tool",
11
+ key: "small_payment",
12
+ label: "小额打款",
13
+ params: { amount: String(p / 100) }
14
+ }
15
+ };
16
+ }
17
+ const c = /^\^\^订单备注-(固定话术|智能提取)@编号=(rmk_[a-z0-9]{8});插旗=([^;]+);保留已有旗帜=(是|否);位置=(最前|最后);内容=([\s\S]+)\^\^$/u.exec(
18
+ t
19
+ );
20
+ if (!c) return null;
21
+ const m = Object.keys(ut).find(
22
+ (p) => ut[p] === c[3]
23
+ );
24
+ if (!m) return null;
25
+ const s = {
26
+ id: c[2],
27
+ contentMode: c[1] === "固定话术" ? "fixed" : "smart",
28
+ content: c[6],
29
+ flag: m,
30
+ preserveFlag: c[4] === "是",
31
+ position: c[5] === "最前" ? "first" : "last"
32
+ };
33
+ return dt(s) ? {
34
+ type: "businessToken",
35
+ attrs: { kind: "tool", key: "order_note", label: "订单备注", params: s }
36
+ } : null;
37
+ }
38
+ function yt(t) {
39
+ var c;
40
+ if (t.type !== "businessToken" || ((c = t.attrs) == null ? void 0 : c.kind) !== "tool") return null;
41
+ const { params: r } = t.attrs;
42
+ return t.attrs.key === "small_payment" ? $t(r == null ? void 0 : r.amount) ? `$$小额打款@${Number(r.amount) * 100}$$` : null : t.attrs.key !== "order_note" || !dt(r) ? null : `^^订单备注-${r.contentMode === "fixed" ? "固定话术" : "智能提取"}@编号=${r.id};插旗=${ut[r.flag]};保留已有旗帜=${r.preserveFlag ? "是" : "否"};位置=${r.position === "first" ? "最前" : "最后"};内容=${r.content}^^`;
43
+ }
44
+ function St(t) {
45
+ try {
46
+ const r = JSON.parse(decodeURIComponent(t)), c = {
47
+ id: String(r.id || ""),
48
+ contentMode: r.content_type === "extract" ? "smart" : "fixed",
49
+ content: String(r.content || ""),
50
+ flag: r.flag,
51
+ preserveFlag: r.keep_flag_if_exists,
52
+ position: r.remark_position === "after" ? "last" : "first"
53
+ };
54
+ return !["fixed", "extract"].includes(String(r.content_type)) || !["before", "after"].includes(String(r.remark_position)) || !dt(c) ? null : {
55
+ type: "businessToken",
56
+ attrs: { kind: "tool", key: "order_note", label: "订单备注", params: c }
57
+ };
58
+ } catch {
59
+ return null;
60
+ }
61
+ }
62
+ const wt = [
63
+ { id: 1, key: "focus_goods_name", name: "焦点商品名称" },
64
+ { id: 2, key: "focus_goods_info", name: "焦点商品信息" },
65
+ { id: 3, key: "focus_goods_sku", name: "焦点商品sku信息" },
66
+ { id: 4, key: "focus_order_amount", name: "焦点订单实付金额" },
67
+ { id: 5, key: "focus_order_status", name: "焦点订单状态" },
68
+ { id: 6, key: "shop_name", name: "店铺名称" }
69
+ ], kt = Object.freeze(wt.map((t) => Object.freeze({ ...t })));
70
+ function bt(t) {
71
+ return kt.find((r) => r.name === t);
72
+ }
73
+ function Tt(t) {
74
+ return kt.find((r) => r.key === t);
75
+ }
76
+ function gt(t) {
77
+ return `{业务属性@${t}}`;
78
+ }
79
+ function o(t, r, c) {
80
+ return { ok: !1, issues: [{ path: r, message: c }], raw: t };
81
+ }
82
+ function N(t) {
83
+ return t.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
84
+ }
85
+ function st(t) {
86
+ 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" : "") || (t.getAttribute("data-tag") === "true" ? "todo" : "");
87
+ }
88
+ function pt(t, r = !1) {
89
+ if (typeof DOMParser > "u")
90
+ return o(t, "web_content", "当前环境不支持 HTML 解析");
91
+ const c = new DOMParser().parseFromString(t, "text/html"), m = [[]];
92
+ let s = null;
93
+ const p = (l) => m[m.length - 1].push(l), k = (l = !1) => {
94
+ (l || m[m.length - 1].length) && m.push([]);
95
+ }, $ = (l, i) => {
96
+ var M, C, B, R, T, U, z, W, H, J, L, F;
97
+ if (s) return;
98
+ if (l.nodeType === 3) {
99
+ (l.textContent || "").replace(/\r\n?/g, `
100
+ `).replace(
101
+ /\^\^订单备注-[\s\S]*?\^\^/gu,
102
+ (S) => S.replace(/\n/g, "")
103
+ ).split(`
104
+ `).forEach((S, x) => {
105
+ x && k(!0), S = S.replace(/\uE000/g, `
106
+ `);
107
+ let v = 0;
108
+ for (const b of S.matchAll(
109
+ /<\{原话复述\}([^<>]*)>|\{待办@([^{}]+)\}/gu
110
+ )) {
111
+ if (b[1] === void 0 && !r) continue;
112
+ const y = b.index || 0;
113
+ y > v && p({ kind: "text", value: S.slice(v, y) }), p(
114
+ b[1] !== void 0 ? { kind: "originalReply", html: N(b[1]) } : { kind: "todo", value: b[0] }
115
+ ), v = y + b[0].length;
116
+ }
117
+ v < S.length && p({ kind: "text", value: S.slice(v) });
118
+ });
119
+ return;
120
+ }
121
+ if (l.nodeType !== 1) return;
122
+ const a = l, g = a.tagName.toLowerCase(), d = st(a);
123
+ if (g === "span" && d === "original_repeat" && a.getAttribute("data-original-repeat-template") === "true") {
124
+ const _ = a.querySelectorAll('[data-original-repeat-input="true"]');
125
+ if (_.length !== 1) {
126
+ s = { path: i, message: "原话模板缺少唯一的回复输入区" };
127
+ return;
128
+ }
129
+ p({ kind: "originalReply", html: _[0].innerHTML });
130
+ return;
131
+ }
132
+ if (g === "span" && d) {
133
+ if (d === "no_send_follow_order") {
134
+ s = { path: i, message: "旧不发送跟单标签尚无新知识节点承载" };
135
+ return;
136
+ }
137
+ if (d === "size_chart" || d === "table_knowledge") {
138
+ s = { path: i, message: `旧${d}标签尚无新知识节点承载` };
139
+ return;
140
+ }
141
+ if (d === "biz_attribute") {
142
+ const v = (a.textContent || "").trim(), b = (M = v.match(
143
+ /^\{业务属性@([^{}<>\r\n]+)\}$/u
144
+ )) == null ? void 0 : M[1], y = ((C = a.getAttribute("data-attr-name")) == null ? void 0 : C.trim()) || b, j = y && bt(y);
145
+ !j || v !== y && v !== gt(y) || a.hasAttribute("data-attr-key") && a.getAttribute("data-attr-key") !== j.key || a.hasAttribute("data-attr-id") && a.getAttribute("data-attr-id") !== String(j.id) ? s = { path: i, message: "业务属性标签名称、ID 或 key 无效" } : p({ kind: "attribute", name: y, key: j.key });
146
+ return;
147
+ }
148
+ if (d === "small_payment" || d === "order_remark") {
149
+ if (d === "order_remark" && a.hasAttribute("data-order-remark")) {
150
+ const E = St(
151
+ a.getAttribute("data-order-remark") || ""
152
+ ), P = E && yt(E);
153
+ P ? p({ kind: "text", value: P }) : s = { path: i, message: "旧订单备注数据无效" };
154
+ return;
155
+ }
156
+ const v = a.textContent || "", b = mt(v), y = (B = b == null ? void 0 : b.attrs) == null ? void 0 : B.params;
157
+ (d === "small_payment" ? ((R = b == null ? void 0 : b.attrs) == null ? void 0 : R.key) === "small_payment" && a.getAttribute("data-max-amount-cent") === String(Number(y == null ? void 0 : y.amount) * 100) : ((T = b == null ? void 0 : b.attrs) == null ? void 0 : T.key) === "order_note" && a.getAttribute("data-remark-id") === (y == null ? void 0 : y.id) && a.getAttribute("data-remark-mode") === ((y == null ? void 0 : y.contentMode) === "fixed" ? "fixed" : "extract") && a.getAttribute("data-remark-flag") === (y == null ? void 0 : y.flag) && a.getAttribute("data-remark-keep-flag") === (y != null && y.preserveFlag ? "1" : "0") && a.getAttribute("data-remark-position") === (y == null ? void 0 : y.position) && a.getAttribute("data-remark-content") === (y == null ? void 0 : y.content)) ? p({ kind: "text", value: v }) : s = { path: i, message: `${d} 标签属性与内容不一致` };
158
+ return;
159
+ }
160
+ if (d === "variable") {
161
+ const v = (a.textContent || "").trim(), b = (z = (U = v.match(/^#([^#\r\n]+)#$/u)) == null ? void 0 : U[1]) == null ? void 0 : z.trim(), j = ((W = a.getAttribute("data-variable-name")) == null ? void 0 : W.trim()) || b;
162
+ !j || !b || b !== j ? s = { path: i, message: "变量标签名称与显示内容不一致" } : p({
163
+ kind: "text",
164
+ value: j === "订单链接" ? "{订单链接}" : v
165
+ });
166
+ return;
167
+ }
168
+ const _ = a.getAttribute("data-tag-name") || a.getAttribute("data-variable-name") || a.getAttribute("data-agent-name") || "", S = a.textContent || "";
169
+ if (d === "cdp_tag" && (!a.getAttribute("data-tag-id") || /已失效/u.test(S))) {
170
+ s = { path: i, message: "失效顾客标签需要只读保全" };
171
+ return;
172
+ }
173
+ if (d === "todo" || d === "cdp_tag") {
174
+ const v = (H = S.match(
175
+ d === "todo" ? /\{待办@([^{}]+)\}/u : /\{(?:顾客标签|意图标签)@([^{}]+)\}/u
176
+ )) == null ? void 0 : H[1], b = a.getAttribute("data-tag-name");
177
+ if (v && b && v !== b) {
178
+ s = { path: i, message: `${d} 标签名称与显示内容不一致` };
179
+ return;
180
+ }
181
+ }
182
+ const x = {
183
+ todo: ((J = S.match(/\{待办(?:@[^{}]+)?\}/u)) == null ? void 0 : J[0]) || (_ ? `{待办@${_}}` : ""),
184
+ cdp_tag: ((L = S.match(/\{(?:顾客标签|意图标签)@[^{}]+\}/u)) == null ? void 0 : L[0]) || (_ ? `{顾客标签@${_}}` : ""),
185
+ separator: "{分隔符}",
186
+ original_repeat: "{原话复述}",
187
+ custom_agent: ((F = S.match(/\{自定义Agent\}@[\s\S]+/u)) == null ? void 0 : F[0]) || (_ ? `{自定义Agent}@${_}` : ""),
188
+ reasoning: "{推理}",
189
+ memory_trigger: "{记忆触发点}"
190
+ };
191
+ x[d] ? p({
192
+ kind: d === "todo" ? "todo" : "text",
193
+ value: x[d]
194
+ }) : s = { path: i, message: `旧标签 ${d} 无法映射到新模型` };
195
+ return;
196
+ }
197
+ if (g === "img" && a.getAttribute("data-tag-icon") === "true") return;
198
+ if (g === "img" || g === "video") {
199
+ const _ = a.getAttribute("src") || "";
200
+ xt(_) ? p({
201
+ kind: "media",
202
+ media: g === "img" ? "image" : "video",
203
+ src: _,
204
+ path: i
205
+ }) : s = { path: i, message: "媒体地址无效" };
206
+ return;
207
+ }
208
+ if (g === "br") {
209
+ k(!0);
210
+ return;
211
+ }
212
+ if (!["p", "div", "span"].includes(g) || g === "span" && a.attributes.length > 0) {
213
+ s = { path: i, message: `HTML 标签 ${g} 无法无损转换` };
214
+ return;
215
+ }
216
+ (g === "p" || g === "div") && k();
217
+ const G = m.length;
218
+ Array.from(a.childNodes).forEach(
219
+ (_, S) => $(_, `${i}.childNodes[${S}]`)
220
+ ), (g === "p" || g === "div") && (m.length === G || m[m.length - 1].length) && k(!0);
221
+ };
222
+ return Array.from(c.body.childNodes).forEach(
223
+ (l, i) => $(l, `web_content.childNodes[${i}]`)
224
+ ), s ? { ok: !1, issues: [s], raw: t } : (m.length > 1 && !m[m.length - 1].length && m.pop(), { ok: !0, value: m });
225
+ }
226
+ function rt(t) {
227
+ return t.every(
228
+ (r) => r.kind === "text" || r.kind === "todo" || r.kind === "attribute"
229
+ ) ? t.map(
230
+ (r) => r.kind === "attribute" ? gt(r.name) : r.value
231
+ ).join("") : null;
232
+ }
233
+ function It(t, r, c) {
234
+ var k, $;
235
+ const m = [], s = /(#@[^#]+@#|##[^#]+##|#[^#\r\n]+#|\{[^{}]+\}|\[sep\]|\$\$小额打款@[^$\r\n]*\$\$|\^\^订单备注-[\s\S]*?\^\^)/gu;
236
+ let p = 0;
237
+ for (const l of t.matchAll(s)) {
238
+ const i = l.index || 0;
239
+ if (i > p) {
240
+ const g = t.slice(p, i);
241
+ if (/\$\$小额打款|\^\^订单备注-|\{业务属性@|<不发送跟单>/u.test(g))
242
+ return o(t, r, "工具、业务属性或不发送跟单标记格式错误");
243
+ m.push({ type: "text", text: g });
244
+ }
245
+ const a = l[0];
246
+ if (a.startsWith("$$小额打款@") || a.startsWith("^^订单备注-")) {
247
+ const g = mt(a);
248
+ if (!g) return o(t, r, `工具标记 ${a} 格式错误`);
249
+ m.push(g);
250
+ } else if (a === "{分隔符}" || a === "[sep]")
251
+ m.push({
252
+ type: "businessToken",
253
+ attrs: {
254
+ kind: "separator",
255
+ key: "separator",
256
+ label: "分隔符",
257
+ token: "{分隔符}"
258
+ }
259
+ });
260
+ else if (a === "{订单链接}" || /^#[^#\r\n]+#$/u.test(a)) {
261
+ const g = a === "{订单链接}" ? "订单链接" : a.slice(1, -1).trim(), d = (k = c.variable) == null ? void 0 : k.call(c, g);
262
+ if (!g || !(d != null && d.key) || d.label !== g)
263
+ return o(t, r, `变量 ${g} 缺少可解析的引用`);
264
+ m.push({
265
+ type: "businessToken",
266
+ attrs: { kind: "variable", key: d.key, label: d.label, token: a }
267
+ });
268
+ } else if (a.startsWith("{业务属性@")) {
269
+ const g = ($ = a.match(/^\{业务属性@([^{}<>\r\n]+)\}$/u)) == null ? void 0 : $[1], d = g && bt(g);
270
+ if (!d)
271
+ return o(t, r, `业务属性 ${g || a} 不在旧目录中`);
272
+ m.push({
273
+ type: "businessToken",
274
+ attrs: { kind: "attribute", key: d.key, label: d.name }
275
+ });
276
+ } else return o(t, r, `正文标记 ${a} 无法在当前位置转换`);
277
+ p = i + a.length;
278
+ }
279
+ if (p < t.length) {
280
+ const l = t.slice(p);
281
+ if (/\$\$小额打款|\^\^订单备注-|\{业务属性@|<不发送跟单>/u.test(l))
282
+ return o(t, r, "工具、业务属性或不发送跟单标记格式错误");
283
+ m.push({ type: "text", text: l });
284
+ }
285
+ return { ok: !0, value: m };
286
+ }
287
+ function _t(t, r) {
288
+ const c = /* @__PURE__ */ new Set();
289
+ let m = 0, s = null;
290
+ const p = (k, $) => {
291
+ var l, i, a;
292
+ if (k.type === "businessToken" && ((l = k.attrs) == null ? void 0 : l.kind) === "tool" && (k.attrs.key === "small_payment" && ++m > 1 && (s = $), k.attrs.key === "order_note")) {
293
+ const g = String(((i = k.attrs.params) == null ? void 0 : i.id) || "");
294
+ c.has(g) && (s = $), c.add(g);
295
+ }
296
+ (a = k.content) == null || a.forEach(
297
+ (g, d) => p(g, `${$}.content[${d}]`)
298
+ );
299
+ };
300
+ return t.forEach((k, $) => p(k, `${r}[${$}]`)), s;
301
+ }
302
+ function Nt(t) {
303
+ var r, c, m, s, p;
304
+ for (let k = 0; k < t.length; k++) {
305
+ const $ = t[k], l = (r = $.content) == null ? void 0 : r[0];
306
+ if ($.type !== "paragraph" || ((c = $.content) == null ? void 0 : c.length) !== 1 || (l == null ? void 0 : l.type) !== "businessToken" || ((m = l.attrs) == null ? void 0 : m.kind) !== "separator")
307
+ continue;
308
+ const i = t[k - 1], a = t[k + 1];
309
+ if ((i == null ? void 0 : i.type) === "paragraph" && ((s = i.content) != null && s.length))
310
+ i.content.push(l);
311
+ else if ((a == null ? void 0 : a.type) === "paragraph" && ((p = a.content) != null && p.length))
312
+ a.content.unshift(l);
313
+ else continue;
314
+ t.splice(k--, 1);
315
+ }
316
+ }
317
+ function Et(t, r, c = {}, m = {}) {
318
+ var X, Z, K, tt, et, nt, at, h;
319
+ if (!t || typeof t != "object" || Array.isArray(t))
320
+ return o(t, "item", "旧知识记录格式不正确");
321
+ if (!(r != null && r.trim()))
322
+ return o(t, "sourceRecordKey", "需要稳定的来源记录键");
323
+ const s = typeof t.web_content == "string" && t.web_content ? "web_content" : "content", p = t[s];
324
+ if (typeof p != "string") return o(t, s, "旧知识缺少内容");
325
+ const k = s === "content" && (!!String(t.todo_plan_id || "").trim() || !!t.todo_tag_metas), $ = pt(p, k);
326
+ if (!$.ok) return { ...$, raw: t };
327
+ const l = $.value, i = l[0] || [], a = i.findIndex(
328
+ (e) => e.kind === "originalReply" || e.kind === "media"
329
+ ), g = rt(
330
+ a >= 0 ? i.slice(0, a) : i
331
+ ), d = g == null ? void 0 : g.match(/^\s*【([^【】\r\n]+)】([\s\S]*)$/u), G = d ? d[1] : m.questionText ?? "";
332
+ if (vt(G))
333
+ return o(t, "questionText", "顾客问法包含保留分隔符");
334
+ const M = new DOMParser().parseFromString(p, "text/html"), C = Array.from(
335
+ M.querySelectorAll('span[data-tag-type="todo"], span[data-tag="true"]')
336
+ ).filter((e) => st(e) === "todo").map(
337
+ (e) => {
338
+ var n;
339
+ return ((n = (e.textContent || "").match(/\{待办@([^{}]+)\}/u)) == null ? void 0 : n[1]) || e.getAttribute("data-tag-name") || "";
340
+ }
341
+ );
342
+ k && C.push(
343
+ ...Array.from(p.matchAll(/\{待办@([^{}]+)\}/gu), (e) => e[1])
344
+ );
345
+ const B = Array.from(
346
+ M.querySelectorAll('span[data-tag-type="cdp_tag"]')
347
+ ).map((e) => {
348
+ var n;
349
+ return {
350
+ name: ((n = (e.textContent || "").match(
351
+ /\{(?:顾客标签|意图标签)@([^{}]+)\}/u
352
+ )) == null ? void 0 : n[1]) || e.getAttribute("data-tag-name") || "",
353
+ id: e.getAttribute("data-tag-id") || ""
354
+ };
355
+ });
356
+ if (B.length > 1)
357
+ return o(t, s, "新模型每条问法只能选择一个顾客标签");
358
+ const R = /* @__PURE__ */ new Map();
359
+ for (const [e, n] of Array.from(
360
+ M.querySelectorAll('span[data-tag-type="todo"], span[data-tag="true"]')
361
+ ).entries()) {
362
+ if (st(n) !== "todo") continue;
363
+ const u = (X = n.getAttribute("plan_id")) == null ? void 0 : X.trim();
364
+ if (!u) continue;
365
+ const I = ((Z = (n.textContent || "").match(/\{待办@([^{}]+)\}/u)) == null ? void 0 : Z[1]) || n.getAttribute("data-tag-name") || "";
366
+ if (!I)
367
+ return o(t, `${s}.todo[${e}]`, "待办标签缺少方案名称");
368
+ const f = R.get(I);
369
+ if (f && f.id !== u)
370
+ return o(
371
+ t,
372
+ `${s}.todo[${e}]`,
373
+ "同名待办对应多个方案 ID"
374
+ );
375
+ R.set(I, { id: u, label: I });
376
+ }
377
+ if (t.todo_tag_metas !== void 0 && t.todo_tag_metas !== "") {
378
+ let e = t.todo_tag_metas;
379
+ if (typeof e == "string")
380
+ try {
381
+ e = JSON.parse(e);
382
+ } catch {
383
+ return o(t, "todo_tag_metas", "待办方案元数据不是有效 JSON");
384
+ }
385
+ if (!Array.isArray(e))
386
+ return o(t, "todo_tag_metas", "待办方案元数据必须为数组");
387
+ for (const [n, u] of e.entries()) {
388
+ if (!u || typeof u != "object" || typeof u.plan_id != "string" || !u.plan_id.trim() || typeof u.plan_name != "string" || !u.plan_name.trim() || u.tag_type !== void 0 && u.tag_type !== 2)
389
+ return o(
390
+ t,
391
+ `todo_tag_metas[${n}]`,
392
+ "待办方案缺少有效 ID、名称或已失效"
393
+ );
394
+ const I = R.get(u.plan_name);
395
+ if (I && I.id !== u.plan_id)
396
+ return o(
397
+ t,
398
+ `todo_tag_metas[${n}]`,
399
+ "待办方案元数据与富文本标签的 plan_id 不一致"
400
+ );
401
+ R.set(u.plan_name, {
402
+ id: u.plan_id,
403
+ label: u.plan_name
404
+ });
405
+ }
406
+ }
407
+ if (String(t.todo_plan_id || "").trim() && typeof t.todo_plan_name == "string") {
408
+ const e = R.get(t.todo_plan_name);
409
+ if (e && e.id !== String(t.todo_plan_id))
410
+ return o(t, "todo_plan_id", "待办方案字段与多方案元数据不一致");
411
+ R.set(t.todo_plan_name, {
412
+ id: String(t.todo_plan_id),
413
+ label: t.todo_plan_name
414
+ });
415
+ }
416
+ const T = {}, U = !d && g && /^(?:\{(?:待办|顾客标签|意图标签)@[^{}]+\}|\{(?:原话复述|记忆触发点|推理)\})+$/u.test(
417
+ g.trim()
418
+ ), z = [];
419
+ let W = !1, H = "", J = "", L = (d == null ? void 0 : d[2].trim()) || (U ? g.trim() : "");
420
+ for (; L; ) {
421
+ if (L.startsWith("{自定义Agent}@")) {
422
+ J = L;
423
+ break;
424
+ }
425
+ const e = L.match(
426
+ /^\{(待办|顾客标签|意图标签)@([^{}]+)\}|^\{(原话复述|记忆触发点|推理)\}/u
427
+ );
428
+ if (!e) {
429
+ if (L.startsWith("{"))
430
+ return o(t, s, `问法后的标记无法转换:${L}`);
431
+ H = L;
432
+ break;
433
+ }
434
+ if (e[1]) {
435
+ const n = e[1] === "待办" ? "todo" : "tagged", u = n === "todo" ? C.find((D) => D === e[2]) : B.find((D) => D.name === e[2]);
436
+ if (!u)
437
+ return o(
438
+ t,
439
+ s,
440
+ `${e[1]} ${e[2]} 不是有效的旧版富文本标签`
441
+ );
442
+ const I = n === "todo" && t.todo_plan_name === e[2] ? String(t.todo_plan_id || "") : n === "tagged" ? u.id : "", f = n === "todo" && R.has(e[2]) ? R.get(e[2]) : I ? { id: I, label: e[2] } : (K = c.selection) == null ? void 0 : K.call(c, n, e[2]);
443
+ if (!(f != null && f.id) || !f.label || f.label !== e[2])
444
+ return o(
445
+ t,
446
+ s,
447
+ `${e[1]} ${e[2]} 缺少匹配的方案 ID`
448
+ );
449
+ if (n === "todo")
450
+ z.push({ kind: "todo", value: e[0] });
451
+ else {
452
+ if (T[n]) return o(t, s, `${e[1]}重复`);
453
+ T[n] = { version: 1, data: { enabled: !0, tag: f } };
454
+ }
455
+ } else if (e[3] === "推理") {
456
+ if (W) return o(t, s, "推理标记重复");
457
+ W = !0;
458
+ } else {
459
+ const n = e[3] === "原话复述" ? "originalReply" : "memory";
460
+ if (T[n]) return o(t, s, `${e[3]}重复`);
461
+ T[n] = { version: 1, data: { enabled: !0 } };
462
+ }
463
+ L = L.slice(e[0].length).trimStart();
464
+ }
465
+ if (Array.isArray(t.tag_meta))
466
+ for (const [e, n] of t.tag_meta.entries()) {
467
+ if (!n || typeof n != "object")
468
+ return o(t, `tag_meta[${e}]`, "标签元数据格式错误");
469
+ const u = n;
470
+ if (![
471
+ "cdp_tag",
472
+ "todo",
473
+ "variable",
474
+ "reasoning",
475
+ "original_repeat",
476
+ "custom_agent",
477
+ "memory",
478
+ "separator"
479
+ ].includes(String(u.type)))
480
+ return o(
481
+ t,
482
+ `tag_meta[${e}]`,
483
+ "旧标签元数据无法映射到新模型"
484
+ );
485
+ if (u.invalid)
486
+ return o(t, `tag_meta[${e}]`, "失效标签需要只读保全");
487
+ if (u.type === "cdp_tag" && (!T.tagged || T.tagged.data.tag.id !== String(u.value || "") || T.tagged.data.tag.label !== String(u.name || "")))
488
+ return o(
489
+ t,
490
+ `tag_meta[${e}]`,
491
+ "顾客标签 ID 与富文本标签不一致"
492
+ );
493
+ }
494
+ const F = t.todo_plan_id;
495
+ if (F != null && String(F).trim()) {
496
+ const e = t.todo_plan_name;
497
+ if (typeof e != "string" || !e.trim())
498
+ return o(t, "todo_plan_name", "待办方案 ID 存在但名称缺失");
499
+ if (!C.includes(e))
500
+ return o(t, "web_content", "待办方案字段缺少对应的富文本标签");
501
+ }
502
+ const _ = d || U ? l.slice(1) : [...l];
503
+ d && a >= 0 && _.unshift(i.slice(a)), J && _.unshift([{ kind: "text", value: J }]);
504
+ const S = Number(t.knowledge_type || 0);
505
+ let x = S === 2 ? "reasoning" : S === 3 ? "agent" : "normal";
506
+ if (t.knowledge_type !== void 0 && ![0, 1, 2, 3].includes(S))
507
+ return o(t, "knowledge_type", "未知的旧知识类型");
508
+ if (Array.isArray(t.tag_meta)) {
509
+ if (t.tag_meta.some(
510
+ (e) => e && typeof e == "object" && e.type === "reasoning"
511
+ ) && S === 1)
512
+ return o(t, "tag_meta", "推理标签与知识类型不一致");
513
+ if (t.tag_meta.some(
514
+ (e) => e && typeof e == "object" && e.type === "custom_agent"
515
+ ) && (S === 1 || S === 2))
516
+ return o(t, "tag_meta", "Agent 标签与知识类型不一致");
517
+ }
518
+ let v = null;
519
+ const b = (tt = _[0]) == null ? void 0 : tt[0], y = (b == null ? void 0 : b.kind) === "text" && /^\s*\{推理\}/u.test(b.value);
520
+ if (W || y) {
521
+ if (x === "agent")
522
+ return o(t, s, "推理标记与 Agent 类型冲突");
523
+ if (x = "reasoning", y && (b == null ? void 0 : b.kind) === "text") {
524
+ const e = b.value.replace(/^\s*\{推理\}\s*/u, ""), n = _[0].slice(1);
525
+ for (e && n.unshift({ kind: "text", value: e }); ((et = n[0]) == null ? void 0 : et.kind) === "text" && !n[0].value.trim(); )
526
+ n.shift();
527
+ n.length ? _[0] = n : _.shift();
528
+ }
529
+ }
530
+ if (_.length && ((nt = rt(_[0])) != null && nt.trim().startsWith("{自定义Agent}@"))) {
531
+ if (x === "reasoning")
532
+ return o(t, s, "Agent 标记与推理类型冲突");
533
+ x = "agent";
534
+ const e = rt(_[0]).trim().slice(11), n = Array.isArray(t.tag_meta) ? t.tag_meta.find(
535
+ (f) => f && typeof f == "object" && f.type === "custom_agent" && f.agent_name === e
536
+ ) : void 0, u = Array.from(
537
+ M.querySelectorAll("span[data-agent-id]")
538
+ ).find(
539
+ (f) => st(f) === "custom_agent" && ((f.textContent || "").trim() === `{自定义Agent}@${e}` || f.getAttribute("data-agent-name") === e || f.getAttribute("data-tag-name") === e)
540
+ ), I = (u == null ? void 0 : u.getAttribute("data-agent-id")) || "";
541
+ if (I && (n != null && n.agent_id) && I !== n.agent_id)
542
+ return o(t, "tag_meta", "Agent ID 与富文本标签不一致");
543
+ if (v = typeof (n == null ? void 0 : n.agent_id) == "string" && n.agent_id ? { id: n.agent_id, name: e } : I.trim() ? { id: I, name: e } : ((at = c.agent) == null ? void 0 : at.call(c, e)) || null, !(v != null && v.id) || v.name !== e)
544
+ return o(t, s, `Agent ${e} 缺少匹配的 ID`);
545
+ _.shift();
546
+ }
547
+ if (x === "agent" && !v)
548
+ return o(t, s, "Agent 知识缺少可解析的 Agent 标记");
549
+ H && _.unshift([{ kind: "text", value: H }]);
550
+ const j = (e, n, u = !1, I = !1) => {
551
+ var w;
552
+ if (e.kind === "originalReply")
553
+ return o(t, n, "原话块不可嵌套原话模板");
554
+ if (e.kind === "media")
555
+ return o(t, n, "原话块包含无法转换的媒体");
556
+ if (e.kind === "attribute")
557
+ return x !== "reasoning" || I ? o(
558
+ t,
559
+ n,
560
+ "业务属性只能位于推理知识正文,不能放入原话"
561
+ ) : {
562
+ ok: !0,
563
+ value: [
564
+ {
565
+ type: "businessToken",
566
+ attrs: { kind: "attribute", key: e.key, label: e.name }
567
+ }
568
+ ]
569
+ };
570
+ if (e.kind !== "todo") {
571
+ const A = It(
572
+ x === "normal" ? e.value.replace(/\{(?:待办(?:@[^{}]+)?|原话复述)\}/gu, "") : e.value,
573
+ n,
574
+ c
575
+ );
576
+ return A.ok && (x !== "reasoning" || I) && A.value.some(
577
+ (q) => {
578
+ var O;
579
+ return q.type === "businessToken" && ((O = q.attrs) == null ? void 0 : O.kind) === "attribute";
580
+ }
581
+ ) ? o(
582
+ t,
583
+ n,
584
+ "业务属性只能位于推理知识正文,不能放入原话"
585
+ ) : A;
586
+ }
587
+ if (x === "normal" && !u) return { ok: !0, value: [] };
588
+ if (x === "agent")
589
+ return o(t, n, "Agent 知识当前没有可保存的待办正文");
590
+ if (e.value === "{待办}")
591
+ return o(t, n, "知识区待办缺少可解析的方案名称和 ID");
592
+ const f = e.value.slice(4, -1), D = R.get(f) || ((w = c.selection) == null ? void 0 : w.call(c, "todo", f));
593
+ return !(D != null && D.id) || D.label !== f ? o(t, n, `待办 ${f} 缺少匹配的方案 ID`) : x === "normal" && T.todo ? o(t, s, "待办重复") : x === "normal" ? (T.todo = { version: 1, data: { enabled: !0, tag: D } }, { ok: !0, value: [] }) : {
594
+ ok: !0,
595
+ value: [
596
+ {
597
+ type: "businessToken",
598
+ attrs: { kind: "todo", key: D.id, label: D.label }
599
+ }
600
+ ]
601
+ };
602
+ };
603
+ if (x === "normal") {
604
+ !z.length && String(F || "").trim() && typeof t.todo_plan_name == "string" && (T.todo = {
605
+ version: 1,
606
+ data: {
607
+ enabled: !0,
608
+ tag: { id: String(F), label: t.todo_plan_name }
609
+ }
610
+ });
611
+ for (const e of z) {
612
+ const n = j(e, s, !0);
613
+ if (!n.ok) return { ...n, raw: t };
614
+ }
615
+ } else z.length && _.unshift(z);
616
+ x !== "normal" && T.originalReply && (delete T.originalReply, _.unshift([{ kind: "text", value: "{原话复述}" }]));
617
+ const E = [];
618
+ for (let e = 0; e < _.length; e++) {
619
+ const n = _[e], u = `${s}.line[${e + 2}]`;
620
+ if (((h = rt(n)) == null ? void 0 : h.trim()) === "{原话复述}" && x === "reasoning") {
621
+ const w = _[++e];
622
+ if (!w) return o(t, u, "原话块缺少内容");
623
+ if (rt(w) === null) return o(t, u, "原话块包含无法转换的媒体");
624
+ const q = [];
625
+ for (const O of w) {
626
+ const Y = j(O, u, !1, !0);
627
+ if (!Y.ok) return { ...Y, raw: t };
628
+ q.push(...Y.value);
629
+ }
630
+ E.push({
631
+ type: "originalReply",
632
+ content: [{ type: "paragraph", content: q }]
633
+ });
634
+ continue;
635
+ }
636
+ if (x === "agent") {
637
+ if (n.some(
638
+ (w) => w.kind === "text" || w.kind === "todo" ? !!w.value.trim() : !0
639
+ ))
640
+ return o(t, u, "Agent 知识不能包含正文");
641
+ continue;
642
+ }
643
+ let f = [];
644
+ const D = () => {
645
+ f.length && (E.push({ type: "paragraph", content: f }), f = []);
646
+ };
647
+ for (const w of n)
648
+ if (w.kind === "originalReply") {
649
+ f.every((O) => {
650
+ var Y;
651
+ return O.type === "text" && !((Y = O.text) != null && Y.trim());
652
+ }) && (f = []), D();
653
+ const A = pt(w.html, k);
654
+ if (!A.ok) return { ...A, raw: t };
655
+ const q = [];
656
+ for (const [O, Y] of A.value.entries()) {
657
+ const ct = [];
658
+ for (const ht of Y) {
659
+ const lt = j(
660
+ ht,
661
+ `${u}.originalReply[${O}]`,
662
+ !1,
663
+ !0
664
+ );
665
+ if (!lt.ok) return { ...lt, raw: t };
666
+ ct.push(...lt.value);
667
+ }
668
+ q.push({ type: "paragraph", content: ct });
669
+ }
670
+ x === "normal" ? E.push(...q) : E.push({ type: "originalReply", content: q });
671
+ } else if (w.kind === "media")
672
+ D(), E.push({
673
+ type: "mediaBlock",
674
+ attrs: { kind: w.media, src: w.src, status: "ready" }
675
+ });
676
+ else {
677
+ const A = j(w, u);
678
+ if (!A.ok) return { ...A, raw: t };
679
+ f.push(...A.value);
680
+ }
681
+ n.some((w) => w.kind === "originalReply") && f.every((w) => {
682
+ var A;
683
+ return w.type === "text" && !((A = w.text) != null && A.trim());
684
+ }) && (f = []), (f.length || !n.length) && E.push({ type: "paragraph", content: f });
685
+ }
686
+ Nt(E);
687
+ const P = _t(E, `${s}.block`);
688
+ if (P) return o(t, P, "工具标签重复");
689
+ const ot = {
690
+ type: "doc",
691
+ content: E.length ? E : [{ type: "paragraph" }]
692
+ }, it = x === "agent" ? null : At(ot, r).doc, Q = {
693
+ schemaVersion: 1,
694
+ type: x,
695
+ question: { text: G },
696
+ knowledge: { doc: it, agentRef: v },
697
+ extensionState: T
698
+ }, V = ft(Q);
699
+ return V ? o(t, V, "转换后的场景未通过新模型校验") : { ok: !0, value: Q };
700
+ }
701
+ function Rt(t, r) {
702
+ var c, m, s, p, k, $;
703
+ if (t.type === "text" && !((c = t.marks) != null && c.length))
704
+ return {
705
+ ok: !0,
706
+ value: { html: N(t.text || ""), text: t.text || "" }
707
+ };
708
+ if (t.type === "businessToken" && ((m = t.attrs) == null ? void 0 : m.kind) === "todo") {
709
+ const l = String(t.attrs.label), i = `{待办@${l}}`;
710
+ return {
711
+ ok: !0,
712
+ value: {
713
+ html: `<span contenteditable="false" data-tag="true" data-tag-type="todo" data-tag-name="${N(
714
+ l
715
+ )}" plan_id="${N(String(t.attrs.key))}">${N(
716
+ i
717
+ )}</span>`,
718
+ text: i
719
+ }
720
+ };
721
+ }
722
+ if (t.type === "businessToken" && ((s = t.attrs) == null ? void 0 : s.kind) === "variable") {
723
+ const l = String(t.attrs.label || t.attrs.key), i = l === "订单链接" ? "{订单链接}" : `#${l}#`, a = `#${l}#`;
724
+ return {
725
+ ok: !0,
726
+ value: {
727
+ html: `<span contenteditable="false" data-tag-type="variable" data-variable="true" data-variable-name="${N(
728
+ l
729
+ )}"${l === "客服昵称" ? ' data-customer="true"' : ""}>${N(
730
+ a
731
+ )}</span>`,
732
+ text: i
733
+ }
734
+ };
735
+ }
736
+ if (t.type === "businessToken" && ((p = t.attrs) == null ? void 0 : p.kind) === "attribute") {
737
+ const l = Tt(String(t.attrs.key));
738
+ if (!l || t.attrs.label !== l.name)
739
+ return o(t, r, "业务属性不在旧目录中或名称与 key 不一致");
740
+ const i = N(l.name);
741
+ return {
742
+ ok: !0,
743
+ value: {
744
+ html: `<span contenteditable="false" data-tag="true" data-tag-type="biz_attribute" data-attr-name="${i}" data-attr-key="${l.key}" data-attr-id="${l.id}">${i}</span>`,
745
+ text: gt(l.name)
746
+ }
747
+ };
748
+ }
749
+ if (t.type === "businessToken" && ((k = t.attrs) == null ? void 0 : k.kind) === "separator")
750
+ return {
751
+ ok: !0,
752
+ value: {
753
+ html: '<span data-tag-type="separator" data-divider="true" contenteditable="false">分隔符</span>',
754
+ text: "[sep]"
755
+ }
756
+ };
757
+ if (t.type === "businessToken" && (($ = t.attrs) == null ? void 0 : $.kind) === "tool") {
758
+ const l = yt(t);
759
+ if (!l) return o(t, r, "工具参数无法映射到旧格式");
760
+ const { params: i } = t.attrs;
761
+ return { ok: !0, value: { html: t.attrs.key === "small_payment" ? `<span contenteditable="false" data-tag="true" data-tag-type="small_payment" data-max-amount-cent="${Number(i.amount) * 100}">${N(l)}</span>` : `<span contenteditable="false" data-tag="true" data-tag-type="order_remark" data-remark-id="${N(
762
+ i.id
763
+ )}" data-remark-mode="${i.contentMode === "fixed" ? "fixed" : "extract"}" data-remark-flag="${N(
764
+ i.flag
765
+ )}" data-remark-keep-flag="${i.preserveFlag ? "1" : "0"}" data-remark-position="${i.position}" data-remark-content="${N(i.content)}">${N(
766
+ l
767
+ )}</span>`, text: l } };
768
+ }
769
+ return o(t, r, `节点 ${t.type} 无法映射到旧格式`);
770
+ }
771
+ function Lt(t, r = {}, c = {}) {
772
+ var U, z, W, H, J, L, F, _, S, x, v, b, y, j, E, P, ot, it, Q, V, X, Z, K, tt, et, nt, at;
773
+ const m = ft(t);
774
+ if (m) return o(t, m, "场景未通过新模型校验");
775
+ const s = _t(
776
+ ((U = t.knowledge.doc) == null ? void 0 : U.content) || [],
777
+ "knowledge.doc.content"
778
+ );
779
+ if (s) return o(t, s, "工具标签重复");
780
+ const p = `【${t.question.text}】`, k = [], $ = [];
781
+ for (const [h, e] of [
782
+ ["todo", "待办"],
783
+ ["tagged", "顾客标签"]
784
+ ]) {
785
+ const n = (z = t.extensionState[h]) == null ? void 0 : z.data;
786
+ if (n != null && n.enabled) {
787
+ const u = `{${e}@${(W = n.tag) == null ? void 0 : W.label}}`;
788
+ k.push(u), $.push(
789
+ h === "todo" ? `<span contenteditable="false" data-tag="true" data-tag-type="todo" data-tag-name="${N(
790
+ ((H = n.tag) == null ? void 0 : H.label) || ""
791
+ )}" plan_id="${N(((J = n.tag) == null ? void 0 : J.id) || "")}">${N(
792
+ u
793
+ )}</span>` : `<span contenteditable="false" data-tag="true" data-tag-type="cdp_tag" data-tag-name="${N(
794
+ ((L = n.tag) == null ? void 0 : L.label) || ""
795
+ )}" data-tag-id="${N(((F = n.tag) == null ? void 0 : F.id) || "")}">${N(
796
+ u
797
+ )}</span>`
798
+ );
799
+ }
800
+ }
801
+ (S = (_ = t.extensionState.originalReply) == null ? void 0 : _.data) != null && S.enabled && (k.push("{原话复述}"), $.push(
802
+ '<span data-tag-type="original_repeat" data-retelling="true">{原话复述}</span>'
803
+ )), (v = (x = t.extensionState.memory) == null ? void 0 : x.data) != null && v.enabled && (k.push("{记忆触发点}"), $.push(
804
+ '<span data-tag-type="memory_trigger" data-memory-trigger="true">{记忆触发点}</span>'
805
+ ));
806
+ for (const h of Object.keys(t.extensionState))
807
+ if (!["todo", "tagged", "originalReply", "memory"].includes(h))
808
+ return o(
809
+ t,
810
+ `extensionState.${h}`,
811
+ "旧格式无法表示此插件状态"
812
+ );
813
+ const l = c.questionStorage || (/^\s*(?:<(?:div|p)>\s*)?【[^【】]+】/u.test(
814
+ String(r.web_content || "")
815
+ ) ? "inline" : "external"), i = l === "inline" ? [`<div>${N(p)}${$.join("")}</div>`] : $.length ? [`<div>${$.join("")}</div>`] : [], a = l === "inline" ? [p + k.join("")] : k.length ? [k.join("")] : [];
816
+ if (t.type === "reasoning" && (i.push("<div>{推理}</div>"), a.push("{推理}")), t.type === "agent") {
817
+ if ((y = (b = t.extensionState.tagged) == null ? void 0 : b.data) != null && y.enabled)
818
+ return o(
819
+ t,
820
+ "extensionState.tagged",
821
+ "旧系统的 Agent 与顾客标签不能组合"
822
+ );
823
+ if (t.knowledge.retainedDoc)
824
+ return o(
825
+ t,
826
+ "knowledge.retainedDoc",
827
+ "旧格式不能保留 Agent 切换前的正文"
828
+ );
829
+ if (!t.knowledge.agentRef)
830
+ return o(t, "knowledge.agentRef", "旧格式需要 Agent 引用");
831
+ const h = `{自定义Agent}@${t.knowledge.agentRef.name}`;
832
+ i.push(
833
+ `<div><span data-tag-type="custom_agent" data-agent="true" data-agent-id="${N(
834
+ t.knowledge.agentRef.id
835
+ )}">${N(h)}</span></div>`
836
+ ), a.push(h);
837
+ } else
838
+ for (const [h, e] of (((j = t.knowledge.doc) == null ? void 0 : j.content) || []).entries()) {
839
+ const n = `knowledge.doc.content[${h}]`;
840
+ if (e.type === "messageSeparator") {
841
+ i.push(
842
+ '<div><span data-tag-type="separator" data-divider="true">{分隔符}</span></div>'
843
+ ), a.push("[sep]");
844
+ continue;
845
+ }
846
+ if (e.type === "mediaBlock" && ((E = e.attrs) == null ? void 0 : E.status) === "ready") {
847
+ const A = e.attrs.kind === "image" ? "img" : "video", q = N(String(e.attrs.src));
848
+ i.push(
849
+ `<div><${A} src="${q}"${A === "video" ? "></video>" : ">"}</div>`
850
+ ), a.push(
851
+ `<${A} src="${q}"${A === "video" ? ' width="240" controls/>' : ' width="120"/>'}`
852
+ );
853
+ continue;
854
+ }
855
+ const u = e.type === "originalReply", I = u ? (P = e.content) == null ? void 0 : P[0] : e;
856
+ if (!I || I.type !== "paragraph" || u && ((ot = e.content) == null ? void 0 : ot.length) !== 1)
857
+ return o(t, n, `节点 ${e.type} 无法映射到旧格式`);
858
+ const f = [];
859
+ for (const [A, q] of (I.content || []).entries()) {
860
+ const O = Rt(q, `${n}.content[${A}]`);
861
+ if (!O.ok) return { ...O, raw: t };
862
+ f.push(O.value);
863
+ }
864
+ const D = f.map((A) => A.html).join(""), w = f.map((A) => A.text).join("");
865
+ u ? (i.push(
866
+ `<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">${D}</span><span>&gt;</span></span></div>`
867
+ ), a.push(`<{原话复述}${w}>`)) : (i.push(`<div>${D}</div>`), a.push(w));
868
+ }
869
+ const g = (it = t.extensionState.todo) == null ? void 0 : it.data, d = [], G = (h) => {
870
+ var e, n;
871
+ h.type === "businessToken" && ((e = h.attrs) == null ? void 0 : e.kind) === "todo" && d.push({
872
+ id: String(h.attrs.key),
873
+ label: String(h.attrs.label)
874
+ }), (n = h.content) == null || n.forEach(G);
875
+ };
876
+ (V = (Q = t.knowledge.doc) == null ? void 0 : Q.content) == null || V.forEach(G);
877
+ const M = g != null && g.enabled && g.tag ? [g.tag, ...d] : d, C = [
878
+ ...new Map(
879
+ M.map((h) => [JSON.stringify([h.id, h.label]), h])
880
+ ).values()
881
+ ];
882
+ if (new Set(C.map((h) => h.label)).size !== C.length)
883
+ return o(
884
+ t,
885
+ "knowledge.doc",
886
+ "同名待办对应多个方案 ID,旧格式无法无损保存"
887
+ );
888
+ const B = C.length === 1 ? C[0] : void 0, R = (X = t.extensionState.tagged) == null ? void 0 : X.data, T = [];
889
+ if (R != null && R.enabled) {
890
+ T.push({
891
+ type: "cdp_tag",
892
+ name: (Z = R.tag) == null ? void 0 : Z.label,
893
+ value: (K = R.tag) == null ? void 0 : K.id
894
+ }), C.forEach((e) => T.push({ type: "todo", name: e.label })), t.type === "reasoning" && T.push({ type: "reasoning", name: "推理" }), (et = (tt = t.extensionState.originalReply) == null ? void 0 : tt.data) != null && et.enabled && T.push({ type: "original_repeat", name: "原话复述" });
895
+ const h = (e) => {
896
+ var n, u;
897
+ e.type === "businessToken" && ((n = e.attrs) == null ? void 0 : n.kind) === "variable" && T.push({
898
+ type: "variable",
899
+ variable_name: e.attrs.label || e.attrs.key
900
+ }), e.type === "originalReply" && T.push({ type: "original_repeat", name: "原话复述" }), (u = e.content) == null || u.forEach(h);
901
+ };
902
+ (at = (nt = t.knowledge.doc) == null ? void 0 : nt.content) == null || at.forEach(h);
903
+ }
904
+ return {
905
+ ok: !0,
906
+ value: {
907
+ ...r,
908
+ knowledge_type: t.type === "reasoning" ? 2 : t.type === "agent" ? 3 : 1,
909
+ todo_plan_id: (B == null ? void 0 : B.id) || "",
910
+ todo_tag_type: C.length ? 2 : 0,
911
+ todo_tag_metas: M.length ? JSON.stringify(
912
+ M.map((h) => ({
913
+ plan_id: h.id,
914
+ plan_name: h.label,
915
+ tag_type: 2
916
+ }))
917
+ ) : "",
918
+ todo_plan_name: (B == null ? void 0 : B.label) || "",
919
+ tag_meta: T,
920
+ web_content: i.join(""),
921
+ content: a.join(`
922
+ `)
923
+ }
924
+ };
925
+ }
926
+ export {
927
+ kt as LEGACY_BUSINESS_ATTRIBUTES,
928
+ Et as legacyItemToScene,
929
+ Lt as sceneToLegacyItem
930
+ };