@fcg-labs/cx-agent-hook 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +2 -0
- package/index.js +15 -3
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -51,6 +51,8 @@ export interface CxHook {
|
|
|
51
51
|
setDraft: (text: string) => void;
|
|
52
52
|
setStatus?: (text: string) => void;
|
|
53
53
|
confirmOverwrite?: () => boolean;
|
|
54
|
+
/** 호칭 개인화용 고객 이름 — LLM 미반출, 인사말에만 클라 치환 */
|
|
55
|
+
customerName?: string;
|
|
54
56
|
}): { promise: Promise<AnswerResult>; abort: () => void };
|
|
55
57
|
|
|
56
58
|
/** 제안을 에디터에 넣었다 (패널이 부른다) */
|
package/index.js
CHANGED
|
@@ -123,7 +123,7 @@ export function createCxHook(config = {}) {
|
|
|
123
123
|
* @returns {{promise: Promise<object>, abort: ()=>void}}
|
|
124
124
|
*/
|
|
125
125
|
composeDraft({ inquiry, context, getDraft, setDraft, setStatus,
|
|
126
|
-
confirmOverwrite } = {}) {
|
|
126
|
+
confirmOverwrite, customerName } = {}) {
|
|
127
127
|
const status = (text) => { if (setStatus) setStatus(text || ""); };
|
|
128
128
|
const noop = { promise: Promise.resolve(NOT_CONFIGURED), abort: () => {} };
|
|
129
129
|
if (!client || !inquiry || typeof setDraft !== "function") {
|
|
@@ -140,10 +140,22 @@ export function createCxHook(config = {}) {
|
|
|
140
140
|
// 새 스트림 = 이전 채택 무효 (문의가 같아도 초안이 바뀐다)
|
|
141
141
|
adoptedAnswerId = null;
|
|
142
142
|
|
|
143
|
+
// 호칭 개인화 — 이름은 융합 키(IDENTITY)라 LLM 에 반출되지 않는다.
|
|
144
|
+
// 서버는 "안녕하세요 고객님"까지만 쓰고, 이름은 초안이 돌아온 뒤
|
|
145
|
+
// 인사말 한 곳에만 끼운다 (본문 중 다른 "고객님"은 건드리지 않음).
|
|
146
|
+
const name = String(customerName || "").trim();
|
|
147
|
+
const personalize = (text) =>
|
|
148
|
+
name
|
|
149
|
+
? String(text).replace(
|
|
150
|
+
/안녕하세요[,]?\s*고객님/,
|
|
151
|
+
(m) => m.replace("고객님", `${name} 고객님`),
|
|
152
|
+
)
|
|
153
|
+
: text;
|
|
154
|
+
|
|
143
155
|
const controller = new AbortController();
|
|
144
156
|
let accumulated = "";
|
|
145
157
|
let pending = null;
|
|
146
|
-
const flushDraft = () => { pending = null; setDraft(accumulated); };
|
|
158
|
+
const flushDraft = () => { pending = null; setDraft(personalize(accumulated)); };
|
|
147
159
|
const queueDraft = () => {
|
|
148
160
|
// trailing 스로틀 — 청크마다 리렌더하면 큰 화면이 버벅인다
|
|
149
161
|
if (pending === null) pending = setTimeout(flushDraft, 80);
|
|
@@ -170,7 +182,7 @@ export function createCxHook(config = {}) {
|
|
|
170
182
|
}).then((result) => {
|
|
171
183
|
clearPending();
|
|
172
184
|
if (result.answered) {
|
|
173
|
-
setDraft(result.answer);
|
|
185
|
+
setDraft(personalize(result.answer)); // 정본 확정 (strip+호칭 반영)
|
|
174
186
|
adoptedAnswerId = result.answerId ?? null;
|
|
175
187
|
status("");
|
|
176
188
|
} else {
|