@fcg-labs/cx-agent-hook 0.2.0 → 0.2.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.
- package/index.d.ts +2 -0
- package/index.js +22 -4
- package/package.json +2 -2
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,28 @@ export function createCxHook(config = {}) {
|
|
|
140
140
|
// 새 스트림 = 이전 채택 무효 (문의가 같아도 초안이 바뀐다)
|
|
141
141
|
adoptedAnswerId = null;
|
|
142
142
|
|
|
143
|
+
// 호칭 개인화 — 0.2.2: 이름을 context 로도 보낸다. 서버가 사설
|
|
144
|
+
// 서빙(AI_CS_LLM_PRIVATE)이면 인사말을 처음부터 이름으로 굽고,
|
|
145
|
+
// **저장은 하지 않는다**(로그에는 name_provided 마커만 — 서버 계약).
|
|
146
|
+
// 아래 클라 치환은 안전망으로 유지: 구 서버·클라우드 폴백처럼 이름
|
|
147
|
+
// 없이 "안녕하세요 고객님"으로 온 초안에만 작동하고, 서버가 이미
|
|
148
|
+
// 이름을 넣었으면 패턴이 안 맞아 no-op 이다.
|
|
149
|
+
const name = String(customerName || "").trim();
|
|
150
|
+
const contextWithName = name
|
|
151
|
+
? { ...(context || {}), customerName: name }
|
|
152
|
+
: context;
|
|
153
|
+
const personalize = (text) =>
|
|
154
|
+
name
|
|
155
|
+
? String(text).replace(
|
|
156
|
+
/안녕하세요[,]?\s*고객님/,
|
|
157
|
+
(m) => m.replace("고객님", `${name} 고객님`),
|
|
158
|
+
)
|
|
159
|
+
: text;
|
|
160
|
+
|
|
143
161
|
const controller = new AbortController();
|
|
144
162
|
let accumulated = "";
|
|
145
163
|
let pending = null;
|
|
146
|
-
const flushDraft = () => { pending = null; setDraft(accumulated); };
|
|
164
|
+
const flushDraft = () => { pending = null; setDraft(personalize(accumulated)); };
|
|
147
165
|
const queueDraft = () => {
|
|
148
166
|
// trailing 스로틀 — 청크마다 리렌더하면 큰 화면이 버벅인다
|
|
149
167
|
if (pending === null) pending = setTimeout(flushDraft, 80);
|
|
@@ -154,7 +172,7 @@ export function createCxHook(config = {}) {
|
|
|
154
172
|
|
|
155
173
|
status(messages.ui_requesting);
|
|
156
174
|
setDraft("");
|
|
157
|
-
const promise = client.getAnswerStream(inquiry,
|
|
175
|
+
const promise = client.getAnswerStream(inquiry, contextWithName, {
|
|
158
176
|
signal: controller.signal,
|
|
159
177
|
onDelta(text) { accumulated += text; queueDraft(); },
|
|
160
178
|
onRestart() {
|
|
@@ -170,7 +188,7 @@ export function createCxHook(config = {}) {
|
|
|
170
188
|
}).then((result) => {
|
|
171
189
|
clearPending();
|
|
172
190
|
if (result.answered) {
|
|
173
|
-
setDraft(result.answer);
|
|
191
|
+
setDraft(personalize(result.answer)); // 정본 확정 (strip+호칭 반영)
|
|
174
192
|
adoptedAnswerId = result.answerId ?? null;
|
|
175
193
|
status("");
|
|
176
194
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fcg-labs/cx-agent-hook",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "FCG CX Agent 후킹 SDK — 서빙 답변 수신 + CS팀 교정(점수·수정·발송) 후킹. 의존성 0, CMS에 install만으로 이식",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -100,4 +100,4 @@
|
|
|
100
100
|
"access": "public"
|
|
101
101
|
},
|
|
102
102
|
"//name": "스코프는 @fcg-labs — org 소유이고 @fcg-labs/tlm 과 같은 자리다. @fcg 는 우리 것이 아니다(발행 불가)."
|
|
103
|
-
}
|
|
103
|
+
}
|