@xbrain-swe/nova-chat-widget 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -24,6 +24,8 @@ type TextPart = {
24
24
  };
25
25
  type MessagePart = TextPart | ToolPart;
26
26
  type ChatMessage = {
27
+ /** assistant 메시지가 서버에 저장될 때의 id(`start` 청크의 `messageId`). 만족도 피드백 대상 식별용. */
28
+ id?: string;
27
29
  role: "user" | "assistant";
28
30
  parts: MessagePart[];
29
31
  };
@@ -109,6 +111,57 @@ declare function XbNovaProvider({ apiKey, botId, appId, screen, apiBaseUrl, clie
109
111
  children: React.ReactNode;
110
112
  }): react.JSX.Element;
111
113
 
114
+ type ClientResults = Record<string, {
115
+ view: ViewKind;
116
+ output: unknown;
117
+ }>;
118
+ type XbNovaFeedbackRating = "up" | "down" | null;
119
+ /** 👎 사유 칩의 코드. */
120
+ type XbNovaFeedbackReason = "inaccurate" | "irrelevant" | "too_long" | "unclear";
121
+ /** 답변 만족도 저장 성공 후 호스트로 전달되는 이벤트. `rating: null`은 평가 취소. */
122
+ type XbNovaFeedbackEvent = {
123
+ conversationId: string;
124
+ messageId: string;
125
+ rating: XbNovaFeedbackRating;
126
+ /** 👎일 때 사용자가 고른 사유 코드(없으면 undefined). */
127
+ reason?: XbNovaFeedbackReason;
128
+ };
129
+ type XbNovaOnboarding = {
130
+ conversation_id: string;
131
+ greeting: string;
132
+ quick_replies: string[];
133
+ branding: {
134
+ title?: string;
135
+ logo_url?: string;
136
+ avatar_text?: string;
137
+ };
138
+ };
139
+ type UseXbNovaChatResult = {
140
+ onboarding: XbNovaOnboarding | null;
141
+ messages: ChatMessage[];
142
+ busy: boolean;
143
+ error: string | null;
144
+ send: (text: string) => Promise<void>;
145
+ /** client action 핸들러가 돌려준 정규화 결과(tool_call_id별). 채팅 화면이 view 렌더러로 그린다. */
146
+ clientResults: ClientResults;
147
+ /** messageId → 현재 평가. 평가 안 한 메시지는 키가 없다. */
148
+ feedback: Record<string, XbNovaFeedbackRating>;
149
+ /** 낙관적으로 반영하고 서버에 저장한다. 실패하면 되돌린다. */
150
+ setFeedback: (messageId: string, rating: XbNovaFeedbackRating, reason?: XbNovaFeedbackReason) => Promise<void>;
151
+ };
152
+ /** `botId`를 넘기면 Provider의 기본 봇 대신 그 봇으로 새 대화를 연다 — 넛지 handoff가 쓴다.
153
+ * `nudgeNodeId`를 넘기면 이 대화가 그 넛지에서 시작됐다고 서버에 표시한다 — 넛지 전환
154
+ * 퍼널(노출→클릭→첫질문→전환)의 마지막 단계가 이 값이 채워진 대화 수를 센다.
155
+ * `onDismissSheet`는 `dismissSheet: true`인 client action이 실행될 때 호출된다 —
156
+ * `<XbNovaChat>`이 시트를 닫는 함수를 넘겨준다(모바일에서 시트가 페이지 대부분을 덮어서,
157
+ * 안 닫으면 그 밑에서 일어나는 일이 안 보인다). */
158
+ declare function useXbNovaChat(options?: {
159
+ botId?: string;
160
+ nudgeNodeId?: string;
161
+ onDismissSheet?: () => void;
162
+ onFeedback?: (e: XbNovaFeedbackEvent) => void;
163
+ }): UseXbNovaChatResult;
164
+
112
165
  type ProductItem = {
113
166
  id: string;
114
167
  title: string;
@@ -148,7 +201,7 @@ type ViewRenderer = (props: {
148
201
  }) => React.ReactNode;
149
202
  type ViewRendererMap = Partial<Record<ViewKind, ViewRenderer>>;
150
203
 
151
- declare function XbNovaChat({ viewRenderers, botId, barStyle, panelStyle, backdropStyle, defaultOpen, idleText, avatarSize, onVerdictAction, }: {
204
+ declare function XbNovaChat({ viewRenderers, botId, barStyle, panelStyle, backdropStyle, defaultOpen, idleText, avatarSize, onVerdictAction, feedback: feedbackEnabled, onFeedback, }: {
152
205
  /** 특정 view만 자체 컴포넌트로 덮어쓰고 싶을 때 — 지정 안 한 view는 기본 렌더러를 쓴다. */
153
206
  viewRenderers?: ViewRendererMap;
154
207
  /** Provider의 기본 봇 대신 다른 봇과 고정적으로 대화하고 싶을 때. 힌트를 눌러 열면
@@ -173,43 +226,12 @@ declare function XbNovaChat({ viewRenderers, botId, barStyle, panelStyle, backdr
173
226
  /** 판단 카드의 행동 버튼을 눌렀을 때 — 실제 동작(상담신청 폼 열기, 섹션 스크롤 등)은
174
227
  * 소비자가 정한다. SDK는 버튼에 적힌 `action` 문자열을 그대로 넘겨줄 뿐 뜻을 모른다. */
175
228
  onVerdictAction?: (action: string) => void;
229
+ /** 완료된 답변 아래 👍/👎 "상담 만족도" 버튼을 보일지. 기본 true. */
230
+ feedback?: boolean;
231
+ /** 만족도가 서버에 저장된 뒤 호출된다(분석 이벤트 전송용). `rating: null`은 평가 취소. */
232
+ onFeedback?: (e: XbNovaFeedbackEvent) => void;
176
233
  }): react.JSX.Element | null;
177
234
 
178
- type ClientResults = Record<string, {
179
- view: ViewKind;
180
- output: unknown;
181
- }>;
182
- type XbNovaOnboarding = {
183
- conversation_id: string;
184
- greeting: string;
185
- quick_replies: string[];
186
- branding: {
187
- title?: string;
188
- logo_url?: string;
189
- avatar_text?: string;
190
- };
191
- };
192
- type UseXbNovaChatResult = {
193
- onboarding: XbNovaOnboarding | null;
194
- messages: ChatMessage[];
195
- busy: boolean;
196
- error: string | null;
197
- send: (text: string) => Promise<void>;
198
- /** client action 핸들러가 돌려준 정규화 결과(tool_call_id별). 채팅 화면이 view 렌더러로 그린다. */
199
- clientResults: ClientResults;
200
- };
201
- /** `botId`를 넘기면 Provider의 기본 봇 대신 그 봇으로 새 대화를 연다 — 넛지 handoff가 쓴다.
202
- * `nudgeNodeId`를 넘기면 이 대화가 그 넛지에서 시작됐다고 서버에 표시한다 — 넛지 전환
203
- * 퍼널(노출→클릭→첫질문→전환)의 마지막 단계가 이 값이 채워진 대화 수를 센다.
204
- * `onDismissSheet`는 `dismissSheet: true`인 client action이 실행될 때 호출된다 —
205
- * `<XbNovaChat>`이 시트를 닫는 함수를 넘겨준다(모바일에서 시트가 페이지 대부분을 덮어서,
206
- * 안 닫으면 그 밑에서 일어나는 일이 안 보인다). */
207
- declare function useXbNovaChat(options?: {
208
- botId?: string;
209
- nudgeNodeId?: string;
210
- onDismissSheet?: () => void;
211
- }): UseXbNovaChatResult;
212
-
213
235
  /** ref형 — 감싸는 엘리먼트를 늘리기 싫을 때. `<div ref={useXbNovaTrack("price", data)}>`. */
214
236
  declare function useXbNovaTrack<T extends HTMLElement = HTMLElement>(region: string, data?: FactValue, label?: string): (node: T | null) => void;
215
237
  /** 선언형 — 감싸기만 하면 됨. `<XbNovaTrack region="price" data={{...}}>...</XbNovaTrack>`. */
@@ -252,4 +274,4 @@ declare function useXbNovaSettings(): {
252
274
  showBar: () => void;
253
275
  };
254
276
 
255
- export { type ChatMessage, type FactValue, type MessagePart, type ProductItem, type TextPart, type ToolPart, type UseXbNovaChatResult, type VerdictAction, type VerdictOutput, type ViewKind, type ViewRenderer, type ViewRendererMap, XbNovaChat, type XbNovaClientAction, type XbNovaClientActionResult, type XbNovaClientActions, XbNovaFact, XbNovaFacts, type XbNovaOnboarding, XbNovaProvider, type XbNovaTheme, XbNovaTrack, trackXbNovaEvent, useXbNovaChat, useXbNovaFact, useXbNovaFacts, useXbNovaSettings, useXbNovaTrack, useXbNovaVisitor };
277
+ export { type ChatMessage, type FactValue, type MessagePart, type ProductItem, type TextPart, type ToolPart, type UseXbNovaChatResult, type VerdictAction, type VerdictOutput, type ViewKind, type ViewRenderer, type ViewRendererMap, XbNovaChat, type XbNovaClientAction, type XbNovaClientActionResult, type XbNovaClientActions, XbNovaFact, XbNovaFacts, type XbNovaFeedbackEvent, type XbNovaFeedbackRating, type XbNovaFeedbackReason, type XbNovaOnboarding, XbNovaProvider, type XbNovaTheme, XbNovaTrack, trackXbNovaEvent, useXbNovaChat, useXbNovaFact, useXbNovaFacts, useXbNovaSettings, useXbNovaTrack, useXbNovaVisitor };
package/dist/index.d.ts CHANGED
@@ -24,6 +24,8 @@ type TextPart = {
24
24
  };
25
25
  type MessagePart = TextPart | ToolPart;
26
26
  type ChatMessage = {
27
+ /** assistant 메시지가 서버에 저장될 때의 id(`start` 청크의 `messageId`). 만족도 피드백 대상 식별용. */
28
+ id?: string;
27
29
  role: "user" | "assistant";
28
30
  parts: MessagePart[];
29
31
  };
@@ -109,6 +111,57 @@ declare function XbNovaProvider({ apiKey, botId, appId, screen, apiBaseUrl, clie
109
111
  children: React.ReactNode;
110
112
  }): react.JSX.Element;
111
113
 
114
+ type ClientResults = Record<string, {
115
+ view: ViewKind;
116
+ output: unknown;
117
+ }>;
118
+ type XbNovaFeedbackRating = "up" | "down" | null;
119
+ /** 👎 사유 칩의 코드. */
120
+ type XbNovaFeedbackReason = "inaccurate" | "irrelevant" | "too_long" | "unclear";
121
+ /** 답변 만족도 저장 성공 후 호스트로 전달되는 이벤트. `rating: null`은 평가 취소. */
122
+ type XbNovaFeedbackEvent = {
123
+ conversationId: string;
124
+ messageId: string;
125
+ rating: XbNovaFeedbackRating;
126
+ /** 👎일 때 사용자가 고른 사유 코드(없으면 undefined). */
127
+ reason?: XbNovaFeedbackReason;
128
+ };
129
+ type XbNovaOnboarding = {
130
+ conversation_id: string;
131
+ greeting: string;
132
+ quick_replies: string[];
133
+ branding: {
134
+ title?: string;
135
+ logo_url?: string;
136
+ avatar_text?: string;
137
+ };
138
+ };
139
+ type UseXbNovaChatResult = {
140
+ onboarding: XbNovaOnboarding | null;
141
+ messages: ChatMessage[];
142
+ busy: boolean;
143
+ error: string | null;
144
+ send: (text: string) => Promise<void>;
145
+ /** client action 핸들러가 돌려준 정규화 결과(tool_call_id별). 채팅 화면이 view 렌더러로 그린다. */
146
+ clientResults: ClientResults;
147
+ /** messageId → 현재 평가. 평가 안 한 메시지는 키가 없다. */
148
+ feedback: Record<string, XbNovaFeedbackRating>;
149
+ /** 낙관적으로 반영하고 서버에 저장한다. 실패하면 되돌린다. */
150
+ setFeedback: (messageId: string, rating: XbNovaFeedbackRating, reason?: XbNovaFeedbackReason) => Promise<void>;
151
+ };
152
+ /** `botId`를 넘기면 Provider의 기본 봇 대신 그 봇으로 새 대화를 연다 — 넛지 handoff가 쓴다.
153
+ * `nudgeNodeId`를 넘기면 이 대화가 그 넛지에서 시작됐다고 서버에 표시한다 — 넛지 전환
154
+ * 퍼널(노출→클릭→첫질문→전환)의 마지막 단계가 이 값이 채워진 대화 수를 센다.
155
+ * `onDismissSheet`는 `dismissSheet: true`인 client action이 실행될 때 호출된다 —
156
+ * `<XbNovaChat>`이 시트를 닫는 함수를 넘겨준다(모바일에서 시트가 페이지 대부분을 덮어서,
157
+ * 안 닫으면 그 밑에서 일어나는 일이 안 보인다). */
158
+ declare function useXbNovaChat(options?: {
159
+ botId?: string;
160
+ nudgeNodeId?: string;
161
+ onDismissSheet?: () => void;
162
+ onFeedback?: (e: XbNovaFeedbackEvent) => void;
163
+ }): UseXbNovaChatResult;
164
+
112
165
  type ProductItem = {
113
166
  id: string;
114
167
  title: string;
@@ -148,7 +201,7 @@ type ViewRenderer = (props: {
148
201
  }) => React.ReactNode;
149
202
  type ViewRendererMap = Partial<Record<ViewKind, ViewRenderer>>;
150
203
 
151
- declare function XbNovaChat({ viewRenderers, botId, barStyle, panelStyle, backdropStyle, defaultOpen, idleText, avatarSize, onVerdictAction, }: {
204
+ declare function XbNovaChat({ viewRenderers, botId, barStyle, panelStyle, backdropStyle, defaultOpen, idleText, avatarSize, onVerdictAction, feedback: feedbackEnabled, onFeedback, }: {
152
205
  /** 특정 view만 자체 컴포넌트로 덮어쓰고 싶을 때 — 지정 안 한 view는 기본 렌더러를 쓴다. */
153
206
  viewRenderers?: ViewRendererMap;
154
207
  /** Provider의 기본 봇 대신 다른 봇과 고정적으로 대화하고 싶을 때. 힌트를 눌러 열면
@@ -173,43 +226,12 @@ declare function XbNovaChat({ viewRenderers, botId, barStyle, panelStyle, backdr
173
226
  /** 판단 카드의 행동 버튼을 눌렀을 때 — 실제 동작(상담신청 폼 열기, 섹션 스크롤 등)은
174
227
  * 소비자가 정한다. SDK는 버튼에 적힌 `action` 문자열을 그대로 넘겨줄 뿐 뜻을 모른다. */
175
228
  onVerdictAction?: (action: string) => void;
229
+ /** 완료된 답변 아래 👍/👎 "상담 만족도" 버튼을 보일지. 기본 true. */
230
+ feedback?: boolean;
231
+ /** 만족도가 서버에 저장된 뒤 호출된다(분석 이벤트 전송용). `rating: null`은 평가 취소. */
232
+ onFeedback?: (e: XbNovaFeedbackEvent) => void;
176
233
  }): react.JSX.Element | null;
177
234
 
178
- type ClientResults = Record<string, {
179
- view: ViewKind;
180
- output: unknown;
181
- }>;
182
- type XbNovaOnboarding = {
183
- conversation_id: string;
184
- greeting: string;
185
- quick_replies: string[];
186
- branding: {
187
- title?: string;
188
- logo_url?: string;
189
- avatar_text?: string;
190
- };
191
- };
192
- type UseXbNovaChatResult = {
193
- onboarding: XbNovaOnboarding | null;
194
- messages: ChatMessage[];
195
- busy: boolean;
196
- error: string | null;
197
- send: (text: string) => Promise<void>;
198
- /** client action 핸들러가 돌려준 정규화 결과(tool_call_id별). 채팅 화면이 view 렌더러로 그린다. */
199
- clientResults: ClientResults;
200
- };
201
- /** `botId`를 넘기면 Provider의 기본 봇 대신 그 봇으로 새 대화를 연다 — 넛지 handoff가 쓴다.
202
- * `nudgeNodeId`를 넘기면 이 대화가 그 넛지에서 시작됐다고 서버에 표시한다 — 넛지 전환
203
- * 퍼널(노출→클릭→첫질문→전환)의 마지막 단계가 이 값이 채워진 대화 수를 센다.
204
- * `onDismissSheet`는 `dismissSheet: true`인 client action이 실행될 때 호출된다 —
205
- * `<XbNovaChat>`이 시트를 닫는 함수를 넘겨준다(모바일에서 시트가 페이지 대부분을 덮어서,
206
- * 안 닫으면 그 밑에서 일어나는 일이 안 보인다). */
207
- declare function useXbNovaChat(options?: {
208
- botId?: string;
209
- nudgeNodeId?: string;
210
- onDismissSheet?: () => void;
211
- }): UseXbNovaChatResult;
212
-
213
235
  /** ref형 — 감싸는 엘리먼트를 늘리기 싫을 때. `<div ref={useXbNovaTrack("price", data)}>`. */
214
236
  declare function useXbNovaTrack<T extends HTMLElement = HTMLElement>(region: string, data?: FactValue, label?: string): (node: T | null) => void;
215
237
  /** 선언형 — 감싸기만 하면 됨. `<XbNovaTrack region="price" data={{...}}>...</XbNovaTrack>`. */
@@ -252,4 +274,4 @@ declare function useXbNovaSettings(): {
252
274
  showBar: () => void;
253
275
  };
254
276
 
255
- export { type ChatMessage, type FactValue, type MessagePart, type ProductItem, type TextPart, type ToolPart, type UseXbNovaChatResult, type VerdictAction, type VerdictOutput, type ViewKind, type ViewRenderer, type ViewRendererMap, XbNovaChat, type XbNovaClientAction, type XbNovaClientActionResult, type XbNovaClientActions, XbNovaFact, XbNovaFacts, type XbNovaOnboarding, XbNovaProvider, type XbNovaTheme, XbNovaTrack, trackXbNovaEvent, useXbNovaChat, useXbNovaFact, useXbNovaFacts, useXbNovaSettings, useXbNovaTrack, useXbNovaVisitor };
277
+ export { type ChatMessage, type FactValue, type MessagePart, type ProductItem, type TextPart, type ToolPart, type UseXbNovaChatResult, type VerdictAction, type VerdictOutput, type ViewKind, type ViewRenderer, type ViewRendererMap, XbNovaChat, type XbNovaClientAction, type XbNovaClientActionResult, type XbNovaClientActions, XbNovaFact, XbNovaFacts, type XbNovaFeedbackEvent, type XbNovaFeedbackRating, type XbNovaFeedbackReason, type XbNovaOnboarding, XbNovaProvider, type XbNovaTheme, XbNovaTrack, trackXbNovaEvent, useXbNovaChat, useXbNovaFact, useXbNovaFacts, useXbNovaSettings, useXbNovaTrack, useXbNovaVisitor };