@applica-software-guru/persona-sdk 0.1.106 → 0.1.108
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/bundle.cjs.js +1 -1
- package/dist/bundle.cjs.js.map +1 -1
- package/dist/bundle.es.js +9 -6
- package/dist/bundle.es.js.map +1 -1
- package/dist/index.d.ts +118 -2
- package/package.json +2 -1
- package/src/agents/types.ts +89 -1
- package/src/index.ts +15 -1
- package/src/service-prices/service-prices-api.ts +11 -2
- package/src/service-prices/types.ts +24 -0
- package/tests/service-prices-api.test.mjs +69 -0
package/src/agents/types.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type LanguageCode = 'en-US' | 'it-IT' | 'es-ES' | 'fr-FR' | 'de-DE' | 'pt
|
|
|
7
7
|
|
|
8
8
|
export type SynthesizerName = 'gcloud' | 'elevenlabs' | 'gtts' | 'openai';
|
|
9
9
|
|
|
10
|
-
export type TranscriberName = 'gcloud' | 'deepgram' | 'vosk';
|
|
10
|
+
export type TranscriberName = 'gcloud' | 'deepgram' | 'elevenlabs' | 'vosk';
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
export type ToolType = 'remote' | 'local';
|
|
@@ -93,13 +93,34 @@ export interface SynthesizerConfiguration {
|
|
|
93
93
|
stability?: number;
|
|
94
94
|
style?: number;
|
|
95
95
|
voiceInstructions?: string;
|
|
96
|
+
/**
|
|
97
|
+
* Solo ElevenLabs, 0-4. Valori alti riducono la latenza ma dal 4 il
|
|
98
|
+
* normalizzatore del testo viene disattivato e numeri e date vengono
|
|
99
|
+
* pronunciati male.
|
|
100
|
+
*/
|
|
101
|
+
optimizeStreamingLatency?: number;
|
|
96
102
|
}
|
|
97
103
|
|
|
104
|
+
export type CommitStrategy = 'vad' | 'manual';
|
|
105
|
+
|
|
98
106
|
export interface TranscriberConfiguration {
|
|
99
107
|
enabled?: boolean;
|
|
100
108
|
transcriberName?: TranscriberName;
|
|
101
109
|
languageCode?: LanguageCode;
|
|
102
110
|
sampleRateHertz?: number;
|
|
111
|
+
/**
|
|
112
|
+
* Secondi di silenzio dopo i quali il turno dell'utente è considerato
|
|
113
|
+
* concluso: è il parametro con più impatto sulla latenza percepita, perché
|
|
114
|
+
* l'agente non inizia a elaborare prima che scada. Valori bassi rendono la
|
|
115
|
+
* conversazione reattiva ma spezzano le pause di pensiero in due turni.
|
|
116
|
+
*/
|
|
117
|
+
silenceDurationThreshold?: number;
|
|
118
|
+
/** Solo ElevenLabs Scribe. */
|
|
119
|
+
modelId?: string;
|
|
120
|
+
commitStrategy?: CommitStrategy;
|
|
121
|
+
keyterms?: string[];
|
|
122
|
+
secondaryLanguages?: string[];
|
|
123
|
+
filterBackgroundAudio?: boolean;
|
|
103
124
|
}
|
|
104
125
|
|
|
105
126
|
export interface KnowledgeConfiguration {
|
|
@@ -149,6 +170,69 @@ export interface WakeupConfiguration {
|
|
|
149
170
|
sleepDelaySeconds?: number;
|
|
150
171
|
}
|
|
151
172
|
|
|
173
|
+
export type ThinkingFillerMode = 'sound' | 'words';
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Riempitivo emesso quando l'agente è occupato e muto.
|
|
177
|
+
*
|
|
178
|
+
* Copre due momenti che per l'utente sono lo stesso silenzio: la chiamata di uno
|
|
179
|
+
* strumento e la fase di ragionamento del modello. Non scatta se l'agente ha già
|
|
180
|
+
* detto qualcosa prima di occuparsi.
|
|
181
|
+
*/
|
|
182
|
+
export interface ThinkingFillerConfiguration {
|
|
183
|
+
enabled?: boolean;
|
|
184
|
+
/** `sound` è il tono breve, `words` una frase parlata scelta a caso. */
|
|
185
|
+
mode?: ThinkingFillerMode;
|
|
186
|
+
words?: string[];
|
|
187
|
+
/** Attesa prima di emettere: le attese rapide non producono niente. */
|
|
188
|
+
delaySeconds?: number;
|
|
189
|
+
/** Distanza minima tra due riempitivi, condivisa col backchannel. */
|
|
190
|
+
throttleSeconds?: number;
|
|
191
|
+
/**
|
|
192
|
+
* Se emettere il riempitivo anche mentre il modello ragiona. Disattivo per
|
|
193
|
+
* default: con modelli che ragionano a ogni turno può diventare invadente.
|
|
194
|
+
*/
|
|
195
|
+
onReasoning?: boolean;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export type BackchannelMode = 'static' | 'llm';
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Riempitivi vocali emessi mentre l'utente sta ancora parlando.
|
|
202
|
+
*
|
|
203
|
+
* Due modalità con compromessi diversi:
|
|
204
|
+
* - `static`: una parola scelta a caso dalla lista. Le clip sono
|
|
205
|
+
* pre-sintetizzate e in cache, quindi la latenza aggiunta è zero.
|
|
206
|
+
* - `llm`: un modello veloce genera la frase seguendo `instructions`. Più
|
|
207
|
+
* pertinente, ma la prima volta che produce un testo nuovo si paga LLM più
|
|
208
|
+
* TTS; se non è pronto in tempo si ripiega su una parola della lista.
|
|
209
|
+
*
|
|
210
|
+
* Richiede un synthesizer con sintesi one-shot (gcloud o elevenlabs).
|
|
211
|
+
*/
|
|
212
|
+
export interface BackchannelConfiguration {
|
|
213
|
+
enabled?: boolean;
|
|
214
|
+
mode?: BackchannelMode;
|
|
215
|
+
/** Lista per `static`, e fallback per `llm` quando il modello tarda. */
|
|
216
|
+
words?: string[];
|
|
217
|
+
/** Solo `llm`: cosa deve generare il modello. */
|
|
218
|
+
instructions?: string;
|
|
219
|
+
/** Tetto sulle parole generate, per non parlare sopra l'utente. */
|
|
220
|
+
maxGeneratedWords?: number;
|
|
221
|
+
/** Parlato continuo richiesto prima di intervenire. */
|
|
222
|
+
minSpeechSeconds?: number;
|
|
223
|
+
maxPerUserTurn?: number;
|
|
224
|
+
partialFreshnessSeconds?: number;
|
|
225
|
+
agentSilenceSeconds?: number;
|
|
226
|
+
throttleSeconds?: number;
|
|
227
|
+
/**
|
|
228
|
+
* Modello usato dalla modalità `llm`. Va scelto piccolo e veloce: sta nel
|
|
229
|
+
* percorso critico di un riempitivo che deve arrivare entro un secondo.
|
|
230
|
+
*/
|
|
231
|
+
model?: ModelConfiguration;
|
|
232
|
+
llmTimeoutSeconds?: number;
|
|
233
|
+
prewarm?: boolean;
|
|
234
|
+
}
|
|
235
|
+
|
|
152
236
|
export interface TelegramConfiguration {
|
|
153
237
|
enabled?: boolean;
|
|
154
238
|
botToken?: string;
|
|
@@ -286,6 +370,8 @@ export interface Agent {
|
|
|
286
370
|
initialMessageMode?: "processed" | "static";
|
|
287
371
|
knowledge?: KnowledgeConfiguration;
|
|
288
372
|
wakeup?: WakeupConfiguration;
|
|
373
|
+
backchannel?: BackchannelConfiguration;
|
|
374
|
+
thinkingFiller?: ThinkingFillerConfiguration;
|
|
289
375
|
telegram?: TelegramConfiguration;
|
|
290
376
|
whatsapp?: WhatsAppConfiguration;
|
|
291
377
|
collaboration?: CollaborationConfiguration;
|
|
@@ -317,6 +403,8 @@ export interface AgentCreateRequest {
|
|
|
317
403
|
initialMessageMode?: "processed" | "static";
|
|
318
404
|
knowledge?: KnowledgeConfiguration;
|
|
319
405
|
wakeup?: WakeupConfiguration;
|
|
406
|
+
backchannel?: BackchannelConfiguration;
|
|
407
|
+
thinkingFiller?: ThinkingFillerConfiguration;
|
|
320
408
|
telegram?: TelegramConfiguration;
|
|
321
409
|
whatsapp?: WhatsAppConfiguration;
|
|
322
410
|
collaboration?: CollaborationConfiguration;
|
package/src/index.ts
CHANGED
|
@@ -39,6 +39,11 @@ export type {
|
|
|
39
39
|
Variable,
|
|
40
40
|
VariableSource,
|
|
41
41
|
WakeupConfiguration,
|
|
42
|
+
BackchannelConfiguration,
|
|
43
|
+
BackchannelMode,
|
|
44
|
+
ThinkingFillerConfiguration,
|
|
45
|
+
ThinkingFillerMode,
|
|
46
|
+
CommitStrategy,
|
|
42
47
|
WhatsAppConfiguration,
|
|
43
48
|
Tool,
|
|
44
49
|
ToolType,
|
|
@@ -151,7 +156,16 @@ export type {
|
|
|
151
156
|
export { MissionsApi } from './missions/missions-api';
|
|
152
157
|
export type { Mission, MissionStatus } from './missions/types';
|
|
153
158
|
export { ServicePricesApi } from './service-prices/service-prices-api';
|
|
154
|
-
export type {
|
|
159
|
+
export type {
|
|
160
|
+
ServicePrice,
|
|
161
|
+
ServicePriceListParams,
|
|
162
|
+
ServicePricePricingStatus,
|
|
163
|
+
ServicePriceSort,
|
|
164
|
+
ServicePriceSortField,
|
|
165
|
+
ServicePriceStats,
|
|
166
|
+
ServicePriceStatsParams,
|
|
167
|
+
ServicePriceUnit,
|
|
168
|
+
} from './service-prices/types';
|
|
155
169
|
export { MarkupRulesApi } from './markup-rules/markup-rules-api';
|
|
156
170
|
export type { MarkupRule } from './markup-rules/types';
|
|
157
171
|
export { ProvidersApi } from './providers/providers-api';
|
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
import { HttpApi } from '../http-api';
|
|
2
2
|
import { Paginated } from '../paginated';
|
|
3
3
|
import { AuthenticationProvider } from '../auth/authentication-provider';
|
|
4
|
-
import { ServicePrice } from './types';
|
|
4
|
+
import { ServicePrice, ServicePriceListParams, ServicePriceStats, ServicePriceStatsParams } from './types';
|
|
5
5
|
|
|
6
6
|
export class ServicePricesApi extends HttpApi {
|
|
7
7
|
constructor(baseUrl: string, auth: string | AuthenticationProvider) {
|
|
8
8
|
super(baseUrl, auth);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
async list(
|
|
11
|
+
async list(
|
|
12
|
+
keyword?: string | null,
|
|
13
|
+
page?: number,
|
|
14
|
+
size?: number,
|
|
15
|
+
extraParams?: ServicePriceListParams
|
|
16
|
+
): Promise<Paginated<ServicePrice>> {
|
|
12
17
|
const { page: p, size: s } = this.normalizePageParams(page, size);
|
|
13
18
|
const params: Record<string, unknown> = { page: p, size: s, ...extraParams };
|
|
14
19
|
if (keyword) params.keyword = keyword;
|
|
15
20
|
return this.httpGet<Paginated<ServicePrice>>('/service-prices', params);
|
|
16
21
|
}
|
|
17
22
|
|
|
23
|
+
async getStats(params: ServicePriceStatsParams = {}): Promise<ServicePriceStats> {
|
|
24
|
+
return this.httpGet<ServicePriceStats>('/service-prices/stats', { ...params });
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
async get(id: string): Promise<ServicePrice> {
|
|
19
28
|
return this.httpGet<ServicePrice>('/service-prices/' + id);
|
|
20
29
|
}
|
|
@@ -5,3 +5,27 @@ export interface ServicePrice {
|
|
|
5
5
|
unit?: string;
|
|
6
6
|
fixedPrice?: number;
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
export type ServicePriceUnit = 'seconds' | 'tokens' | 'characters' | 'pages' | 'calls';
|
|
10
|
+
export type ServicePricePricingStatus = 'priced' | 'unpriced' | 'withFixedPrice';
|
|
11
|
+
export type ServicePriceSortField = 'service' | 'cost' | 'unit' | 'fixedPrice';
|
|
12
|
+
export type ServicePriceSort = `${ServicePriceSortField},${'asc' | 'desc'}`;
|
|
13
|
+
|
|
14
|
+
export interface ServicePriceListParams {
|
|
15
|
+
sort?: ServicePriceSort;
|
|
16
|
+
unit?: ServicePriceUnit;
|
|
17
|
+
pricingStatus?: ServicePricePricingStatus;
|
|
18
|
+
[key: string]: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ServicePriceStatsParams {
|
|
22
|
+
keyword?: string | null;
|
|
23
|
+
unit?: ServicePriceUnit;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ServicePriceStats {
|
|
27
|
+
total: number;
|
|
28
|
+
priced: number;
|
|
29
|
+
unpriced: number;
|
|
30
|
+
withFixedPrice: number;
|
|
31
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
|
|
4
|
+
import { ServicePricesApi } from '../dist/bundle.es.js';
|
|
5
|
+
|
|
6
|
+
function jsonResponse(body) {
|
|
7
|
+
return new Response(JSON.stringify(body), {
|
|
8
|
+
status: 200,
|
|
9
|
+
headers: { 'Content-Type': 'application/json' },
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
test('service price list forwards typed sort and filters', async (context) => {
|
|
14
|
+
const originalFetch = globalThis.fetch;
|
|
15
|
+
context.after(() => {
|
|
16
|
+
globalThis.fetch = originalFetch;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
let requestUrl;
|
|
20
|
+
globalThis.fetch = async (url) => {
|
|
21
|
+
requestUrl = new URL(url);
|
|
22
|
+
return jsonResponse({ items: [], total: 0, page: 2, size: 10 });
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const api = new ServicePricesApi('https://example.test', 'api-key');
|
|
26
|
+
await api.list('openai', 2, 10, {
|
|
27
|
+
sort: 'cost,desc',
|
|
28
|
+
unit: 'tokens',
|
|
29
|
+
pricingStatus: 'unpriced',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
assert.equal(requestUrl.pathname, '/service-prices');
|
|
33
|
+
assert.deepEqual(Object.fromEntries(requestUrl.searchParams), {
|
|
34
|
+
page: '2',
|
|
35
|
+
size: '10',
|
|
36
|
+
sort: 'cost,desc',
|
|
37
|
+
unit: 'tokens',
|
|
38
|
+
pricingStatus: 'unpriced',
|
|
39
|
+
keyword: 'openai',
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('service price stats forwards its filters and returns KPI values', async (context) => {
|
|
44
|
+
const originalFetch = globalThis.fetch;
|
|
45
|
+
context.after(() => {
|
|
46
|
+
globalThis.fetch = originalFetch;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
let requestUrl;
|
|
50
|
+
globalThis.fetch = async (url) => {
|
|
51
|
+
requestUrl = new URL(url);
|
|
52
|
+
return jsonResponse({ total: 10, priced: 7, unpriced: 3, withFixedPrice: 2 });
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const api = new ServicePricesApi('https://example.test', 'api-key');
|
|
56
|
+
const stats = await api.getStats({ keyword: 'model', unit: 'tokens' });
|
|
57
|
+
|
|
58
|
+
assert.equal(requestUrl.pathname, '/service-prices/stats');
|
|
59
|
+
assert.deepEqual(Object.fromEntries(requestUrl.searchParams), {
|
|
60
|
+
keyword: 'model',
|
|
61
|
+
unit: 'tokens',
|
|
62
|
+
});
|
|
63
|
+
assert.deepEqual(stats, {
|
|
64
|
+
total: 10,
|
|
65
|
+
priced: 7,
|
|
66
|
+
unpriced: 3,
|
|
67
|
+
withFixedPrice: 2,
|
|
68
|
+
});
|
|
69
|
+
});
|