@absolutejs/voice 0.0.22-beta.481 → 0.0.22-beta.483
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.ts +4 -0
- package/dist/index.js +214 -0
- package/dist/llmJudge.d.ts +45 -0
- package/dist/semanticTurn.d.ts +27 -0
- package/dist/testing/index.js +12 -0
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -71,10 +71,14 @@ export { createVoiceSessionListRoutes, createVoiceSessionReplayHTMLHandler, crea
|
|
|
71
71
|
export { createVoiceAgent, createVoiceAgentSquad, createVoiceAgentTool, } from "./agent";
|
|
72
72
|
export { createAIVoiceModel } from "./aiVoiceModel";
|
|
73
73
|
export type { CreateAIVoiceModelOptions } from "./aiVoiceModel";
|
|
74
|
+
export { createVoiceAIJudgeCompletion, createVoiceLLMJudge, } from "./llmJudge";
|
|
75
|
+
export type { CreateVoiceAIJudgeCompletionOptions, CreateVoiceLLMJudgeOptions, VoiceLLMJudge, VoiceLLMJudgeCompletion, VoiceLLMJudgeCriterionVerdict, VoiceLLMJudgeInput, VoiceLLMJudgeRubric, VoiceLLMJudgeRubricCriterion, VoiceLLMJudgeVerdict, } from "./llmJudge";
|
|
74
76
|
export { DEFAULT_VOICE_REDACTION_PATTERNS, createVoiceTranscriptRedactor, redactVoiceTranscript, } from "./redaction";
|
|
75
77
|
export type { CreateVoiceTranscriptRedactorOptions, VoiceRedactionPattern, VoiceTranscriptRedactor, } from "./redaction";
|
|
76
78
|
export { DEFAULT_VOICE_PRICE_BOOK, createVoiceCostAccountant, } from "./costAccounting";
|
|
77
79
|
export type { CreateVoiceCostAccountantOptions, VoiceCostAccountant, VoiceCostBreakdown, VoiceCostLLMRecord, VoiceCostSTTRecord, VoiceCostTTSRecord, VoiceCostTelephonyRecord, VoicePriceBook, VoiceProviderRates, } from "./costAccounting";
|
|
80
|
+
export { createPunctuationSemanticTurnDetector, createRegexSemanticTurnDetector, } from "./semanticTurn";
|
|
81
|
+
export type { CreatePunctuationSemanticTurnDetectorOptions, CreateRegexSemanticTurnDetectorOptions, VoiceSemanticTurnDetector, VoiceSemanticTurnInput, VoiceSemanticTurnVerdict, } from "./semanticTurn";
|
|
78
82
|
export { createMonologueAMDDetector } from "./amdDetector";
|
|
79
83
|
export type { MonologueAMDDetectorOptions, VoiceAMDDetector, VoiceAMDDetectorInput, VoiceAMDVerdict, } from "./amdDetector";
|
|
80
84
|
export { createVoiceRAGTool } from "./ragTool";
|
package/dist/index.js
CHANGED
|
@@ -4786,6 +4786,18 @@ var createVoiceSession = (options) => {
|
|
|
4786
4786
|
session,
|
|
4787
4787
|
type: "turn.transcript"
|
|
4788
4788
|
});
|
|
4789
|
+
if (options.semanticTurnDetector) {
|
|
4790
|
+
const verdict = await Promise.resolve(options.semanticTurnDetector.evaluate({
|
|
4791
|
+
lastFinalTranscript: transcript,
|
|
4792
|
+
partialText: session.currentTurn.partialText,
|
|
4793
|
+
silenceMs: session.currentTurn.silenceStartedAt !== undefined ? Date.now() - session.currentTurn.silenceStartedAt : 0,
|
|
4794
|
+
transcripts: session.currentTurn.transcripts
|
|
4795
|
+
}));
|
|
4796
|
+
if (verdict.endOfTurn) {
|
|
4797
|
+
clearSilenceTimer();
|
|
4798
|
+
await requestTurnCommit("vendor");
|
|
4799
|
+
}
|
|
4800
|
+
}
|
|
4789
4801
|
};
|
|
4790
4802
|
const resumePendingTurnCommit = (session) => {
|
|
4791
4803
|
const pendingText = buildTurnText(session.currentTurn.transcripts, session.currentTurn.partialText, {
|
|
@@ -34981,6 +34993,134 @@ var createAIVoiceModel = (options) => ({
|
|
|
34981
34993
|
return output;
|
|
34982
34994
|
}
|
|
34983
34995
|
});
|
|
34996
|
+
// src/llmJudge.ts
|
|
34997
|
+
var DEFAULT_SYSTEM_PROMPT = "You are an impartial evaluator scoring a voice-agent transcript against a rubric. " + "For each criterion, decide pass/fail and give a one-sentence rationale grounded in the transcript. " + 'Respond with strict JSON: {"criteria":[{"criterionId":"\u2026","passed":true,"rationale":"\u2026"}],"summary":"\u2026"}.';
|
|
34998
|
+
var buildPrompt = (rubric, input) => {
|
|
34999
|
+
const criteriaBlock = rubric.criteria.map((criterion) => `- ${criterion.id}${criterion.required ? " (required)" : ""}: ${criterion.description}`).join(`
|
|
35000
|
+
`);
|
|
35001
|
+
const metadataBlock = input.metadata ? `
|
|
35002
|
+
Metadata:
|
|
35003
|
+
${JSON.stringify(input.metadata, null, 2)}
|
|
35004
|
+
` : "";
|
|
35005
|
+
return `Rubric criteria:
|
|
35006
|
+
${criteriaBlock}
|
|
35007
|
+
${metadataBlock}
|
|
35008
|
+
Transcript:
|
|
35009
|
+
${input.transcript}
|
|
35010
|
+
|
|
35011
|
+
Return JSON only.`;
|
|
35012
|
+
};
|
|
35013
|
+
var extractJson = (raw) => {
|
|
35014
|
+
const trimmed = raw.trim();
|
|
35015
|
+
if (!trimmed) {
|
|
35016
|
+
throw new Error("LLM judge returned an empty response");
|
|
35017
|
+
}
|
|
35018
|
+
const fenced = /```(?:json)?\s*([\s\S]*?)```/i.exec(trimmed);
|
|
35019
|
+
const candidate = fenced ? fenced[1].trim() : trimmed;
|
|
35020
|
+
try {
|
|
35021
|
+
return JSON.parse(candidate);
|
|
35022
|
+
} catch {
|
|
35023
|
+
const start = candidate.indexOf("{");
|
|
35024
|
+
const end = candidate.lastIndexOf("}");
|
|
35025
|
+
if (start >= 0 && end > start) {
|
|
35026
|
+
return JSON.parse(candidate.slice(start, end + 1));
|
|
35027
|
+
}
|
|
35028
|
+
throw new Error(`LLM judge response was not valid JSON: ${raw.slice(0, 200)}`);
|
|
35029
|
+
}
|
|
35030
|
+
};
|
|
35031
|
+
var parseCriteria = (payload, rubric) => {
|
|
35032
|
+
if (!payload || typeof payload !== "object") {
|
|
35033
|
+
throw new Error("LLM judge response is not a JSON object");
|
|
35034
|
+
}
|
|
35035
|
+
const root = payload;
|
|
35036
|
+
const criteriaRaw = root.criteria;
|
|
35037
|
+
if (!Array.isArray(criteriaRaw)) {
|
|
35038
|
+
throw new Error("LLM judge response is missing the 'criteria' array");
|
|
35039
|
+
}
|
|
35040
|
+
const verdictById = new Map;
|
|
35041
|
+
for (const entry of criteriaRaw) {
|
|
35042
|
+
if (!entry || typeof entry !== "object") {
|
|
35043
|
+
continue;
|
|
35044
|
+
}
|
|
35045
|
+
const record = entry;
|
|
35046
|
+
const criterionId = typeof record.criterionId === "string" ? record.criterionId : typeof record.id === "string" ? record.id : undefined;
|
|
35047
|
+
if (!criterionId) {
|
|
35048
|
+
continue;
|
|
35049
|
+
}
|
|
35050
|
+
verdictById.set(criterionId, {
|
|
35051
|
+
criterionId,
|
|
35052
|
+
passed: record.passed === true,
|
|
35053
|
+
rationale: typeof record.rationale === "string" ? record.rationale : ""
|
|
35054
|
+
});
|
|
35055
|
+
}
|
|
35056
|
+
const criteria = rubric.criteria.map((criterion) => verdictById.get(criterion.id) ?? {
|
|
35057
|
+
criterionId: criterion.id,
|
|
35058
|
+
passed: false,
|
|
35059
|
+
rationale: "Judge did not return a verdict for this criterion."
|
|
35060
|
+
});
|
|
35061
|
+
return {
|
|
35062
|
+
criteria,
|
|
35063
|
+
summary: typeof root.summary === "string" ? root.summary : undefined
|
|
35064
|
+
};
|
|
35065
|
+
};
|
|
35066
|
+
var scoreVerdict = (rubric, criteria) => {
|
|
35067
|
+
const totalWeight = rubric.criteria.reduce((sum, criterion) => sum + (criterion.weight ?? 1), 0);
|
|
35068
|
+
if (totalWeight === 0) {
|
|
35069
|
+
return { passed: false, score: 0 };
|
|
35070
|
+
}
|
|
35071
|
+
const weightById = new Map(rubric.criteria.map((criterion) => [criterion.id, criterion.weight ?? 1]));
|
|
35072
|
+
const requiredIds = new Set(rubric.criteria.filter((criterion) => criterion.required).map((criterion) => criterion.id));
|
|
35073
|
+
let earned = 0;
|
|
35074
|
+
let allRequiredPassed = true;
|
|
35075
|
+
for (const verdict of criteria) {
|
|
35076
|
+
if (verdict.passed) {
|
|
35077
|
+
earned += weightById.get(verdict.criterionId) ?? 1;
|
|
35078
|
+
} else if (requiredIds.has(verdict.criterionId)) {
|
|
35079
|
+
allRequiredPassed = false;
|
|
35080
|
+
}
|
|
35081
|
+
}
|
|
35082
|
+
const score = earned / totalWeight;
|
|
35083
|
+
const minPassScore = rubric.minPassScore ?? 1;
|
|
35084
|
+
return {
|
|
35085
|
+
passed: allRequiredPassed && score >= minPassScore,
|
|
35086
|
+
score
|
|
35087
|
+
};
|
|
35088
|
+
};
|
|
35089
|
+
var createVoiceLLMJudge = (options) => ({
|
|
35090
|
+
evaluate: async (input) => {
|
|
35091
|
+
const prompt = buildPrompt(options.rubric, input);
|
|
35092
|
+
const raw = await options.completion({
|
|
35093
|
+
prompt,
|
|
35094
|
+
systemPrompt: options.systemPrompt ?? DEFAULT_SYSTEM_PROMPT
|
|
35095
|
+
});
|
|
35096
|
+
const parsed = parseCriteria(extractJson(raw), options.rubric);
|
|
35097
|
+
const { passed, score } = scoreVerdict(options.rubric, parsed.criteria);
|
|
35098
|
+
return {
|
|
35099
|
+
criteria: parsed.criteria,
|
|
35100
|
+
passed,
|
|
35101
|
+
score,
|
|
35102
|
+
summary: parsed.summary
|
|
35103
|
+
};
|
|
35104
|
+
},
|
|
35105
|
+
rubric: options.rubric
|
|
35106
|
+
});
|
|
35107
|
+
var createVoiceAIJudgeCompletion = (options) => async ({ prompt, systemPrompt }) => {
|
|
35108
|
+
const messages = [
|
|
35109
|
+
{ content: prompt, role: "user" }
|
|
35110
|
+
];
|
|
35111
|
+
const stream = options.provider.stream({
|
|
35112
|
+
messages,
|
|
35113
|
+
model: options.model,
|
|
35114
|
+
systemPrompt
|
|
35115
|
+
});
|
|
35116
|
+
let buffered = "";
|
|
35117
|
+
for await (const chunk of stream) {
|
|
35118
|
+
if (chunk.type === "text") {
|
|
35119
|
+
buffered += chunk.content;
|
|
35120
|
+
}
|
|
35121
|
+
}
|
|
35122
|
+
return buffered;
|
|
35123
|
+
};
|
|
34984
35124
|
// src/redaction.ts
|
|
34985
35125
|
var DEFAULT_VOICE_REDACTION_PATTERNS = [
|
|
34986
35126
|
{
|
|
@@ -35164,6 +35304,76 @@ var createVoiceCostAccountant = (options = {}) => {
|
|
|
35164
35304
|
})
|
|
35165
35305
|
};
|
|
35166
35306
|
};
|
|
35307
|
+
// src/semanticTurn.ts
|
|
35308
|
+
var DEFAULT_END_PUNCTUATION = [".", "?", "!"];
|
|
35309
|
+
var DEFAULT_FILLER_WORDS = [
|
|
35310
|
+
"uh",
|
|
35311
|
+
"um",
|
|
35312
|
+
"er",
|
|
35313
|
+
"ah",
|
|
35314
|
+
"like",
|
|
35315
|
+
"you know",
|
|
35316
|
+
"i mean",
|
|
35317
|
+
"well",
|
|
35318
|
+
"so"
|
|
35319
|
+
];
|
|
35320
|
+
var stripTerminalPunctuation = (text) => text.replace(/[\s.?!]+$/u, "").trim();
|
|
35321
|
+
var createPunctuationSemanticTurnDetector = (options = {}) => {
|
|
35322
|
+
const endPunctuation = options.endPunctuation ?? DEFAULT_END_PUNCTUATION;
|
|
35323
|
+
const fillerWords = (options.fillerWords ?? DEFAULT_FILLER_WORDS).map((word) => word.toLowerCase());
|
|
35324
|
+
const minPartialWords = options.minPartialWords ?? 2;
|
|
35325
|
+
return {
|
|
35326
|
+
evaluate: ({ lastFinalTranscript, partialText }) => {
|
|
35327
|
+
const candidate = partialText.trim().length > 0 ? partialText : lastFinalTranscript?.text ?? "";
|
|
35328
|
+
const trimmed = candidate.trim();
|
|
35329
|
+
if (!trimmed) {
|
|
35330
|
+
return { endOfTurn: false, reason: "empty" };
|
|
35331
|
+
}
|
|
35332
|
+
const wordCount = trimmed.split(/\s+/u).filter(Boolean).length;
|
|
35333
|
+
if (wordCount < minPartialWords) {
|
|
35334
|
+
return { endOfTurn: false, reason: "below-min-words" };
|
|
35335
|
+
}
|
|
35336
|
+
const lastChar = trimmed.at(-1);
|
|
35337
|
+
const endsWithTerminal = typeof lastChar === "string" && endPunctuation.includes(lastChar);
|
|
35338
|
+
if (!endsWithTerminal) {
|
|
35339
|
+
return { endOfTurn: false, reason: "no-terminal-punctuation" };
|
|
35340
|
+
}
|
|
35341
|
+
const lastWord = stripTerminalPunctuation(trimmed).split(/\s+/u).at(-1)?.toLowerCase();
|
|
35342
|
+
if (lastWord && fillerWords.includes(lastWord)) {
|
|
35343
|
+
return { endOfTurn: false, reason: "trailing-filler" };
|
|
35344
|
+
}
|
|
35345
|
+
return {
|
|
35346
|
+
confidence: 0.9,
|
|
35347
|
+
endOfTurn: true,
|
|
35348
|
+
reason: "terminal-punctuation"
|
|
35349
|
+
};
|
|
35350
|
+
}
|
|
35351
|
+
};
|
|
35352
|
+
};
|
|
35353
|
+
var createRegexSemanticTurnDetector = (options) => {
|
|
35354
|
+
const minPartialWords = options.minPartialWords ?? 2;
|
|
35355
|
+
return {
|
|
35356
|
+
evaluate: ({ lastFinalTranscript, partialText }) => {
|
|
35357
|
+
const candidate = partialText.trim().length > 0 ? partialText : lastFinalTranscript?.text ?? "";
|
|
35358
|
+
const trimmed = candidate.trim();
|
|
35359
|
+
if (!trimmed) {
|
|
35360
|
+
return { endOfTurn: false, reason: "empty" };
|
|
35361
|
+
}
|
|
35362
|
+
const wordCount = trimmed.split(/\s+/u).filter(Boolean).length;
|
|
35363
|
+
if (wordCount < minPartialWords) {
|
|
35364
|
+
return { endOfTurn: false, reason: "below-min-words" };
|
|
35365
|
+
}
|
|
35366
|
+
const match = options.endPattern.exec(trimmed);
|
|
35367
|
+
if (!match) {
|
|
35368
|
+
return { endOfTurn: false, reason: "pattern-miss" };
|
|
35369
|
+
}
|
|
35370
|
+
return {
|
|
35371
|
+
endOfTurn: true,
|
|
35372
|
+
reason: "pattern-match"
|
|
35373
|
+
};
|
|
35374
|
+
}
|
|
35375
|
+
};
|
|
35376
|
+
};
|
|
35167
35377
|
// src/amdDetector.ts
|
|
35168
35378
|
var createMonologueAMDDetector = (options = {}) => {
|
|
35169
35379
|
const minMonologueMs = options.minMonologueMs ?? 8000;
|
|
@@ -46252,6 +46462,7 @@ export {
|
|
|
46252
46462
|
createVoiceLinearIssueUpdateSink,
|
|
46253
46463
|
createVoiceLinearIssueSyncSinks,
|
|
46254
46464
|
createVoiceLinearIssueSink,
|
|
46465
|
+
createVoiceLLMJudge,
|
|
46255
46466
|
createVoiceIntegrationSinkWorkerLoop,
|
|
46256
46467
|
createVoiceIntegrationSinkWorker,
|
|
46257
46468
|
createVoiceIntegrationHTTPSink,
|
|
@@ -46347,6 +46558,7 @@ export {
|
|
|
46347
46558
|
createVoiceAgentTool,
|
|
46348
46559
|
createVoiceAgentSquad,
|
|
46349
46560
|
createVoiceAgent,
|
|
46561
|
+
createVoiceAIJudgeCompletion,
|
|
46350
46562
|
createTwilioVoiceRoutes,
|
|
46351
46563
|
createTwilioVoiceResponse,
|
|
46352
46564
|
createTwilioMediaStreamBridge,
|
|
@@ -46359,6 +46571,8 @@ export {
|
|
|
46359
46571
|
createStoredVoiceExternalObjectMap,
|
|
46360
46572
|
createStoredVoiceCallReviewArtifact,
|
|
46361
46573
|
createRiskyTurnCorrectionHandler,
|
|
46574
|
+
createRegexSemanticTurnDetector,
|
|
46575
|
+
createPunctuationSemanticTurnDetector,
|
|
46362
46576
|
createPlivoVoiceRoutes,
|
|
46363
46577
|
createPlivoVoiceResponse,
|
|
46364
46578
|
createPlivoMediaStreamBridge,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AIProviderConfig } from "@absolutejs/ai";
|
|
2
|
+
export type VoiceLLMJudgeRubricCriterion = {
|
|
3
|
+
description: string;
|
|
4
|
+
id: string;
|
|
5
|
+
required?: boolean;
|
|
6
|
+
weight?: number;
|
|
7
|
+
};
|
|
8
|
+
export type VoiceLLMJudgeRubric = {
|
|
9
|
+
criteria: VoiceLLMJudgeRubricCriterion[];
|
|
10
|
+
minPassScore?: number;
|
|
11
|
+
};
|
|
12
|
+
export type VoiceLLMJudgeCriterionVerdict = {
|
|
13
|
+
criterionId: string;
|
|
14
|
+
passed: boolean;
|
|
15
|
+
rationale: string;
|
|
16
|
+
};
|
|
17
|
+
export type VoiceLLMJudgeVerdict = {
|
|
18
|
+
criteria: VoiceLLMJudgeCriterionVerdict[];
|
|
19
|
+
passed: boolean;
|
|
20
|
+
score: number;
|
|
21
|
+
summary?: string;
|
|
22
|
+
};
|
|
23
|
+
export type VoiceLLMJudgeInput = {
|
|
24
|
+
metadata?: Record<string, unknown>;
|
|
25
|
+
transcript: string;
|
|
26
|
+
};
|
|
27
|
+
export type VoiceLLMJudgeCompletion = (input: {
|
|
28
|
+
prompt: string;
|
|
29
|
+
systemPrompt?: string;
|
|
30
|
+
}) => Promise<string>;
|
|
31
|
+
export type CreateVoiceLLMJudgeOptions = {
|
|
32
|
+
completion: VoiceLLMJudgeCompletion;
|
|
33
|
+
rubric: VoiceLLMJudgeRubric;
|
|
34
|
+
systemPrompt?: string;
|
|
35
|
+
};
|
|
36
|
+
export type VoiceLLMJudge = {
|
|
37
|
+
evaluate: (input: VoiceLLMJudgeInput) => Promise<VoiceLLMJudgeVerdict>;
|
|
38
|
+
rubric: VoiceLLMJudgeRubric;
|
|
39
|
+
};
|
|
40
|
+
export declare const createVoiceLLMJudge: (options: CreateVoiceLLMJudgeOptions) => VoiceLLMJudge;
|
|
41
|
+
export type CreateVoiceAIJudgeCompletionOptions = {
|
|
42
|
+
model: string;
|
|
43
|
+
provider: AIProviderConfig;
|
|
44
|
+
};
|
|
45
|
+
export declare const createVoiceAIJudgeCompletion: (options: CreateVoiceAIJudgeCompletionOptions) => VoiceLLMJudgeCompletion;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Transcript } from "./types";
|
|
2
|
+
export type VoiceSemanticTurnInput = {
|
|
3
|
+
audioLevel?: number;
|
|
4
|
+
lastFinalTranscript?: Transcript;
|
|
5
|
+
partialText: string;
|
|
6
|
+
silenceMs: number;
|
|
7
|
+
transcripts: Transcript[];
|
|
8
|
+
};
|
|
9
|
+
export type VoiceSemanticTurnVerdict = {
|
|
10
|
+
confidence?: number;
|
|
11
|
+
endOfTurn: boolean;
|
|
12
|
+
reason?: string;
|
|
13
|
+
};
|
|
14
|
+
export type VoiceSemanticTurnDetector = {
|
|
15
|
+
evaluate: (input: VoiceSemanticTurnInput) => Promise<VoiceSemanticTurnVerdict> | VoiceSemanticTurnVerdict;
|
|
16
|
+
};
|
|
17
|
+
export type CreatePunctuationSemanticTurnDetectorOptions = {
|
|
18
|
+
endPunctuation?: ReadonlyArray<string>;
|
|
19
|
+
fillerWords?: ReadonlyArray<string>;
|
|
20
|
+
minPartialWords?: number;
|
|
21
|
+
};
|
|
22
|
+
export declare const createPunctuationSemanticTurnDetector: (options?: CreatePunctuationSemanticTurnDetectorOptions) => VoiceSemanticTurnDetector;
|
|
23
|
+
export type CreateRegexSemanticTurnDetectorOptions = {
|
|
24
|
+
endPattern: RegExp;
|
|
25
|
+
minPartialWords?: number;
|
|
26
|
+
};
|
|
27
|
+
export declare const createRegexSemanticTurnDetector: (options: CreateRegexSemanticTurnDetectorOptions) => VoiceSemanticTurnDetector;
|
package/dist/testing/index.js
CHANGED
|
@@ -6754,6 +6754,18 @@ var createVoiceSession = (options) => {
|
|
|
6754
6754
|
session,
|
|
6755
6755
|
type: "turn.transcript"
|
|
6756
6756
|
});
|
|
6757
|
+
if (options.semanticTurnDetector) {
|
|
6758
|
+
const verdict = await Promise.resolve(options.semanticTurnDetector.evaluate({
|
|
6759
|
+
lastFinalTranscript: transcript,
|
|
6760
|
+
partialText: session.currentTurn.partialText,
|
|
6761
|
+
silenceMs: session.currentTurn.silenceStartedAt !== undefined ? Date.now() - session.currentTurn.silenceStartedAt : 0,
|
|
6762
|
+
transcripts: session.currentTurn.transcripts
|
|
6763
|
+
}));
|
|
6764
|
+
if (verdict.endOfTurn) {
|
|
6765
|
+
clearSilenceTimer();
|
|
6766
|
+
await requestTurnCommit("vendor");
|
|
6767
|
+
}
|
|
6768
|
+
}
|
|
6757
6769
|
};
|
|
6758
6770
|
const resumePendingTurnCommit = (session) => {
|
|
6759
6771
|
const pendingText = buildTurnText(session.currentTurn.transcripts, session.currentTurn.partialText, {
|
package/dist/types.d.ts
CHANGED
|
@@ -731,6 +731,7 @@ export type CreateVoiceSessionOptions<TContext = unknown, TSession extends Voice
|
|
|
731
731
|
provider?: string;
|
|
732
732
|
};
|
|
733
733
|
redact?: import("./redaction").VoiceTranscriptRedactor;
|
|
734
|
+
semanticTurnDetector?: import("./semanticTurn").VoiceSemanticTurnDetector;
|
|
734
735
|
reconnect: Required<VoiceReconnectConfig>;
|
|
735
736
|
phraseHints?: VoicePhraseHint[];
|
|
736
737
|
sessionMetadata?: Record<string, unknown>;
|