@botonic/core 0.46.1 → 0.48.0
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/lib/cjs/core-bot.js +10 -2
- package/lib/cjs/core-bot.js.map +1 -1
- package/lib/cjs/models/ai-agents.d.ts +9 -0
- package/lib/cjs/models/legacy-types.d.ts +19 -0
- package/lib/cjs/models/legacy-types.js.map +1 -1
- package/lib/cjs/testing/index.d.ts +91 -0
- package/lib/cjs/testing/index.js +196 -0
- package/lib/cjs/testing/index.js.map +1 -0
- package/lib/esm/core-bot.js +10 -2
- package/lib/esm/core-bot.js.map +1 -1
- package/lib/esm/models/ai-agents.d.ts +9 -0
- package/lib/esm/models/legacy-types.d.ts +19 -0
- package/lib/esm/models/legacy-types.js.map +1 -1
- package/lib/esm/testing/index.d.ts +91 -0
- package/lib/esm/testing/index.js +196 -0
- package/lib/esm/testing/index.js.map +1 -0
- package/package.json +18 -1
- package/src/core-bot.ts +11 -3
- package/src/models/ai-agents.ts +11 -0
- package/src/models/legacy-types.ts +21 -0
- package/src/testing/index.ts +311 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type BotContext,
|
|
3
|
+
type BotRequest,
|
|
4
|
+
type BotSecrets,
|
|
5
|
+
type BotSettings,
|
|
6
|
+
type ContactInfo,
|
|
7
|
+
INPUT,
|
|
8
|
+
type Input,
|
|
9
|
+
PROVIDER,
|
|
10
|
+
type ProviderType,
|
|
11
|
+
type ResolvedPlugins,
|
|
12
|
+
type Session,
|
|
13
|
+
type SessionUser,
|
|
14
|
+
} from '../models'
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Default values
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
export const TEST_DEFAULTS = {
|
|
21
|
+
HUBTYPE_API_URL: 'https://api.hubtype.com',
|
|
22
|
+
STATIC_URL: 'https://static.hubtype.com',
|
|
23
|
+
LITELLM_API_URL: 'https://api.litellm.com',
|
|
24
|
+
AZURE_OPENAI_API_BASE: 'https://api.openai.com',
|
|
25
|
+
AZURE_OPENAI_API_VERSION: '2026-02-01',
|
|
26
|
+
LANGUAGE_DETECTION_ENABLED: true,
|
|
27
|
+
HUBTYPE_ACCESS_TOKEN: 'testAccessToken', // pragma: allowlist secret
|
|
28
|
+
LITELLM_API_KEY: 'testLiteLLMAPIKey', // pragma: allowlist secret
|
|
29
|
+
AZURE_OPENAI_API_KEY: 'testAzureOpenAIAPIKey', // pragma: allowlist secret
|
|
30
|
+
ACCESS_TOKEN: 'fake_access_token',
|
|
31
|
+
HUBTYPE_API_HOST: 'https://api.hubtype.com',
|
|
32
|
+
FLOW_THREAD_ID: 'testFlowThreadId',
|
|
33
|
+
BOT_ID: 'testBotId',
|
|
34
|
+
USER_ID: 'testUserId',
|
|
35
|
+
ORG_ID: 'testOrgId',
|
|
36
|
+
ORG_NAME: 'testOrg',
|
|
37
|
+
PROVIDER: PROVIDER.WEBCHAT as ProviderType,
|
|
38
|
+
LOCALE: 'en',
|
|
39
|
+
COUNTRY: 'US',
|
|
40
|
+
BOT_INTERACTION_ID: 'testInteractionId',
|
|
41
|
+
MESSAGE_ID: 'testMessageId',
|
|
42
|
+
LAST_ROUTE_PATH: '',
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Leaf factories
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
export function createTestSettings(
|
|
50
|
+
overrides?: Partial<BotSettings>
|
|
51
|
+
): BotSettings {
|
|
52
|
+
return {
|
|
53
|
+
HUBTYPE_API_URL: TEST_DEFAULTS.HUBTYPE_API_URL,
|
|
54
|
+
STATIC_URL: TEST_DEFAULTS.STATIC_URL,
|
|
55
|
+
LITELLM_API_URL: TEST_DEFAULTS.LITELLM_API_URL,
|
|
56
|
+
AZURE_OPENAI_API_BASE: TEST_DEFAULTS.AZURE_OPENAI_API_BASE,
|
|
57
|
+
AZURE_OPENAI_API_VERSION: TEST_DEFAULTS.AZURE_OPENAI_API_VERSION,
|
|
58
|
+
LANGUAGE_DETECTION_ENABLED: TEST_DEFAULTS.LANGUAGE_DETECTION_ENABLED,
|
|
59
|
+
CUSTOM_SHORT_URL_HOST: null,
|
|
60
|
+
custom: {},
|
|
61
|
+
...overrides,
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function createTestSecrets(overrides?: Partial<BotSecrets>): BotSecrets {
|
|
66
|
+
return {
|
|
67
|
+
HUBTYPE_ACCESS_TOKEN: TEST_DEFAULTS.HUBTYPE_ACCESS_TOKEN,
|
|
68
|
+
LITELLM_API_KEY: TEST_DEFAULTS.LITELLM_API_KEY,
|
|
69
|
+
AZURE_OPENAI_API_KEY: TEST_DEFAULTS.AZURE_OPENAI_API_KEY,
|
|
70
|
+
custom: {},
|
|
71
|
+
...overrides,
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface TestUserOptions {
|
|
76
|
+
id?: string
|
|
77
|
+
provider?: ProviderType
|
|
78
|
+
locale?: string
|
|
79
|
+
country?: string
|
|
80
|
+
systemLocale?: string
|
|
81
|
+
contactInfo?: ContactInfo[]
|
|
82
|
+
extraData?: Record<string, any>
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function createTestSessionUser(
|
|
86
|
+
options?: TestUserOptions
|
|
87
|
+
): SessionUser<Record<string, any>> {
|
|
88
|
+
const locale = options?.locale ?? TEST_DEFAULTS.LOCALE
|
|
89
|
+
const country = options?.country ?? TEST_DEFAULTS.COUNTRY
|
|
90
|
+
return {
|
|
91
|
+
id: options?.id ?? TEST_DEFAULTS.USER_ID,
|
|
92
|
+
provider: options?.provider ?? TEST_DEFAULTS.PROVIDER,
|
|
93
|
+
locale,
|
|
94
|
+
country,
|
|
95
|
+
system_locale: options?.systemLocale ?? locale,
|
|
96
|
+
contact_info: options?.contactInfo ?? [],
|
|
97
|
+
extra_data: options?.extraData ?? {},
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface TestSessionOptions {
|
|
102
|
+
user?: TestUserOptions
|
|
103
|
+
botId?: string
|
|
104
|
+
organization?: string
|
|
105
|
+
organizationId?: string
|
|
106
|
+
isFirstInteraction?: boolean
|
|
107
|
+
isTestIntegration?: boolean
|
|
108
|
+
accessToken?: string
|
|
109
|
+
hubtypeApi?: string
|
|
110
|
+
flowThreadId?: string
|
|
111
|
+
retries?: number
|
|
112
|
+
shadowing?: boolean
|
|
113
|
+
hubtypeCaseId?: string
|
|
114
|
+
captureUserInputNodeId?: string
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function createTestSession(
|
|
118
|
+
options?: TestSessionOptions
|
|
119
|
+
): Session<Record<string, any>> {
|
|
120
|
+
return {
|
|
121
|
+
bot: { id: options?.botId ?? TEST_DEFAULTS.BOT_ID },
|
|
122
|
+
user: createTestSessionUser(options?.user),
|
|
123
|
+
organization: options?.organization ?? TEST_DEFAULTS.ORG_NAME,
|
|
124
|
+
organization_id: options?.organizationId ?? TEST_DEFAULTS.ORG_ID,
|
|
125
|
+
is_first_interaction: options?.isFirstInteraction ?? false,
|
|
126
|
+
is_test_integration: options?.isTestIntegration ?? false,
|
|
127
|
+
_access_token: options?.accessToken ?? TEST_DEFAULTS.ACCESS_TOKEN,
|
|
128
|
+
_hubtype_api: options?.hubtypeApi ?? TEST_DEFAULTS.HUBTYPE_API_HOST,
|
|
129
|
+
flow_thread_id: options?.flowThreadId ?? TEST_DEFAULTS.FLOW_THREAD_ID,
|
|
130
|
+
__retries: options?.retries ?? 0,
|
|
131
|
+
_shadowing: options?.shadowing,
|
|
132
|
+
_hubtype_case_id: options?.hubtypeCaseId,
|
|
133
|
+
capture_user_input: options?.captureUserInputNodeId
|
|
134
|
+
? { node_id: options.captureUserInputNodeId }
|
|
135
|
+
: undefined,
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface TestInputOptions {
|
|
140
|
+
type?: Input['type']
|
|
141
|
+
data?: string
|
|
142
|
+
text?: string
|
|
143
|
+
payload?: string
|
|
144
|
+
src?: string
|
|
145
|
+
botInteractionId?: string
|
|
146
|
+
messageId?: string
|
|
147
|
+
context?: Input['context']
|
|
148
|
+
transcript?: string
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function createTestInput(options?: TestInputOptions): Input {
|
|
152
|
+
return {
|
|
153
|
+
type: options?.type ?? INPUT.TEXT,
|
|
154
|
+
data: options?.data,
|
|
155
|
+
text: options?.text,
|
|
156
|
+
payload: options?.payload,
|
|
157
|
+
src: options?.src,
|
|
158
|
+
transcript: options?.transcript,
|
|
159
|
+
context: options?.context,
|
|
160
|
+
bot_interaction_id:
|
|
161
|
+
options?.botInteractionId ?? TEST_DEFAULTS.BOT_INTERACTION_ID,
|
|
162
|
+
message_id: options?.messageId ?? TEST_DEFAULTS.MESSAGE_ID,
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
// Composite factories
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
|
|
170
|
+
export interface TestBotRequestOptions {
|
|
171
|
+
input?: TestInputOptions | Input
|
|
172
|
+
session?: TestSessionOptions | Session
|
|
173
|
+
lastRoutePath?: string
|
|
174
|
+
settings?: Partial<BotSettings> | BotSettings
|
|
175
|
+
secrets?: Partial<BotSecrets> | BotSecrets
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function isFullInput(v: TestInputOptions | Input): v is Input {
|
|
179
|
+
return 'bot_interaction_id' in v && 'message_id' in v
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function isFullSession(v: TestSessionOptions | Session): v is Session {
|
|
183
|
+
return 'bot' in v && '__retries' in v
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function isFullSettings(
|
|
187
|
+
v: Partial<BotSettings> | BotSettings
|
|
188
|
+
): v is BotSettings {
|
|
189
|
+
return (
|
|
190
|
+
'HUBTYPE_API_URL' in v &&
|
|
191
|
+
'STATIC_URL' in v &&
|
|
192
|
+
'LITELLM_API_URL' in v &&
|
|
193
|
+
'AZURE_OPENAI_API_BASE' in v &&
|
|
194
|
+
'AZURE_OPENAI_API_VERSION' in v &&
|
|
195
|
+
'LANGUAGE_DETECTION_ENABLED' in v &&
|
|
196
|
+
'CUSTOM_SHORT_URL_HOST' in v &&
|
|
197
|
+
'custom' in v
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function isFullSecrets(v: Partial<BotSecrets> | BotSecrets): v is BotSecrets {
|
|
202
|
+
return (
|
|
203
|
+
'HUBTYPE_ACCESS_TOKEN' in v &&
|
|
204
|
+
'LITELLM_API_KEY' in v &&
|
|
205
|
+
'AZURE_OPENAI_API_KEY' in v &&
|
|
206
|
+
'custom' in v
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function createTestBotRequest(
|
|
211
|
+
options?: TestBotRequestOptions
|
|
212
|
+
): BotRequest {
|
|
213
|
+
const input =
|
|
214
|
+
options?.input == null
|
|
215
|
+
? createTestInput()
|
|
216
|
+
: isFullInput(options.input)
|
|
217
|
+
? options.input
|
|
218
|
+
: createTestInput(options.input)
|
|
219
|
+
|
|
220
|
+
const session =
|
|
221
|
+
options?.session == null
|
|
222
|
+
? createTestSession()
|
|
223
|
+
: isFullSession(options.session)
|
|
224
|
+
? options.session
|
|
225
|
+
: createTestSession(options.session)
|
|
226
|
+
|
|
227
|
+
const settings =
|
|
228
|
+
options?.settings == null
|
|
229
|
+
? createTestSettings()
|
|
230
|
+
: isFullSettings(options.settings)
|
|
231
|
+
? options.settings
|
|
232
|
+
: createTestSettings(options.settings)
|
|
233
|
+
|
|
234
|
+
const secrets =
|
|
235
|
+
options?.secrets == null
|
|
236
|
+
? createTestSecrets()
|
|
237
|
+
: isFullSecrets(options.secrets)
|
|
238
|
+
? options.secrets
|
|
239
|
+
: createTestSecrets(options.secrets)
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
input,
|
|
243
|
+
session,
|
|
244
|
+
lastRoutePath: options?.lastRoutePath ?? TEST_DEFAULTS.LAST_ROUTE_PATH,
|
|
245
|
+
settings,
|
|
246
|
+
secrets,
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface TestBotContextOptions<
|
|
251
|
+
TPlugins extends ResolvedPlugins = ResolvedPlugins,
|
|
252
|
+
> extends TestBotRequestOptions {
|
|
253
|
+
plugins?: TPlugins
|
|
254
|
+
params?: Record<string, string>
|
|
255
|
+
defaultDelay?: number
|
|
256
|
+
defaultTyping?: number
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function createTestBotContext<
|
|
260
|
+
TPlugins extends ResolvedPlugins = ResolvedPlugins,
|
|
261
|
+
>(options?: TestBotContextOptions<TPlugins>): BotContext<TPlugins> {
|
|
262
|
+
const request = createTestBotRequest(options)
|
|
263
|
+
|
|
264
|
+
const sessionForLocale =
|
|
265
|
+
options?.session == null
|
|
266
|
+
? createTestSession()
|
|
267
|
+
: isFullSession(options.session)
|
|
268
|
+
? options.session
|
|
269
|
+
: createTestSession(options.session)
|
|
270
|
+
|
|
271
|
+
const locale = sessionForLocale.user.locale
|
|
272
|
+
const country = sessionForLocale.user.country
|
|
273
|
+
const systemLocale = sessionForLocale.user.system_locale
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
...request,
|
|
277
|
+
plugins: options?.plugins ?? ({} as TPlugins),
|
|
278
|
+
params: options?.params ?? {},
|
|
279
|
+
defaultDelay: options?.defaultDelay ?? 0,
|
|
280
|
+
defaultTyping: options?.defaultTyping ?? 0,
|
|
281
|
+
getUserLocale: () => locale,
|
|
282
|
+
getUserCountry: () => country,
|
|
283
|
+
getSystemLocale: () => systemLocale,
|
|
284
|
+
setUserLocale: () => undefined,
|
|
285
|
+
setUserCountry: () => undefined,
|
|
286
|
+
setSystemLocale: () => undefined,
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Alias for `createTestBotContext` typed as `PluginPreRequest`.
|
|
292
|
+
* PluginPreRequest === BotContext in @botonic/core.
|
|
293
|
+
*/
|
|
294
|
+
export const createTestPluginPreRequest = createTestBotContext
|
|
295
|
+
|
|
296
|
+
export interface TestPluginPostRequestOptions<
|
|
297
|
+
TPlugins extends ResolvedPlugins = ResolvedPlugins,
|
|
298
|
+
> extends TestBotContextOptions<TPlugins> {
|
|
299
|
+
response?: string | null
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export function createTestPluginPostRequest<
|
|
303
|
+
TPlugins extends ResolvedPlugins = ResolvedPlugins,
|
|
304
|
+
>(
|
|
305
|
+
options?: TestPluginPostRequestOptions<TPlugins>
|
|
306
|
+
): BotContext<TPlugins> & { response: string | null } {
|
|
307
|
+
return {
|
|
308
|
+
...createTestBotContext(options),
|
|
309
|
+
response: options?.response ?? null,
|
|
310
|
+
}
|
|
311
|
+
}
|