@csntgao/uni-base 0.6.3 → 0.6.6
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/AGENTS.md +10 -8
- package/CLAUDE.md +10 -8
- package/README.md +27 -21
- package/docs//346/225/260/345/255/227/345/221/230/345/267/245/345/256/214/346/225/264/346/212/275/345/261/211/346/216/245/345/205/245/350/257/264/346/230/216.md +46 -0
- package/docs//347/273/204/347/273/207/345/221/230/345/267/245/345/215/225/351/200/211/347/273/204/344/273/266/346/216/245/345/205/245/350/257/264/346/230/216.md +1 -1
- package/docs//347/273/204/347/273/207/345/221/230/345/267/245/345/244/232/351/200/211/347/273/204/344/273/266/346/216/245/345/205/245/350/257/264/346/230/216.md +1 -1
- package/examples/vanilla/main.js +1 -1
- package/examples/vanilla/package.json +3 -3
- package/package.json +12 -13
- package/packages/core/package.json +2 -2
- package/packages/core/src/assistant-actions.ts +120 -0
- package/packages/core/src/customer-support-types.ts +15 -0
- package/packages/core/src/index.ts +8 -0
- package/packages/core/src/types.ts +6 -0
- package/packages/core/tests/assistant-actions.test.ts +76 -0
- package/packages/web-components/package.json +3 -3
- package/packages/web-components/scripts/verify-runtime-build.mjs +1 -0
- package/packages/web-components/src/chat.ts +267 -15
- package/packages/web-components/src/customer-support-chat.ts +1 -1
- package/packages/web-components/src/customer-support-transport.ts +118 -16
- package/packages/web-components/src/index.ts +14 -2
- package/packages/web-components/src/notification-center.ts +1 -1
- package/packages/web-components/src/notification-popover.ts +1 -1
- package/packages/web-components/src/uniplat-base-notification-center-transport.ts +1 -1
- package/packages/web-components/tests/chat.test.ts +418 -10
- package/packages/web-components/tests/customer-support-chat.test.ts +1 -1
- package/packages/web-components/tests/customer-support-transport.test.ts +89 -1
- package/packages/web-components/tests/notification-center.test.ts +1 -1
- package/packages/web-components/tests/notification-popover.test.ts +1 -1
- package/packages/web-components/tsup.config.ts +1 -1
- package/packages/web-components/tsup.runtime.config.ts +1 -1
- package/restart +0 -0
- package/tsconfig.base.json +2 -2
- package/vitest.config.ts +2 -2
- package//344/272/244/346/216/245/346/226/207/346/241/243.md +21 -26
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
CustomerSupportAgent,
|
|
3
3
|
CustomerSupportCreateSessionResult,
|
|
4
|
+
CustomerSupportHandoffResult,
|
|
4
5
|
CustomerSupportMessage,
|
|
5
6
|
CustomerSupportMessagePage,
|
|
6
7
|
CustomerSupportSenderType,
|
|
7
8
|
CustomerSupportSession,
|
|
8
9
|
CustomerSupportSessionStatus,
|
|
9
10
|
CustomerSupportTransport,
|
|
10
|
-
} from '@
|
|
11
|
+
} from '@csntgao/ai-employee-client'
|
|
12
|
+
import { isUuidV4 } from '@csntgao/ai-employee-client'
|
|
11
13
|
|
|
12
14
|
export interface HrSaasCustomerSupportTransportOptions {
|
|
13
15
|
serviceBaseUrl: string
|
|
@@ -15,8 +17,30 @@ export interface HrSaasCustomerSupportTransportOptions {
|
|
|
15
17
|
fetch?: typeof fetch
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
export type HrSaasCustomerSupportTransportErrorCode =
|
|
21
|
+
| 'AUTH_REQUIRED'
|
|
22
|
+
| 'SOURCE_SESSION_NOT_FOUND'
|
|
23
|
+
| 'SOURCE_SESSION_ACCESS_DENIED'
|
|
24
|
+
| 'HANDOFF_ACTION_NOT_FOUND'
|
|
25
|
+
| 'HANDOFF_ACTION_MISMATCH'
|
|
26
|
+
| 'UNAUTHORIZED'
|
|
27
|
+
| 'CUSTOMER_SUPPORT_UNAVAILABLE'
|
|
28
|
+
| 'REQUEST_FAILED'
|
|
29
|
+
| 'INVALID_RESPONSE'
|
|
30
|
+
|
|
31
|
+
export class HrSaasCustomerSupportTransportError extends Error {
|
|
32
|
+
readonly code: HrSaasCustomerSupportTransportErrorCode
|
|
33
|
+
|
|
34
|
+
constructor(code: HrSaasCustomerSupportTransportErrorCode) {
|
|
35
|
+
super('Customer support request failed')
|
|
36
|
+
this.name = 'HrSaasCustomerSupportTransportError'
|
|
37
|
+
this.code = code
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
18
41
|
const SESSION_PAGE_ACTION = 'user_session_page'
|
|
19
42
|
const SESSION_CREATE_ACTION = 'user_session_create'
|
|
43
|
+
const SESSION_HANDOFF_CREATE_ACTION = 'user_session_handoff_create'
|
|
20
44
|
const SESSION_DETAIL_ACTION = 'user_session_detail'
|
|
21
45
|
const MESSAGE_PAGE_ACTION = 'user_message_page'
|
|
22
46
|
const MESSAGE_SEND_ACTION = 'user_message_send'
|
|
@@ -63,6 +87,37 @@ export function createHrSaasCustomerSupportTransport(
|
|
|
63
87
|
if (parsedInitialMessage) result.initialMessage = parsedInitialMessage
|
|
64
88
|
return result
|
|
65
89
|
},
|
|
90
|
+
async createHandoffSession(handoffRequest) {
|
|
91
|
+
const sourceSessionId = requiredText(handoffRequest.sourceSessionId, 128)
|
|
92
|
+
const actionTransactionId = requiredText(handoffRequest.actionTransactionId, 36)
|
|
93
|
+
if (!isUuidV4(actionTransactionId)) {
|
|
94
|
+
throw new HrSaasCustomerSupportTransportError('INVALID_RESPONSE')
|
|
95
|
+
}
|
|
96
|
+
const data = record(
|
|
97
|
+
await request(SESSION_HANDOFF_CREATE_ACTION, {
|
|
98
|
+
source_session_id: sourceSessionId,
|
|
99
|
+
action_transaction_id: actionTransactionId,
|
|
100
|
+
}),
|
|
101
|
+
)
|
|
102
|
+
const session = parseSession(data.session)
|
|
103
|
+
const initialMessage = parseMessage(data.initial_message)
|
|
104
|
+
if (
|
|
105
|
+
!session ||
|
|
106
|
+
!initialMessage ||
|
|
107
|
+
initialMessage.sessionId !== session.id ||
|
|
108
|
+
typeof data.created !== 'boolean' ||
|
|
109
|
+
typeof data.repaired !== 'boolean'
|
|
110
|
+
) {
|
|
111
|
+
throw new HrSaasCustomerSupportTransportError('INVALID_RESPONSE')
|
|
112
|
+
}
|
|
113
|
+
const result: CustomerSupportHandoffResult = {
|
|
114
|
+
session,
|
|
115
|
+
initialMessage,
|
|
116
|
+
created: data.created,
|
|
117
|
+
repaired: data.repaired,
|
|
118
|
+
}
|
|
119
|
+
return result
|
|
120
|
+
},
|
|
66
121
|
async getSession(sessionId) {
|
|
67
122
|
const data = await request(SESSION_DETAIL_ACTION, {
|
|
68
123
|
session_id: requiredText(sessionId, 128),
|
|
@@ -169,27 +224,74 @@ async function requestData(
|
|
|
169
224
|
accessToken: string,
|
|
170
225
|
body: Record<string, unknown>,
|
|
171
226
|
): Promise<unknown> {
|
|
172
|
-
if (!fetchImplementation) throw new
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
227
|
+
if (!fetchImplementation) throw new HrSaasCustomerSupportTransportError('REQUEST_FAILED')
|
|
228
|
+
let response: Response
|
|
229
|
+
try {
|
|
230
|
+
response = await fetchImplementation(endpoint, {
|
|
231
|
+
method: 'POST',
|
|
232
|
+
credentials: 'include',
|
|
233
|
+
headers: {
|
|
234
|
+
accept: 'application/json',
|
|
235
|
+
authorization: `Bearer ${accessToken}`,
|
|
236
|
+
'content-type': 'application/json',
|
|
237
|
+
},
|
|
238
|
+
body: JSON.stringify(body),
|
|
239
|
+
})
|
|
240
|
+
} catch {
|
|
241
|
+
throw new HrSaasCustomerSupportTransportError('REQUEST_FAILED')
|
|
242
|
+
}
|
|
243
|
+
let payload: unknown = null
|
|
244
|
+
try {
|
|
245
|
+
payload = await response.json()
|
|
246
|
+
} catch {
|
|
247
|
+
if (!response.ok) throw transportResponseError({}, response.status)
|
|
248
|
+
throw new HrSaasCustomerSupportTransportError('INVALID_RESPONSE')
|
|
249
|
+
}
|
|
185
250
|
const envelope = record(payload)
|
|
251
|
+
if (!response.ok) throw transportResponseError(envelope, response.status)
|
|
186
252
|
if ('rescode' in envelope) {
|
|
187
|
-
if (Number(envelope.rescode) !== 0)
|
|
253
|
+
if (Number(envelope.rescode) !== 0) {
|
|
254
|
+
throw transportResponseError(envelope, response.status)
|
|
255
|
+
}
|
|
188
256
|
return envelope.data
|
|
189
257
|
}
|
|
190
258
|
return payload
|
|
191
259
|
}
|
|
192
260
|
|
|
261
|
+
function transportResponseError(
|
|
262
|
+
envelope: Record<string, unknown>,
|
|
263
|
+
status: number,
|
|
264
|
+
): HrSaasCustomerSupportTransportError {
|
|
265
|
+
const detail = record(envelope.data)
|
|
266
|
+
const error = record(envelope.error)
|
|
267
|
+
const candidate = [
|
|
268
|
+
envelope.error_code,
|
|
269
|
+
envelope.code,
|
|
270
|
+
detail.error_code,
|
|
271
|
+
detail.code,
|
|
272
|
+
error.error_code,
|
|
273
|
+
error.code,
|
|
274
|
+
].find((value) => typeof value === 'string' && value.trim())
|
|
275
|
+
const code = typeof candidate === 'string' ? candidate.trim().toUpperCase() : ''
|
|
276
|
+
if (isTransportErrorCode(code)) return new HrSaasCustomerSupportTransportError(code)
|
|
277
|
+
if (status === 401) return new HrSaasCustomerSupportTransportError('UNAUTHORIZED')
|
|
278
|
+
if (status === 503) {
|
|
279
|
+
return new HrSaasCustomerSupportTransportError('CUSTOMER_SUPPORT_UNAVAILABLE')
|
|
280
|
+
}
|
|
281
|
+
return new HrSaasCustomerSupportTransportError('REQUEST_FAILED')
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function isTransportErrorCode(value: string): value is HrSaasCustomerSupportTransportErrorCode {
|
|
285
|
+
return [
|
|
286
|
+
'SOURCE_SESSION_NOT_FOUND',
|
|
287
|
+
'SOURCE_SESSION_ACCESS_DENIED',
|
|
288
|
+
'HANDOFF_ACTION_NOT_FOUND',
|
|
289
|
+
'HANDOFF_ACTION_MISMATCH',
|
|
290
|
+
'UNAUTHORIZED',
|
|
291
|
+
'CUSTOMER_SUPPORT_UNAVAILABLE',
|
|
292
|
+
].includes(value)
|
|
293
|
+
}
|
|
294
|
+
|
|
193
295
|
function validateServiceBaseUrl(value: string): string {
|
|
194
296
|
const raw = typeof value === 'string' ? value.trim() : ''
|
|
195
297
|
if (!raw) throw new TypeError('Customer support serviceBaseUrl is required')
|
|
@@ -216,7 +318,7 @@ async function resolveAccessToken(provider: () => string | Promise<string>): Pro
|
|
|
216
318
|
} catch {
|
|
217
319
|
// Provider details may contain credentials and are intentionally discarded.
|
|
218
320
|
}
|
|
219
|
-
if (!value) throw new
|
|
321
|
+
if (!value) throw new HrSaasCustomerSupportTransportError('AUTH_REQUIRED')
|
|
220
322
|
return value
|
|
221
323
|
}
|
|
222
324
|
|
|
@@ -77,8 +77,20 @@ export type {
|
|
|
77
77
|
CustomerSupportChatConfig,
|
|
78
78
|
CustomerSupportChatEventMap,
|
|
79
79
|
} from './customer-support-chat'
|
|
80
|
-
export {
|
|
81
|
-
|
|
80
|
+
export {
|
|
81
|
+
createHrSaasCustomerSupportTransport,
|
|
82
|
+
HrSaasCustomerSupportTransportError,
|
|
83
|
+
} from './customer-support-transport'
|
|
84
|
+
export type {
|
|
85
|
+
HrSaasCustomerSupportTransportErrorCode,
|
|
86
|
+
HrSaasCustomerSupportTransportOptions,
|
|
87
|
+
} from './customer-support-transport'
|
|
88
|
+
export { isUuidV4, parseAiEmployeeAssistantContent } from '@csntgao/ai-employee-client'
|
|
89
|
+
export type {
|
|
90
|
+
AiEmployeeAssistantAction,
|
|
91
|
+
OpenCustomerSupportAssistantAction,
|
|
92
|
+
ParsedAiEmployeeAssistantContent,
|
|
93
|
+
} from '@csntgao/ai-employee-client'
|
|
82
94
|
export type {
|
|
83
95
|
NotificationCenterConfig,
|
|
84
96
|
NotificationCenterEventMap,
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
type NotificationCenterErrorDetail,
|
|
5
5
|
type NotificationDto,
|
|
6
6
|
type NotificationTypeSummary,
|
|
7
|
-
} from '@
|
|
7
|
+
} from '@csntgao/ai-employee-client'
|
|
8
8
|
import { LitElement, css, html, nothing, type TemplateResult } from 'lit'
|
|
9
9
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js'
|
|
10
10
|
import { renderSafeMarkdown } from './safe-markdown'
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
type NotificationCenterErrorDetail,
|
|
4
4
|
type NotificationCenterTransport,
|
|
5
5
|
type NotificationDto,
|
|
6
|
-
} from '@
|
|
6
|
+
} from '@csntgao/ai-employee-client'
|
|
7
7
|
import { LitElement, css, html, nothing, type TemplateResult } from 'lit'
|
|
8
8
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js'
|
|
9
9
|
import { prototypeIcon, type PrototypeIconName } from './prototype-icons'
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
NotificationResource,
|
|
11
11
|
NotificationSource,
|
|
12
12
|
NotificationTypeSummary,
|
|
13
|
-
} from '@
|
|
13
|
+
} from '@csntgao/ai-employee-client'
|
|
14
14
|
|
|
15
15
|
export interface UniplatBaseNotificationCenterTransportOptions {
|
|
16
16
|
serviceBaseUrl: string
|