@absolutejs/voice 0.0.22-beta.517 → 0.0.22-beta.519
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 +2 -2
- package/dist/index.js +186 -153
- package/dist/ragTool.d.ts +2 -7
- package/dist/recordingRedaction.d.ts +30 -1
- package/dist/testing/index.js +9 -1
- package/dist/types.d.ts +8 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -75,8 +75,8 @@ export { createVoiceAIJudgeCompletion, createVoiceLLMJudge, } from "./llmJudge";
|
|
|
75
75
|
export type { CreateVoiceAIJudgeCompletionOptions, CreateVoiceLLMJudgeOptions, VoiceLLMJudge, VoiceLLMJudgeCompletion, VoiceLLMJudgeCriterionVerdict, VoiceLLMJudgeInput, VoiceLLMJudgeRubric, VoiceLLMJudgeRubricCriterion, VoiceLLMJudgeVerdict, } from "./llmJudge";
|
|
76
76
|
export { DEFAULT_VOICE_REDACTION_PATTERNS, createVoiceTranscriptRedactor, redactVoiceTranscript, } from "./redaction";
|
|
77
77
|
export type { CreateVoiceTranscriptRedactorOptions, VoiceRedactionPattern, VoiceTranscriptRedactor, } from "./redaction";
|
|
78
|
-
export { deriveVoiceRecordingRedactionRanges } from "./recordingRedaction";
|
|
79
|
-
export type { DeriveVoiceRecordingRedactionRangesInput, VoiceRecordingRedactionRange, } from "./recordingRedaction";
|
|
78
|
+
export { deriveVoiceRecordingRedactionRanges, redactVoiceRecording, } from "./recordingRedaction";
|
|
79
|
+
export type { DeriveVoiceRecordingRedactionRangesInput, RedactVoiceRecordingInput, RedactVoiceRecordingResult, VoiceRecordingRedactionRange, } from "./recordingRedaction";
|
|
80
80
|
export { DEFAULT_VOICE_PRICE_BOOK, createVoiceCostAccountant, } from "./costAccounting";
|
|
81
81
|
export type { CreateVoiceCostAccountantOptions, VoiceCostAccountant, VoiceCostBreakdown, VoiceCostLLMRecord, VoiceCostSTTRecord, VoiceCostTTSRecord, VoiceCostTelephonyRecord, VoicePriceBook, VoiceProviderRates, } from "./costAccounting";
|
|
82
82
|
export { describeVoiceAssistantMode, resolveVoiceAssistantMode, } from "./assistantMode";
|
package/dist/index.js
CHANGED
|
@@ -3769,7 +3769,8 @@ var setTurnResult = (session, turnId, input) => {
|
|
|
3769
3769
|
session.turns = session.turns.map((turn) => turn.id === turnId ? {
|
|
3770
3770
|
...turn,
|
|
3771
3771
|
assistantText: input.assistantText ?? turn.assistantText,
|
|
3772
|
-
result: input.result ?? turn.result
|
|
3772
|
+
result: input.result ?? turn.result,
|
|
3773
|
+
citations: input.citations && input.citations.length > 0 ? [...input.citations] : turn.citations
|
|
3773
3774
|
} : turn);
|
|
3774
3775
|
};
|
|
3775
3776
|
var ensureCallLifecycleState = (session) => {
|
|
@@ -5157,6 +5158,7 @@ var createVoiceSession = (options) => {
|
|
|
5157
5158
|
});
|
|
5158
5159
|
const output = {
|
|
5159
5160
|
assistantText: committedOutput?.assistantText,
|
|
5161
|
+
citations: committedOutput?.citations,
|
|
5160
5162
|
complete: committedOutput?.complete,
|
|
5161
5163
|
escalate: committedOutput?.escalate,
|
|
5162
5164
|
noAnswer: committedOutput?.noAnswer,
|
|
@@ -5164,6 +5166,12 @@ var createVoiceSession = (options) => {
|
|
|
5164
5166
|
transfer: committedOutput?.transfer,
|
|
5165
5167
|
voicemail: committedOutput?.voicemail
|
|
5166
5168
|
};
|
|
5169
|
+
if (output.citations && output.citations.length > 0) {
|
|
5170
|
+
const turnCitations = output.citations;
|
|
5171
|
+
await writeSession((currentSession) => {
|
|
5172
|
+
setTurnResult(currentSession, turn.id, { citations: turnCitations });
|
|
5173
|
+
});
|
|
5174
|
+
}
|
|
5167
5175
|
if (output?.assistantText) {
|
|
5168
5176
|
const assistantTextStartedAt = Date.now();
|
|
5169
5177
|
await writeSession((currentSession) => {
|
|
@@ -8733,6 +8741,159 @@ var assertVoiceCampaignDialerProofEvidence = (report, input = {}) => {
|
|
|
8733
8741
|
}
|
|
8734
8742
|
return assertion;
|
|
8735
8743
|
};
|
|
8744
|
+
// src/ragTool.ts
|
|
8745
|
+
var extractVoiceRAGCitations = (toolResults, toolName = "searchKnowledgeBase") => {
|
|
8746
|
+
const out = [];
|
|
8747
|
+
for (const entry of toolResults) {
|
|
8748
|
+
if (entry.toolName !== toolName) {
|
|
8749
|
+
continue;
|
|
8750
|
+
}
|
|
8751
|
+
const result = entry.result;
|
|
8752
|
+
const citations = result?.citations;
|
|
8753
|
+
if (!Array.isArray(citations)) {
|
|
8754
|
+
continue;
|
|
8755
|
+
}
|
|
8756
|
+
for (const citation of citations) {
|
|
8757
|
+
out.push({
|
|
8758
|
+
chunkId: citation.chunkId,
|
|
8759
|
+
score: citation.score,
|
|
8760
|
+
source: citation.source,
|
|
8761
|
+
title: citation.title
|
|
8762
|
+
});
|
|
8763
|
+
}
|
|
8764
|
+
}
|
|
8765
|
+
return out;
|
|
8766
|
+
};
|
|
8767
|
+
var DEFAULT_TOOL_NAME = "searchKnowledgeBase";
|
|
8768
|
+
var DEFAULT_DESCRIPTION = "Search the knowledge base and return short grounded citations. Use this whenever the caller asks a question that may be answered by indexed reference material.";
|
|
8769
|
+
var DEFAULT_TOP_K = 6;
|
|
8770
|
+
var DEFAULT_MAX_TOP_K = 20;
|
|
8771
|
+
var DEFAULT_MAX_CHUNK_CHARS = 320;
|
|
8772
|
+
var truncate = (value, limit) => {
|
|
8773
|
+
if (limit <= 0 || value.length <= limit)
|
|
8774
|
+
return value;
|
|
8775
|
+
return `${value.slice(0, Math.max(0, limit - 1)).trimEnd()}\u2026`;
|
|
8776
|
+
};
|
|
8777
|
+
var formatScore = (score) => {
|
|
8778
|
+
if (!Number.isFinite(score))
|
|
8779
|
+
return "n/a";
|
|
8780
|
+
return score.toFixed(3);
|
|
8781
|
+
};
|
|
8782
|
+
var buildDefaultCitationMessage = (citations, args, maxChunkChars) => {
|
|
8783
|
+
if (citations.length === 0) {
|
|
8784
|
+
return `No knowledge base results for "${args.query}".`;
|
|
8785
|
+
}
|
|
8786
|
+
const lines = citations.map((citation, index) => {
|
|
8787
|
+
const label = citation.title ?? citation.source ?? citation.chunkId;
|
|
8788
|
+
const text = truncate(citation.chunkText, maxChunkChars);
|
|
8789
|
+
return `${String(index + 1)}. ${label} (score ${formatScore(citation.score)}): ${text}`;
|
|
8790
|
+
});
|
|
8791
|
+
return [
|
|
8792
|
+
`Knowledge base results for "${args.query}":`,
|
|
8793
|
+
...lines
|
|
8794
|
+
].join(`
|
|
8795
|
+
`);
|
|
8796
|
+
};
|
|
8797
|
+
var filterAllowedFilterKeys = (filter, allowedKeys) => {
|
|
8798
|
+
if (!filter)
|
|
8799
|
+
return;
|
|
8800
|
+
if (!allowedKeys)
|
|
8801
|
+
return filter;
|
|
8802
|
+
const allowed = new Set(allowedKeys);
|
|
8803
|
+
const entries = Object.entries(filter).filter(([key]) => allowed.has(key));
|
|
8804
|
+
if (entries.length === 0)
|
|
8805
|
+
return;
|
|
8806
|
+
return Object.fromEntries(entries);
|
|
8807
|
+
};
|
|
8808
|
+
var mergeFilters = (...filters) => {
|
|
8809
|
+
const present = filters.filter((entry) => entry !== undefined);
|
|
8810
|
+
if (present.length === 0)
|
|
8811
|
+
return;
|
|
8812
|
+
return Object.assign({}, ...present);
|
|
8813
|
+
};
|
|
8814
|
+
var buildVoiceRAGToolParameters = (options) => {
|
|
8815
|
+
if (options.parameters)
|
|
8816
|
+
return options.parameters;
|
|
8817
|
+
const defaultTopK = options.topK ?? DEFAULT_TOP_K;
|
|
8818
|
+
const maxTopK = options.maxTopK ?? DEFAULT_MAX_TOP_K;
|
|
8819
|
+
const properties = {
|
|
8820
|
+
query: {
|
|
8821
|
+
description: "Natural-language question to look up in the knowledge base.",
|
|
8822
|
+
type: "string"
|
|
8823
|
+
},
|
|
8824
|
+
topK: {
|
|
8825
|
+
default: defaultTopK,
|
|
8826
|
+
description: `How many citations to return (1-${String(maxTopK)}).`,
|
|
8827
|
+
maximum: maxTopK,
|
|
8828
|
+
minimum: 1,
|
|
8829
|
+
type: "integer"
|
|
8830
|
+
}
|
|
8831
|
+
};
|
|
8832
|
+
if (options.allowedFilterKeys && options.allowedFilterKeys.length > 0) {
|
|
8833
|
+
properties.filter = {
|
|
8834
|
+
additionalProperties: false,
|
|
8835
|
+
description: "Optional metadata filter. Only keys listed here are honored: " + options.allowedFilterKeys.join(", "),
|
|
8836
|
+
properties: Object.fromEntries(options.allowedFilterKeys.map((key) => [key, {}])),
|
|
8837
|
+
type: "object"
|
|
8838
|
+
};
|
|
8839
|
+
}
|
|
8840
|
+
return {
|
|
8841
|
+
additionalProperties: false,
|
|
8842
|
+
properties,
|
|
8843
|
+
required: ["query"],
|
|
8844
|
+
type: "object"
|
|
8845
|
+
};
|
|
8846
|
+
};
|
|
8847
|
+
var createVoiceRAGTool = (collection, options = {}) => {
|
|
8848
|
+
const name = options.name ?? DEFAULT_TOOL_NAME;
|
|
8849
|
+
const description = options.description ?? DEFAULT_DESCRIPTION;
|
|
8850
|
+
const defaultTopK = options.topK ?? DEFAULT_TOP_K;
|
|
8851
|
+
const maxTopK = options.maxTopK ?? DEFAULT_MAX_TOP_K;
|
|
8852
|
+
const maxChunkChars = options.maxChunkChars ?? DEFAULT_MAX_CHUNK_CHARS;
|
|
8853
|
+
const parameters = buildVoiceRAGToolParameters(options);
|
|
8854
|
+
return createVoiceAgentTool({
|
|
8855
|
+
description,
|
|
8856
|
+
execute: async ({ args, context }) => {
|
|
8857
|
+
const query = typeof args?.query === "string" ? args.query.trim() : "";
|
|
8858
|
+
if (query.length === 0) {
|
|
8859
|
+
const empty = {
|
|
8860
|
+
citations: [],
|
|
8861
|
+
message: "Knowledge base search requires a non-empty query.",
|
|
8862
|
+
query: "",
|
|
8863
|
+
topK: 0
|
|
8864
|
+
};
|
|
8865
|
+
return empty;
|
|
8866
|
+
}
|
|
8867
|
+
const requestedTopK = typeof args?.topK === "number" && Number.isFinite(args.topK) ? Math.min(maxTopK, Math.max(1, Math.floor(args.topK))) : defaultTopK;
|
|
8868
|
+
const llmFilter = filterAllowedFilterKeys(args?.filter, options.allowedFilterKeys);
|
|
8869
|
+
const fixedFilter = typeof options.fixedFilter === "function" ? options.fixedFilter({ context }) : options.fixedFilter;
|
|
8870
|
+
const filter = mergeFilters(fixedFilter, llmFilter);
|
|
8871
|
+
const rawResults = await collection.search({
|
|
8872
|
+
filter,
|
|
8873
|
+
query,
|
|
8874
|
+
scoreThreshold: options.scoreThreshold,
|
|
8875
|
+
topK: requestedTopK
|
|
8876
|
+
});
|
|
8877
|
+
const citations = Array.from(rawResults).slice(0, requestedTopK);
|
|
8878
|
+
const formatter = options.formatResult ? options.formatResult : (entries, innerArgs) => buildDefaultCitationMessage(entries, innerArgs, maxChunkChars);
|
|
8879
|
+
const message = formatter(citations, {
|
|
8880
|
+
filter,
|
|
8881
|
+
query,
|
|
8882
|
+
topK: requestedTopK
|
|
8883
|
+
});
|
|
8884
|
+
return {
|
|
8885
|
+
citations,
|
|
8886
|
+
message,
|
|
8887
|
+
query,
|
|
8888
|
+
topK: requestedTopK
|
|
8889
|
+
};
|
|
8890
|
+
},
|
|
8891
|
+
name,
|
|
8892
|
+
parameters,
|
|
8893
|
+
resultToMessage: options.resultToMessage ?? ((result) => result.message)
|
|
8894
|
+
});
|
|
8895
|
+
};
|
|
8896
|
+
|
|
8736
8897
|
// src/agent.ts
|
|
8737
8898
|
var normalizeText3 = (value) => typeof value === "string" ? value.trim() : "";
|
|
8738
8899
|
var toErrorMessage3 = (error) => error instanceof Error ? error.message : String(error);
|
|
@@ -9106,9 +9267,11 @@ var createVoiceAgent = (options) => {
|
|
|
9106
9267
|
turn: input.turn,
|
|
9107
9268
|
type: "agent.result"
|
|
9108
9269
|
});
|
|
9270
|
+
const citations = extractVoiceRAGCitations(toolResults);
|
|
9109
9271
|
return {
|
|
9110
9272
|
agentId: options.id,
|
|
9111
9273
|
assistantText: output.assistantText,
|
|
9274
|
+
...citations.length > 0 ? { citations } : {},
|
|
9112
9275
|
complete: output.complete,
|
|
9113
9276
|
escalate: output.escalate,
|
|
9114
9277
|
handoff: output.handoff,
|
|
@@ -35409,6 +35572,10 @@ var createVoiceTranscriptRedactor = (options = {}) => {
|
|
|
35409
35572
|
};
|
|
35410
35573
|
var redactVoiceTranscript = (transcript, patterns = DEFAULT_VOICE_REDACTION_PATTERNS) => createVoiceTranscriptRedactor({ patterns })(transcript);
|
|
35411
35574
|
// src/recordingRedaction.ts
|
|
35575
|
+
import {
|
|
35576
|
+
applyAudioRedaction,
|
|
35577
|
+
mergeAudioRedactionRanges
|
|
35578
|
+
} from "@absolutejs/media";
|
|
35412
35579
|
var matchesAnyPattern = (text, patterns) => {
|
|
35413
35580
|
for (const pattern of patterns) {
|
|
35414
35581
|
pattern.regex.lastIndex = 0;
|
|
@@ -35446,6 +35613,23 @@ var deriveVoiceRecordingRedactionRanges = (input) => {
|
|
|
35446
35613
|
}
|
|
35447
35614
|
return out;
|
|
35448
35615
|
};
|
|
35616
|
+
var redactVoiceRecording = (input) => {
|
|
35617
|
+
const derived = deriveVoiceRecordingRedactionRanges({
|
|
35618
|
+
transcripts: input.transcripts,
|
|
35619
|
+
...input.recordingStartedAtEpochMs !== undefined ? { recordingStartedAtEpochMs: input.recordingStartedAtEpochMs } : {},
|
|
35620
|
+
...input.paddingMs !== undefined ? { paddingMs: input.paddingMs } : {},
|
|
35621
|
+
...input.patterns !== undefined ? { patterns: input.patterns } : {}
|
|
35622
|
+
});
|
|
35623
|
+
const ranges = mergeAudioRedactionRanges(derived);
|
|
35624
|
+
const bytes = applyAudioRedaction(input.pcm, input.format, ranges, {
|
|
35625
|
+
...input.fill !== undefined ? { fill: input.fill } : {}
|
|
35626
|
+
});
|
|
35627
|
+
return {
|
|
35628
|
+
bytes,
|
|
35629
|
+
ranges,
|
|
35630
|
+
redactedCount: ranges.length
|
|
35631
|
+
};
|
|
35632
|
+
};
|
|
35449
35633
|
// src/costAccounting.ts
|
|
35450
35634
|
var DEFAULT_VOICE_PRICE_BOOK = {
|
|
35451
35635
|
"anthropic:claude-opus-4-5": {
|
|
@@ -36320,158 +36504,6 @@ var createMonologueAMDDetector = (options = {}) => {
|
|
|
36320
36504
|
intervalMs: options.intervalMs ?? 1000
|
|
36321
36505
|
};
|
|
36322
36506
|
};
|
|
36323
|
-
// src/ragTool.ts
|
|
36324
|
-
var extractVoiceRAGCitations = (toolResults, toolName = "searchKnowledgeBase") => {
|
|
36325
|
-
const out = [];
|
|
36326
|
-
for (const entry of toolResults) {
|
|
36327
|
-
if (entry.toolName !== toolName) {
|
|
36328
|
-
continue;
|
|
36329
|
-
}
|
|
36330
|
-
const result = entry.result;
|
|
36331
|
-
const citations = result?.citations;
|
|
36332
|
-
if (!Array.isArray(citations)) {
|
|
36333
|
-
continue;
|
|
36334
|
-
}
|
|
36335
|
-
for (const citation of citations) {
|
|
36336
|
-
out.push({
|
|
36337
|
-
chunkId: citation.chunkId,
|
|
36338
|
-
score: citation.score,
|
|
36339
|
-
source: citation.source,
|
|
36340
|
-
title: citation.title
|
|
36341
|
-
});
|
|
36342
|
-
}
|
|
36343
|
-
}
|
|
36344
|
-
return out;
|
|
36345
|
-
};
|
|
36346
|
-
var DEFAULT_TOOL_NAME = "searchKnowledgeBase";
|
|
36347
|
-
var DEFAULT_DESCRIPTION = "Search the knowledge base and return short grounded citations. Use this whenever the caller asks a question that may be answered by indexed reference material.";
|
|
36348
|
-
var DEFAULT_TOP_K = 6;
|
|
36349
|
-
var DEFAULT_MAX_TOP_K = 20;
|
|
36350
|
-
var DEFAULT_MAX_CHUNK_CHARS = 320;
|
|
36351
|
-
var truncate = (value, limit) => {
|
|
36352
|
-
if (limit <= 0 || value.length <= limit)
|
|
36353
|
-
return value;
|
|
36354
|
-
return `${value.slice(0, Math.max(0, limit - 1)).trimEnd()}\u2026`;
|
|
36355
|
-
};
|
|
36356
|
-
var formatScore = (score) => {
|
|
36357
|
-
if (!Number.isFinite(score))
|
|
36358
|
-
return "n/a";
|
|
36359
|
-
return score.toFixed(3);
|
|
36360
|
-
};
|
|
36361
|
-
var buildDefaultCitationMessage = (citations, args, maxChunkChars) => {
|
|
36362
|
-
if (citations.length === 0) {
|
|
36363
|
-
return `No knowledge base results for "${args.query}".`;
|
|
36364
|
-
}
|
|
36365
|
-
const lines = citations.map((citation, index) => {
|
|
36366
|
-
const label = citation.title ?? citation.source ?? citation.chunkId;
|
|
36367
|
-
const text = truncate(citation.chunkText, maxChunkChars);
|
|
36368
|
-
return `${String(index + 1)}. ${label} (score ${formatScore(citation.score)}): ${text}`;
|
|
36369
|
-
});
|
|
36370
|
-
return [
|
|
36371
|
-
`Knowledge base results for "${args.query}":`,
|
|
36372
|
-
...lines
|
|
36373
|
-
].join(`
|
|
36374
|
-
`);
|
|
36375
|
-
};
|
|
36376
|
-
var filterAllowedFilterKeys = (filter, allowedKeys) => {
|
|
36377
|
-
if (!filter)
|
|
36378
|
-
return;
|
|
36379
|
-
if (!allowedKeys)
|
|
36380
|
-
return filter;
|
|
36381
|
-
const allowed = new Set(allowedKeys);
|
|
36382
|
-
const entries = Object.entries(filter).filter(([key]) => allowed.has(key));
|
|
36383
|
-
if (entries.length === 0)
|
|
36384
|
-
return;
|
|
36385
|
-
return Object.fromEntries(entries);
|
|
36386
|
-
};
|
|
36387
|
-
var mergeFilters = (...filters) => {
|
|
36388
|
-
const present = filters.filter((entry) => entry !== undefined);
|
|
36389
|
-
if (present.length === 0)
|
|
36390
|
-
return;
|
|
36391
|
-
return Object.assign({}, ...present);
|
|
36392
|
-
};
|
|
36393
|
-
var buildVoiceRAGToolParameters = (options) => {
|
|
36394
|
-
if (options.parameters)
|
|
36395
|
-
return options.parameters;
|
|
36396
|
-
const defaultTopK = options.topK ?? DEFAULT_TOP_K;
|
|
36397
|
-
const maxTopK = options.maxTopK ?? DEFAULT_MAX_TOP_K;
|
|
36398
|
-
const properties = {
|
|
36399
|
-
query: {
|
|
36400
|
-
description: "Natural-language question to look up in the knowledge base.",
|
|
36401
|
-
type: "string"
|
|
36402
|
-
},
|
|
36403
|
-
topK: {
|
|
36404
|
-
default: defaultTopK,
|
|
36405
|
-
description: `How many citations to return (1-${String(maxTopK)}).`,
|
|
36406
|
-
maximum: maxTopK,
|
|
36407
|
-
minimum: 1,
|
|
36408
|
-
type: "integer"
|
|
36409
|
-
}
|
|
36410
|
-
};
|
|
36411
|
-
if (options.allowedFilterKeys && options.allowedFilterKeys.length > 0) {
|
|
36412
|
-
properties.filter = {
|
|
36413
|
-
additionalProperties: false,
|
|
36414
|
-
description: "Optional metadata filter. Only keys listed here are honored: " + options.allowedFilterKeys.join(", "),
|
|
36415
|
-
properties: Object.fromEntries(options.allowedFilterKeys.map((key) => [key, {}])),
|
|
36416
|
-
type: "object"
|
|
36417
|
-
};
|
|
36418
|
-
}
|
|
36419
|
-
return {
|
|
36420
|
-
additionalProperties: false,
|
|
36421
|
-
properties,
|
|
36422
|
-
required: ["query"],
|
|
36423
|
-
type: "object"
|
|
36424
|
-
};
|
|
36425
|
-
};
|
|
36426
|
-
var createVoiceRAGTool = (collection, options = {}) => {
|
|
36427
|
-
const name = options.name ?? DEFAULT_TOOL_NAME;
|
|
36428
|
-
const description = options.description ?? DEFAULT_DESCRIPTION;
|
|
36429
|
-
const defaultTopK = options.topK ?? DEFAULT_TOP_K;
|
|
36430
|
-
const maxTopK = options.maxTopK ?? DEFAULT_MAX_TOP_K;
|
|
36431
|
-
const maxChunkChars = options.maxChunkChars ?? DEFAULT_MAX_CHUNK_CHARS;
|
|
36432
|
-
const parameters = buildVoiceRAGToolParameters(options);
|
|
36433
|
-
return createVoiceAgentTool({
|
|
36434
|
-
description,
|
|
36435
|
-
execute: async ({ args, context }) => {
|
|
36436
|
-
const query = typeof args?.query === "string" ? args.query.trim() : "";
|
|
36437
|
-
if (query.length === 0) {
|
|
36438
|
-
const empty = {
|
|
36439
|
-
citations: [],
|
|
36440
|
-
message: "Knowledge base search requires a non-empty query.",
|
|
36441
|
-
query: "",
|
|
36442
|
-
topK: 0
|
|
36443
|
-
};
|
|
36444
|
-
return empty;
|
|
36445
|
-
}
|
|
36446
|
-
const requestedTopK = typeof args?.topK === "number" && Number.isFinite(args.topK) ? Math.min(maxTopK, Math.max(1, Math.floor(args.topK))) : defaultTopK;
|
|
36447
|
-
const llmFilter = filterAllowedFilterKeys(args?.filter, options.allowedFilterKeys);
|
|
36448
|
-
const fixedFilter = typeof options.fixedFilter === "function" ? options.fixedFilter({ context }) : options.fixedFilter;
|
|
36449
|
-
const filter = mergeFilters(fixedFilter, llmFilter);
|
|
36450
|
-
const rawResults = await collection.search({
|
|
36451
|
-
filter,
|
|
36452
|
-
query,
|
|
36453
|
-
scoreThreshold: options.scoreThreshold,
|
|
36454
|
-
topK: requestedTopK
|
|
36455
|
-
});
|
|
36456
|
-
const citations = Array.from(rawResults).slice(0, requestedTopK);
|
|
36457
|
-
const formatter = options.formatResult ? options.formatResult : (entries, innerArgs) => buildDefaultCitationMessage(entries, innerArgs, maxChunkChars);
|
|
36458
|
-
const message = formatter(citations, {
|
|
36459
|
-
filter,
|
|
36460
|
-
query,
|
|
36461
|
-
topK: requestedTopK
|
|
36462
|
-
});
|
|
36463
|
-
return {
|
|
36464
|
-
citations,
|
|
36465
|
-
message,
|
|
36466
|
-
query,
|
|
36467
|
-
topK: requestedTopK
|
|
36468
|
-
};
|
|
36469
|
-
},
|
|
36470
|
-
name,
|
|
36471
|
-
parameters,
|
|
36472
|
-
resultToMessage: options.resultToMessage ?? ((result) => result.message)
|
|
36473
|
-
});
|
|
36474
|
-
};
|
|
36475
36507
|
// src/agentTools.ts
|
|
36476
36508
|
var createVoiceEndCallTool = (options = {}) => createVoiceAgentTool({
|
|
36477
36509
|
description: options.description ?? "End the call gracefully. Call this only when the conversation is complete or the caller asks to hang up.",
|
|
@@ -51767,6 +51799,7 @@ export {
|
|
|
51767
51799
|
redactVoiceTraceText,
|
|
51768
51800
|
redactVoiceTraceEvents,
|
|
51769
51801
|
redactVoiceTraceEvent,
|
|
51802
|
+
redactVoiceRecording,
|
|
51770
51803
|
redactVoiceAuditEvents,
|
|
51771
51804
|
redactVoiceAuditEvent,
|
|
51772
51805
|
recordVoiceWorkflowContractTrace,
|
package/dist/ragTool.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type VoiceAgentTool } from "./agent";
|
|
2
|
-
import type { VoiceSessionRecord } from "./types";
|
|
2
|
+
import type { VoiceSessionRecord, VoiceTurnCitation } from "./types";
|
|
3
3
|
export type VoiceRAGQueryResult = {
|
|
4
4
|
chunkId: string;
|
|
5
5
|
chunkText: string;
|
|
@@ -29,12 +29,7 @@ export type VoiceRAGToolResult = {
|
|
|
29
29
|
query: string;
|
|
30
30
|
topK: number;
|
|
31
31
|
};
|
|
32
|
-
export type VoiceRAGCitationSummary =
|
|
33
|
-
chunkId: string;
|
|
34
|
-
score: number;
|
|
35
|
-
source?: string;
|
|
36
|
-
title?: string;
|
|
37
|
-
};
|
|
32
|
+
export type VoiceRAGCitationSummary = VoiceTurnCitation;
|
|
38
33
|
export declare const extractVoiceRAGCitations: (toolResults: ReadonlyArray<{
|
|
39
34
|
result?: unknown;
|
|
40
35
|
toolName: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AudioRedactionFill } from "@absolutejs/media";
|
|
2
|
+
import type { AudioFormat, Transcript } from "./types";
|
|
2
3
|
import { type VoiceRedactionPattern } from "./redaction";
|
|
3
4
|
export type VoiceRecordingRedactionRange = {
|
|
4
5
|
endMs: number;
|
|
@@ -16,3 +17,31 @@ export type DeriveVoiceRecordingRedactionRangesInput = {
|
|
|
16
17
|
transcripts: ReadonlyArray<Transcript>;
|
|
17
18
|
};
|
|
18
19
|
export declare const deriveVoiceRecordingRedactionRanges: (input: DeriveVoiceRecordingRedactionRangesInput) => VoiceRecordingRedactionRange[];
|
|
20
|
+
export type RedactVoiceRecordingInput = {
|
|
21
|
+
/** Raw pcm_s16le bytes of the recorded artifact. */
|
|
22
|
+
pcm: ArrayBuffer | ArrayBufferView;
|
|
23
|
+
/** Format of the recording (must be raw pcm_s16le). */
|
|
24
|
+
format: AudioFormat;
|
|
25
|
+
/** Final transcripts with timing, scanned for sensitive content. */
|
|
26
|
+
transcripts: ReadonlyArray<Transcript>;
|
|
27
|
+
recordingStartedAtEpochMs?: number;
|
|
28
|
+
paddingMs?: number;
|
|
29
|
+
patterns?: ReadonlyArray<VoiceRedactionPattern>;
|
|
30
|
+
/** Bleep style — silence (default) or a tone. */
|
|
31
|
+
fill?: AudioRedactionFill;
|
|
32
|
+
};
|
|
33
|
+
export type RedactVoiceRecordingResult = {
|
|
34
|
+
/** The redacted pcm_s16le bytes. */
|
|
35
|
+
bytes: Uint8Array;
|
|
36
|
+
/** The merged ranges that were bleeped. */
|
|
37
|
+
ranges: VoiceRecordingRedactionRange[];
|
|
38
|
+
/** How many ranges were redacted. */
|
|
39
|
+
redactedCount: number;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* End-to-end recording redaction: derives sensitive ranges from final
|
|
43
|
+
* transcripts, merges overlaps, and applies the audio bleep via
|
|
44
|
+
* `@absolutejs/media`'s `applyAudioRedaction`. Returns the redacted bytes
|
|
45
|
+
* ready to re-store in place of the original artifact.
|
|
46
|
+
*/
|
|
47
|
+
export declare const redactVoiceRecording: (input: RedactVoiceRecordingInput) => RedactVoiceRecordingResult;
|
package/dist/testing/index.js
CHANGED
|
@@ -5628,7 +5628,8 @@ var setTurnResult = (session, turnId, input) => {
|
|
|
5628
5628
|
session.turns = session.turns.map((turn) => turn.id === turnId ? {
|
|
5629
5629
|
...turn,
|
|
5630
5630
|
assistantText: input.assistantText ?? turn.assistantText,
|
|
5631
|
-
result: input.result ?? turn.result
|
|
5631
|
+
result: input.result ?? turn.result,
|
|
5632
|
+
citations: input.citations && input.citations.length > 0 ? [...input.citations] : turn.citations
|
|
5632
5633
|
} : turn);
|
|
5633
5634
|
};
|
|
5634
5635
|
var ensureCallLifecycleState = (session) => {
|
|
@@ -7016,6 +7017,7 @@ var createVoiceSession = (options) => {
|
|
|
7016
7017
|
});
|
|
7017
7018
|
const output = {
|
|
7018
7019
|
assistantText: committedOutput?.assistantText,
|
|
7020
|
+
citations: committedOutput?.citations,
|
|
7019
7021
|
complete: committedOutput?.complete,
|
|
7020
7022
|
escalate: committedOutput?.escalate,
|
|
7021
7023
|
noAnswer: committedOutput?.noAnswer,
|
|
@@ -7023,6 +7025,12 @@ var createVoiceSession = (options) => {
|
|
|
7023
7025
|
transfer: committedOutput?.transfer,
|
|
7024
7026
|
voicemail: committedOutput?.voicemail
|
|
7025
7027
|
};
|
|
7028
|
+
if (output.citations && output.citations.length > 0) {
|
|
7029
|
+
const turnCitations = output.citations;
|
|
7030
|
+
await writeSession((currentSession) => {
|
|
7031
|
+
setTurnResult(currentSession, turn.id, { citations: turnCitations });
|
|
7032
|
+
});
|
|
7033
|
+
}
|
|
7026
7034
|
if (output?.assistantText) {
|
|
7027
7035
|
const assistantTextStartedAt = Date.now();
|
|
7028
7036
|
await writeSession((currentSession) => {
|
package/dist/types.d.ts
CHANGED
|
@@ -247,6 +247,12 @@ export type VoiceReconnectClientState = {
|
|
|
247
247
|
nextAttemptAt?: number;
|
|
248
248
|
status: VoiceReconnectClientStatus;
|
|
249
249
|
};
|
|
250
|
+
export type VoiceTurnCitation = {
|
|
251
|
+
chunkId: string;
|
|
252
|
+
score: number;
|
|
253
|
+
source?: string;
|
|
254
|
+
title?: string;
|
|
255
|
+
};
|
|
250
256
|
export type VoiceTurnRecord<TResult = unknown> = {
|
|
251
257
|
id: string;
|
|
252
258
|
text: string;
|
|
@@ -254,6 +260,7 @@ export type VoiceTurnRecord<TResult = unknown> = {
|
|
|
254
260
|
transcripts: Transcript[];
|
|
255
261
|
assistantText?: string;
|
|
256
262
|
attachments?: import("./agent").VoiceAgentMessageAttachment[];
|
|
263
|
+
citations?: VoiceTurnCitation[];
|
|
257
264
|
committedAt: number;
|
|
258
265
|
result?: TResult;
|
|
259
266
|
};
|
|
@@ -502,6 +509,7 @@ export type VoiceRouteResult<TResult = unknown> = {
|
|
|
502
509
|
complete?: boolean;
|
|
503
510
|
result?: TResult;
|
|
504
511
|
assistantText?: string;
|
|
512
|
+
citations?: ReadonlyArray<VoiceTurnCitation>;
|
|
505
513
|
transfer?: {
|
|
506
514
|
metadata?: Record<string, unknown>;
|
|
507
515
|
reason?: string;
|