@hiper2d/ai-agents 0.1.5 → 0.2.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/README.md +18 -0
- package/dist/index.d.mts +219 -1
- package/dist/index.d.ts +219 -1
- package/dist/index.js +313 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +294 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -44,10 +44,12 @@ __export(index_exports, {
|
|
|
44
44
|
DeepSeekV2Agent: () => DeepSeekV2Agent,
|
|
45
45
|
FUGU_REASONING_EFFORTS: () => FUGU_REASONING_EFFORTS,
|
|
46
46
|
FuguAgent: () => FuguAgent,
|
|
47
|
+
GEMINI_AUDIO_TOKENS_PER_SECOND: () => GEMINI_AUDIO_TOKENS_PER_SECOND,
|
|
47
48
|
GEMINI_REASONING_EFFORTS: () => GEMINI_REASONING_EFFORTS,
|
|
48
49
|
GLM_REASONING_EFFORTS: () => GLM_REASONING_EFFORTS,
|
|
49
50
|
GlmAgent: () => GlmAgent,
|
|
50
51
|
GoogleAgent: () => GoogleAgent,
|
|
52
|
+
GoogleVoiceAgent: () => GoogleVoiceAgent,
|
|
51
53
|
Gpt5Agent: () => Gpt5Agent,
|
|
52
54
|
GrokAgent: () => GrokAgent,
|
|
53
55
|
KimiAgent: () => KimiAgent,
|
|
@@ -65,23 +67,35 @@ __export(index_exports, {
|
|
|
65
67
|
ModelRefusalError: () => ModelRefusalError,
|
|
66
68
|
ModelUnavailableError: () => ModelUnavailableError,
|
|
67
69
|
OPENAI_REASONING_EFFORTS: () => OPENAI_REASONING_EFFORTS,
|
|
70
|
+
OpenAiVoiceAgent: () => OpenAiVoiceAgent,
|
|
68
71
|
QwenAgent: () => QwenAgent,
|
|
69
72
|
REASONING_EFFORT_SCALE: () => REASONING_EFFORT_SCALE,
|
|
73
|
+
SUPPORTED_VOICE_PROVIDERS: () => SUPPORTED_VOICE_PROVIDERS,
|
|
70
74
|
SupportedAiKeyNames: () => SupportedAiKeyNames,
|
|
71
75
|
SupportedAiModels: () => SupportedAiModels,
|
|
76
|
+
VOICE_MODEL_CONSTANTS: () => VOICE_MODEL_CONSTANTS,
|
|
77
|
+
VOICE_MODEL_PRICING: () => VOICE_MODEL_PRICING,
|
|
78
|
+
VOICE_PROVIDER_API_KEY: () => VOICE_PROVIDER_API_KEY,
|
|
79
|
+
VoiceAgentFactory: () => VoiceAgentFactory,
|
|
72
80
|
ZodSchemaConverter: () => ZodSchemaConverter,
|
|
81
|
+
buildGoogleTtsPrompt: () => buildGoogleTtsPrompt,
|
|
73
82
|
calculateAnthropicCost: () => calculateAnthropicCost,
|
|
74
83
|
calculateCost: () => calculateCost,
|
|
75
84
|
calculateDeepSeekCost: () => calculateDeepSeekCost,
|
|
85
|
+
calculateGeminiSttCost: () => calculateGeminiSttCost,
|
|
86
|
+
calculateGeminiTtsCost: () => calculateGeminiTtsCost,
|
|
76
87
|
calculateGoogleCost: () => calculateGoogleCost,
|
|
77
88
|
calculateGrokCost: () => calculateGrokCost,
|
|
78
89
|
calculateKimiCost: () => calculateKimiCost,
|
|
79
90
|
calculateMistralCost: () => calculateMistralCost,
|
|
80
91
|
calculateModelCost: () => calculateModelCost,
|
|
81
92
|
calculateOpenAICost: () => calculateOpenAICost,
|
|
93
|
+
calculateOpenAiSttCost: () => calculateOpenAiSttCost,
|
|
94
|
+
calculateOpenAiTtsCost: () => calculateOpenAiTtsCost,
|
|
82
95
|
clampReasoningEffort: () => clampReasoningEffort,
|
|
83
96
|
cleanResponse: () => cleanResponse,
|
|
84
97
|
createCatalog: () => createCatalog,
|
|
98
|
+
createVoiceAgent: () => createVoiceAgent,
|
|
85
99
|
extractAnthropicTokenUsage: () => extractAnthropicTokenUsage,
|
|
86
100
|
extractAnthropicTokenUsageFromResponse: () => extractTokenUsageFromResponse5,
|
|
87
101
|
extractDeepSeekTokenUsage: () => extractDeepSeekTokenUsage,
|
|
@@ -99,6 +113,8 @@ __export(index_exports, {
|
|
|
99
113
|
extractOpenAITokenUsageFromResponse: () => extractTokenUsageFromResponse,
|
|
100
114
|
extractTokenUsage: () => extractTokenUsage,
|
|
101
115
|
extractUsageAndCalculateCost: () => extractUsageAndCalculateCost,
|
|
116
|
+
generateGoogleTtsAudio: () => generateGoogleTtsAudio,
|
|
117
|
+
generateOpenAiTtsAudio: () => generateOpenAiTtsAudio,
|
|
102
118
|
generateSchemaInstructions: () => generateSchemaInstructions,
|
|
103
119
|
getModelConfigByApiName: () => getModelConfigByApiName,
|
|
104
120
|
getModelDisplayName: () => getModelDisplayName,
|
|
@@ -115,6 +131,7 @@ __export(index_exports, {
|
|
|
115
131
|
modelIsFast: () => modelIsFast,
|
|
116
132
|
needsPromptBasedSchema: () => needsPromptBasedSchema,
|
|
117
133
|
parseAndValidateLlmJson: () => parseAndValidateLlmJson,
|
|
134
|
+
pcmToWav: () => pcmToWav,
|
|
118
135
|
safeValidateResponse: () => safeValidateResponse,
|
|
119
136
|
setLlmLogger: () => setLlmLogger,
|
|
120
137
|
stableHashHex: () => stableHashHex,
|
|
@@ -126,6 +143,8 @@ __export(index_exports, {
|
|
|
126
143
|
toGeminiEffort: () => toGeminiEffort,
|
|
127
144
|
toGlmEffort: () => toGlmEffort,
|
|
128
145
|
toOpenAIEffort: () => toOpenAIEffort,
|
|
146
|
+
transcribeWithGemini: () => transcribeWithGemini,
|
|
147
|
+
transcribeWithOpenAi: () => transcribeWithOpenAi,
|
|
129
148
|
validateResponse: () => validateResponse
|
|
130
149
|
});
|
|
131
150
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -1750,6 +1769,263 @@ function extractTokenUsageFromResponse7(response) {
|
|
|
1750
1769
|
return extractMistralTokenUsage(response);
|
|
1751
1770
|
}
|
|
1752
1771
|
|
|
1772
|
+
// src/voice/voice-catalog.ts
|
|
1773
|
+
var VOICE_MODEL_CONSTANTS = {
|
|
1774
|
+
OPENAI_TTS: "gpt-4o-mini-tts",
|
|
1775
|
+
OPENAI_STT: "whisper-1",
|
|
1776
|
+
// ai.google.dev/gemini-api/docs/speech-generation
|
|
1777
|
+
GOOGLE_TTS: "gemini-3.1-flash-tts-preview",
|
|
1778
|
+
// ai.google.dev/gemini-api/docs/transcribe — Interactions API only (see google-stt.ts)
|
|
1779
|
+
GOOGLE_STT: "gemini-3.5-transcribe"
|
|
1780
|
+
};
|
|
1781
|
+
var SUPPORTED_VOICE_PROVIDERS = ["openai", "google"];
|
|
1782
|
+
var VOICE_PROVIDER_API_KEY = {
|
|
1783
|
+
openai: API_KEY_CONSTANTS.OPENAI,
|
|
1784
|
+
google: API_KEY_CONSTANTS.GOOGLE
|
|
1785
|
+
};
|
|
1786
|
+
var VOICE_MODEL_PRICING = {
|
|
1787
|
+
[VOICE_MODEL_CONSTANTS.OPENAI_TTS]: { pricePerMillionCharacters: 15 },
|
|
1788
|
+
[VOICE_MODEL_CONSTANTS.OPENAI_STT]: { pricePerMinute: 6e-3 },
|
|
1789
|
+
// Measured 2026-09-05: ~32 audio tokens per second of speech, so a 15-second
|
|
1790
|
+
// line is ~$0.01 — about 3-5x an OpenAI line of the same length.
|
|
1791
|
+
[VOICE_MODEL_CONSTANTS.GOOGLE_TTS]: { textInputPricePerM: 1, audioOutputPricePerM: 20 },
|
|
1792
|
+
// ~25 audio tokens per second in, ~175 text tokens per minute out: ≈ $0.005/min.
|
|
1793
|
+
[VOICE_MODEL_CONSTANTS.GOOGLE_STT]: { audioInputPricePerM: 2, textOutputPricePerM: 12 }
|
|
1794
|
+
};
|
|
1795
|
+
|
|
1796
|
+
// src/voice/voice-pricing.ts
|
|
1797
|
+
function roundUSD(value) {
|
|
1798
|
+
return parseFloat((value || 0).toFixed(6));
|
|
1799
|
+
}
|
|
1800
|
+
function calculateOpenAiTtsCost(characterCount) {
|
|
1801
|
+
const rate = VOICE_MODEL_PRICING[VOICE_MODEL_CONSTANTS.OPENAI_TTS]?.pricePerMillionCharacters ?? 0;
|
|
1802
|
+
if (!characterCount || characterCount <= 0 || rate <= 0) return 0;
|
|
1803
|
+
return roundUSD(characterCount / 1e6 * rate);
|
|
1804
|
+
}
|
|
1805
|
+
function calculateOpenAiSttCost(durationSeconds) {
|
|
1806
|
+
const rate = VOICE_MODEL_PRICING[VOICE_MODEL_CONSTANTS.OPENAI_STT]?.pricePerMinute ?? 0;
|
|
1807
|
+
if (!durationSeconds || durationSeconds <= 0 || rate <= 0) return 0;
|
|
1808
|
+
return roundUSD(durationSeconds / 60 * rate);
|
|
1809
|
+
}
|
|
1810
|
+
function calculateGeminiTtsCost(usage) {
|
|
1811
|
+
const pricing = VOICE_MODEL_PRICING[VOICE_MODEL_CONSTANTS.GOOGLE_TTS];
|
|
1812
|
+
return tokenPairCost(usage, pricing?.textInputPricePerM ?? 0, pricing?.audioOutputPricePerM ?? 0);
|
|
1813
|
+
}
|
|
1814
|
+
function calculateGeminiSttCost(usage) {
|
|
1815
|
+
const pricing = VOICE_MODEL_PRICING[VOICE_MODEL_CONSTANTS.GOOGLE_STT];
|
|
1816
|
+
return tokenPairCost(usage, pricing?.audioInputPricePerM ?? 0, pricing?.textOutputPricePerM ?? 0);
|
|
1817
|
+
}
|
|
1818
|
+
function tokenPairCost(usage, inputRate, outputRate) {
|
|
1819
|
+
const inputTokens = Math.max(0, usage.inputTokens || 0);
|
|
1820
|
+
const outputTokens = Math.max(0, usage.outputTokens || 0);
|
|
1821
|
+
return inputTokens / 1e6 * inputRate + outputTokens / 1e6 * outputRate;
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
// src/voice/openai-tts.ts
|
|
1825
|
+
var import_openai = require("openai");
|
|
1826
|
+
async function generateOpenAiTtsAudio(text, apiKey, options = {}) {
|
|
1827
|
+
const client = new import_openai.OpenAI({ apiKey });
|
|
1828
|
+
const speechOptions = {
|
|
1829
|
+
model: VOICE_MODEL_CONSTANTS.OPENAI_TTS,
|
|
1830
|
+
voice: options.voice || "alloy",
|
|
1831
|
+
input: text,
|
|
1832
|
+
speed: options.speed || 1,
|
|
1833
|
+
response_format: options.format || "wav"
|
|
1834
|
+
};
|
|
1835
|
+
if (options.instructions) {
|
|
1836
|
+
speechOptions.instructions = options.instructions;
|
|
1837
|
+
}
|
|
1838
|
+
const response = await client.audio.speech.create(speechOptions);
|
|
1839
|
+
return await response.arrayBuffer();
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
// src/voice/openai-stt.ts
|
|
1843
|
+
var import_openai2 = require("openai");
|
|
1844
|
+
async function transcribeWithOpenAi(audioBuffer, apiKey, options = {}) {
|
|
1845
|
+
const client = new import_openai2.OpenAI({ apiKey });
|
|
1846
|
+
const audioFile = new File([new Uint8Array(audioBuffer)], options.fileName || "audio.webm", { type: options.mimeType || "audio/webm" });
|
|
1847
|
+
const transcription = await client.audio.transcriptions.create({
|
|
1848
|
+
file: audioFile,
|
|
1849
|
+
model: VOICE_MODEL_CONSTANTS.OPENAI_STT,
|
|
1850
|
+
language: options.language || "en",
|
|
1851
|
+
prompt: options.prompt,
|
|
1852
|
+
temperature: options.temperature || 0,
|
|
1853
|
+
response_format: "verbose_json"
|
|
1854
|
+
});
|
|
1855
|
+
const explicitDuration = Number(transcription?.duration) || 0;
|
|
1856
|
+
const segments = Array.isArray(transcription?.segments) ? transcription.segments : [];
|
|
1857
|
+
const segmentsDuration = segments.reduce((max, segment) => {
|
|
1858
|
+
const end = Number(segment?.end);
|
|
1859
|
+
return end > max ? end : max;
|
|
1860
|
+
}, 0);
|
|
1861
|
+
const text = typeof transcription?.text === "string" ? transcription.text : segments.map((segment) => segment?.text || "").join(" ");
|
|
1862
|
+
return { text: text.trim(), durationSeconds: explicitDuration || segmentsDuration };
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
// src/voice/openai-voice-agent.ts
|
|
1866
|
+
var OpenAiVoiceAgent = class {
|
|
1867
|
+
constructor(apiKey) {
|
|
1868
|
+
this.apiKey = apiKey;
|
|
1869
|
+
}
|
|
1870
|
+
apiKey;
|
|
1871
|
+
provider = "openai";
|
|
1872
|
+
ttsModel = VOICE_MODEL_CONSTANTS.OPENAI_TTS;
|
|
1873
|
+
sttModel = VOICE_MODEL_CONSTANTS.OPENAI_STT;
|
|
1874
|
+
async speak(request) {
|
|
1875
|
+
const audio = await generateOpenAiTtsAudio(request.text, this.apiKey, {
|
|
1876
|
+
voice: request.voice,
|
|
1877
|
+
instructions: request.voiceStyle || void 0
|
|
1878
|
+
});
|
|
1879
|
+
const characters = request.text.length;
|
|
1880
|
+
return { audio, costUSD: calculateOpenAiTtsCost(characters), usage: { characters } };
|
|
1881
|
+
}
|
|
1882
|
+
async transcribe(request) {
|
|
1883
|
+
const { text, durationSeconds } = await transcribeWithOpenAi(request.audio, this.apiKey, {
|
|
1884
|
+
language: request.language,
|
|
1885
|
+
prompt: request.prompt,
|
|
1886
|
+
fileName: request.fileName,
|
|
1887
|
+
mimeType: request.mimeType
|
|
1888
|
+
});
|
|
1889
|
+
return { text, durationSeconds, costUSD: calculateOpenAiSttCost(durationSeconds), usage: { audioSeconds: durationSeconds } };
|
|
1890
|
+
}
|
|
1891
|
+
};
|
|
1892
|
+
|
|
1893
|
+
// src/voice/google-tts.ts
|
|
1894
|
+
var import_genai = require("@google/genai");
|
|
1895
|
+
var AUDIO_TOKENS_PER_SECOND = 32;
|
|
1896
|
+
var SAMPLE_RATE = 24e3;
|
|
1897
|
+
var PCM_BYTES_PER_SECOND = SAMPLE_RATE * 2;
|
|
1898
|
+
function buildGoogleTtsPrompt(text, voiceStyle) {
|
|
1899
|
+
const style = voiceStyle?.trim().replace(/[:.!,;\s]+$/, "");
|
|
1900
|
+
if (!style) return text;
|
|
1901
|
+
const isShort = style.split(/\s+/).length <= 3 && !/[.!?,;]/.test(style);
|
|
1902
|
+
return isShort ? `Say ${style}: ${text}` : `${style}:
|
|
1903
|
+
${text}`;
|
|
1904
|
+
}
|
|
1905
|
+
function pcmToWav(pcmData, sampleRate = SAMPLE_RATE) {
|
|
1906
|
+
const numChannels = 1;
|
|
1907
|
+
const bitsPerSample = 16;
|
|
1908
|
+
const blockAlign = numChannels * (bitsPerSample / 8);
|
|
1909
|
+
const byteRate = sampleRate * blockAlign;
|
|
1910
|
+
const headerSize = 44;
|
|
1911
|
+
const buffer = new ArrayBuffer(headerSize + pcmData.length);
|
|
1912
|
+
const view = new DataView(buffer);
|
|
1913
|
+
const writeString = (offset, str) => {
|
|
1914
|
+
for (let i = 0; i < str.length; i++) view.setUint8(offset + i, str.charCodeAt(i));
|
|
1915
|
+
};
|
|
1916
|
+
writeString(0, "RIFF");
|
|
1917
|
+
view.setUint32(4, 36 + pcmData.length, true);
|
|
1918
|
+
writeString(8, "WAVE");
|
|
1919
|
+
writeString(12, "fmt ");
|
|
1920
|
+
view.setUint32(16, 16, true);
|
|
1921
|
+
view.setUint16(20, 1, true);
|
|
1922
|
+
view.setUint16(22, numChannels, true);
|
|
1923
|
+
view.setUint32(24, sampleRate, true);
|
|
1924
|
+
view.setUint32(28, byteRate, true);
|
|
1925
|
+
view.setUint16(32, blockAlign, true);
|
|
1926
|
+
view.setUint16(34, bitsPerSample, true);
|
|
1927
|
+
writeString(36, "data");
|
|
1928
|
+
view.setUint32(40, pcmData.length, true);
|
|
1929
|
+
new Uint8Array(buffer, headerSize).set(pcmData);
|
|
1930
|
+
return buffer;
|
|
1931
|
+
}
|
|
1932
|
+
async function generateGoogleTtsAudio(text, apiKey, options) {
|
|
1933
|
+
const client = new import_genai.GoogleGenAI({ apiKey });
|
|
1934
|
+
const response = await client.models.generateContent({
|
|
1935
|
+
model: VOICE_MODEL_CONSTANTS.GOOGLE_TTS,
|
|
1936
|
+
contents: [{ parts: [{ text: buildGoogleTtsPrompt(text, options.voiceStyle) }] }],
|
|
1937
|
+
config: {
|
|
1938
|
+
responseModalities: ["AUDIO"],
|
|
1939
|
+
speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: options.voiceName } } }
|
|
1940
|
+
}
|
|
1941
|
+
});
|
|
1942
|
+
const parts = response.candidates?.[0]?.content?.parts ?? [];
|
|
1943
|
+
const audioPart = parts.find((part) => part.inlineData?.mimeType?.startsWith("audio/"));
|
|
1944
|
+
if (!audioPart?.inlineData?.data) {
|
|
1945
|
+
throw new Error("No audio data in Google TTS response");
|
|
1946
|
+
}
|
|
1947
|
+
const pcmData = new Uint8Array(Buffer.from(audioPart.inlineData.data, "base64"));
|
|
1948
|
+
const usageMetadata = response.usageMetadata ?? {};
|
|
1949
|
+
const inputTokens = usageMetadata.promptTokenCount ?? 0;
|
|
1950
|
+
const reportedOutput = usageMetadata.candidatesTokenCount;
|
|
1951
|
+
const outputTokens = reportedOutput && reportedOutput > 0 ? reportedOutput : Math.ceil(pcmData.length / PCM_BYTES_PER_SECOND * AUDIO_TOKENS_PER_SECOND);
|
|
1952
|
+
return { audio: pcmToWav(pcmData), usage: { inputTokens, outputTokens } };
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
// src/voice/google-stt.ts
|
|
1956
|
+
var import_genai2 = require("@google/genai");
|
|
1957
|
+
var GEMINI_AUDIO_TOKENS_PER_SECOND = 25;
|
|
1958
|
+
async function transcribeWithGemini(audioBuffer, apiKey, options = {}) {
|
|
1959
|
+
const client = new import_genai2.GoogleGenAI({ apiKey });
|
|
1960
|
+
const interaction = await client.interactions.create({
|
|
1961
|
+
model: VOICE_MODEL_CONSTANTS.GOOGLE_STT,
|
|
1962
|
+
input: [{ type: "audio", data: Buffer.from(audioBuffer).toString("base64"), mime_type: options.mimeType || "audio/webm" }]
|
|
1963
|
+
});
|
|
1964
|
+
const text = typeof interaction?.output_text === "string" ? interaction.output_text.trim() : "";
|
|
1965
|
+
const usage = interaction?.usage ?? {};
|
|
1966
|
+
const byModality = (rows, modality) => (rows ?? []).filter((r) => r?.modality === modality).reduce((sum, r) => sum + (Number(r?.tokens) || 0), 0);
|
|
1967
|
+
const inputTokens = byModality(usage.input_tokens_by_modality, "audio") || usage.total_input_tokens || 0;
|
|
1968
|
+
const invocationOutput = (usage.model_invocation_token_counts ?? []).reduce((sum, inv) => sum + (inv?.candidates_tokens_details ?? []).reduce((s, d) => s + (Number(d?.tokens) || 0), 0), 0);
|
|
1969
|
+
const outputTokens = usage.total_output_tokens || invocationOutput || Math.ceil(text.length / 4);
|
|
1970
|
+
return { text, durationSeconds: inputTokens / GEMINI_AUDIO_TOKENS_PER_SECOND, usage: { inputTokens, outputTokens } };
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
// src/voice/google-voice-agent.ts
|
|
1974
|
+
var GoogleVoiceAgent = class {
|
|
1975
|
+
constructor(apiKey) {
|
|
1976
|
+
this.apiKey = apiKey;
|
|
1977
|
+
}
|
|
1978
|
+
apiKey;
|
|
1979
|
+
provider = "google";
|
|
1980
|
+
ttsModel = VOICE_MODEL_CONSTANTS.GOOGLE_TTS;
|
|
1981
|
+
sttModel = VOICE_MODEL_CONSTANTS.GOOGLE_STT;
|
|
1982
|
+
async speak(request) {
|
|
1983
|
+
const { audio, usage } = await generateGoogleTtsAudio(request.text, this.apiKey, {
|
|
1984
|
+
voiceName: request.voice,
|
|
1985
|
+
voiceStyle: request.voiceStyle
|
|
1986
|
+
});
|
|
1987
|
+
return { audio, costUSD: calculateGeminiTtsCost(usage), usage };
|
|
1988
|
+
}
|
|
1989
|
+
async transcribe(request) {
|
|
1990
|
+
const { text, durationSeconds, usage } = await transcribeWithGemini(request.audio, this.apiKey, { mimeType: request.mimeType });
|
|
1991
|
+
return { text, durationSeconds, costUSD: calculateGeminiSttCost(usage), usage };
|
|
1992
|
+
}
|
|
1993
|
+
};
|
|
1994
|
+
|
|
1995
|
+
// src/voice/voice-agent-factory.ts
|
|
1996
|
+
var VoiceAgentFactory = class _VoiceAgentFactory {
|
|
1997
|
+
/** Build an agent from a key already resolved by the caller. */
|
|
1998
|
+
static createAgent(provider, apiKey) {
|
|
1999
|
+
switch (provider) {
|
|
2000
|
+
case "openai":
|
|
2001
|
+
return new OpenAiVoiceAgent(apiKey);
|
|
2002
|
+
case "google":
|
|
2003
|
+
return new GoogleVoiceAgent(apiKey);
|
|
2004
|
+
default:
|
|
2005
|
+
throw new Error(`Unknown voice provider: ${provider}`);
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
/**
|
|
2009
|
+
* Build an agent from a key map (the shape AgentFactory takes), reading the
|
|
2010
|
+
* provider's key by its API_KEY_CONSTANTS name. Throws when the key is missing
|
|
2011
|
+
* so the host can report a misconfiguration before any SDK is touched.
|
|
2012
|
+
*/
|
|
2013
|
+
static createAgentFromKeys(provider, apiKeys) {
|
|
2014
|
+
if (!SUPPORTED_VOICE_PROVIDERS.includes(provider)) {
|
|
2015
|
+
throw new Error(`Unknown voice provider: ${provider}`);
|
|
2016
|
+
}
|
|
2017
|
+
const keyName = VOICE_PROVIDER_API_KEY[provider];
|
|
2018
|
+
const apiKey = apiKeys[keyName];
|
|
2019
|
+
if (!apiKey) {
|
|
2020
|
+
throw new Error(`Missing API key ${keyName} for voice provider ${provider}`);
|
|
2021
|
+
}
|
|
2022
|
+
return _VoiceAgentFactory.createAgent(provider, apiKey);
|
|
2023
|
+
}
|
|
2024
|
+
};
|
|
2025
|
+
function createVoiceAgent(provider, apiKey) {
|
|
2026
|
+
return VoiceAgentFactory.createAgent(provider, apiKey);
|
|
2027
|
+
}
|
|
2028
|
+
|
|
1753
2029
|
// src/agents/abstract-agent.ts
|
|
1754
2030
|
var AbstractAgent = class {
|
|
1755
2031
|
name;
|
|
@@ -1896,7 +2172,7 @@ ${msg.content}` };
|
|
|
1896
2172
|
};
|
|
1897
2173
|
|
|
1898
2174
|
// src/agents/gpt-5-agent.ts
|
|
1899
|
-
var
|
|
2175
|
+
var import_openai3 = __toESM(require("openai"));
|
|
1900
2176
|
var import_zod2 = require("openai/helpers/zod");
|
|
1901
2177
|
var Gpt5Agent = class extends AbstractAgent {
|
|
1902
2178
|
client;
|
|
@@ -1912,7 +2188,7 @@ var Gpt5Agent = class extends AbstractAgent {
|
|
|
1912
2188
|
};
|
|
1913
2189
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
1914
2190
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
1915
|
-
this.client = new
|
|
2191
|
+
this.client = new import_openai3.default({
|
|
1916
2192
|
apiKey
|
|
1917
2193
|
});
|
|
1918
2194
|
}
|
|
@@ -2444,7 +2720,7 @@ ${schemaDescription}`;
|
|
|
2444
2720
|
};
|
|
2445
2721
|
|
|
2446
2722
|
// src/agents/google-agent.ts
|
|
2447
|
-
var
|
|
2723
|
+
var import_genai3 = require("@google/genai");
|
|
2448
2724
|
var GoogleAgent = class extends AbstractAgent {
|
|
2449
2725
|
client;
|
|
2450
2726
|
defaultConfig = {
|
|
@@ -2463,7 +2739,7 @@ var GoogleAgent = class extends AbstractAgent {
|
|
|
2463
2739
|
};
|
|
2464
2740
|
constructor(name, instruction, model, apiKey, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
2465
2741
|
super(name, instruction, model, 0.2, enableThinking, agentLoggingConfig);
|
|
2466
|
-
this.client = new
|
|
2742
|
+
this.client = new import_genai3.GoogleGenAI({
|
|
2467
2743
|
apiKey
|
|
2468
2744
|
});
|
|
2469
2745
|
}
|
|
@@ -3024,7 +3300,7 @@ ${schemaDescription}`
|
|
|
3024
3300
|
};
|
|
3025
3301
|
|
|
3026
3302
|
// src/agents/deepseek-v2-agent.ts
|
|
3027
|
-
var
|
|
3303
|
+
var import_openai4 = __toESM(require("openai"));
|
|
3028
3304
|
var DeepSeekV2Agent = class extends AbstractAgent {
|
|
3029
3305
|
client;
|
|
3030
3306
|
// Log message templates
|
|
@@ -3040,7 +3316,7 @@ var DeepSeekV2Agent = class extends AbstractAgent {
|
|
|
3040
3316
|
};
|
|
3041
3317
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
3042
3318
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
3043
|
-
this.client = new
|
|
3319
|
+
this.client = new import_openai4.default({
|
|
3044
3320
|
baseURL: "https://api.deepseek.com",
|
|
3045
3321
|
apiKey
|
|
3046
3322
|
});
|
|
@@ -3232,7 +3508,7 @@ ${schemaDescription}`
|
|
|
3232
3508
|
};
|
|
3233
3509
|
|
|
3234
3510
|
// src/agents/grok-agent.ts
|
|
3235
|
-
var
|
|
3511
|
+
var import_openai5 = require("openai");
|
|
3236
3512
|
var GrokAgent = class extends AbstractAgent {
|
|
3237
3513
|
client;
|
|
3238
3514
|
// Log message templates
|
|
@@ -3249,7 +3525,7 @@ var GrokAgent = class extends AbstractAgent {
|
|
|
3249
3525
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
3250
3526
|
const convId = stableHashHex(`${name}
|
|
3251
3527
|
${instruction}`);
|
|
3252
|
-
this.client = new
|
|
3528
|
+
this.client = new import_openai5.OpenAI({
|
|
3253
3529
|
apiKey,
|
|
3254
3530
|
baseURL: "https://api.x.ai/v1",
|
|
3255
3531
|
timeout: 12e5,
|
|
@@ -3422,7 +3698,7 @@ ${input[0].content}`;
|
|
|
3422
3698
|
};
|
|
3423
3699
|
|
|
3424
3700
|
// src/agents/kimi-agent.ts
|
|
3425
|
-
var
|
|
3701
|
+
var import_openai6 = require("openai");
|
|
3426
3702
|
var KimiAgent = class extends AbstractAgent {
|
|
3427
3703
|
client;
|
|
3428
3704
|
// kimi-k3 rejects any temperature other than 1, so we never send the field.
|
|
@@ -3449,7 +3725,7 @@ var KimiAgent = class extends AbstractAgent {
|
|
|
3449
3725
|
};
|
|
3450
3726
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
3451
3727
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
3452
|
-
this.client = new
|
|
3728
|
+
this.client = new import_openai6.OpenAI({
|
|
3453
3729
|
apiKey,
|
|
3454
3730
|
baseURL: "https://api.moonshot.ai/v1"
|
|
3455
3731
|
});
|
|
@@ -3640,7 +3916,7 @@ ${openAIMessages[0].content}`;
|
|
|
3640
3916
|
};
|
|
3641
3917
|
|
|
3642
3918
|
// src/agents/glm-agent.ts
|
|
3643
|
-
var
|
|
3919
|
+
var import_openai7 = require("openai");
|
|
3644
3920
|
var GlmAgent = class extends AbstractAgent {
|
|
3645
3921
|
client;
|
|
3646
3922
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
@@ -3666,7 +3942,7 @@ var GlmAgent = class extends AbstractAgent {
|
|
|
3666
3942
|
};
|
|
3667
3943
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
3668
3944
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
3669
|
-
this.client = new
|
|
3945
|
+
this.client = new import_openai7.OpenAI({
|
|
3670
3946
|
apiKey,
|
|
3671
3947
|
baseURL: "https://api.z.ai/api/paas/v4/"
|
|
3672
3948
|
});
|
|
@@ -3820,7 +4096,7 @@ ${openAIMessages[0].content}`;
|
|
|
3820
4096
|
};
|
|
3821
4097
|
|
|
3822
4098
|
// src/agents/fugu-agent.ts
|
|
3823
|
-
var
|
|
4099
|
+
var import_openai8 = require("openai");
|
|
3824
4100
|
var FuguAgent = class extends AbstractAgent {
|
|
3825
4101
|
client;
|
|
3826
4102
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
@@ -3844,7 +4120,7 @@ var FuguAgent = class extends AbstractAgent {
|
|
|
3844
4120
|
};
|
|
3845
4121
|
constructor(name, instruction, model, apiKey, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
3846
4122
|
super(name, instruction, model, 1, enableThinking, agentLoggingConfig);
|
|
3847
|
-
this.client = new
|
|
4123
|
+
this.client = new import_openai8.OpenAI({
|
|
3848
4124
|
apiKey,
|
|
3849
4125
|
baseURL: "https://api.sakana.ai/v1",
|
|
3850
4126
|
timeout: 12e5
|
|
@@ -4011,7 +4287,7 @@ ${schemaDescription}`;
|
|
|
4011
4287
|
};
|
|
4012
4288
|
|
|
4013
4289
|
// src/agents/qwen-agent.ts
|
|
4014
|
-
var
|
|
4290
|
+
var import_openai9 = require("openai");
|
|
4015
4291
|
var QwenAgent = class extends AbstractAgent {
|
|
4016
4292
|
client;
|
|
4017
4293
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
@@ -4036,7 +4312,7 @@ var QwenAgent = class extends AbstractAgent {
|
|
|
4036
4312
|
};
|
|
4037
4313
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
4038
4314
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
4039
|
-
this.client = new
|
|
4315
|
+
this.client = new import_openai9.OpenAI({
|
|
4040
4316
|
apiKey,
|
|
4041
4317
|
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
|
4042
4318
|
});
|
|
@@ -4211,7 +4487,7 @@ ${openAIMessages[0].content}`;
|
|
|
4211
4487
|
};
|
|
4212
4488
|
|
|
4213
4489
|
// src/agents/minimax-agent.ts
|
|
4214
|
-
var
|
|
4490
|
+
var import_openai10 = require("openai");
|
|
4215
4491
|
var MiniMaxAgent = class extends AbstractAgent {
|
|
4216
4492
|
client;
|
|
4217
4493
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
@@ -4236,7 +4512,7 @@ var MiniMaxAgent = class extends AbstractAgent {
|
|
|
4236
4512
|
};
|
|
4237
4513
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
4238
4514
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
4239
|
-
this.client = new
|
|
4515
|
+
this.client = new import_openai10.OpenAI({
|
|
4240
4516
|
apiKey,
|
|
4241
4517
|
baseURL: "https://api.minimax.io/v1"
|
|
4242
4518
|
});
|
|
@@ -4474,10 +4750,12 @@ var AgentFactory = class {
|
|
|
4474
4750
|
DeepSeekV2Agent,
|
|
4475
4751
|
FUGU_REASONING_EFFORTS,
|
|
4476
4752
|
FuguAgent,
|
|
4753
|
+
GEMINI_AUDIO_TOKENS_PER_SECOND,
|
|
4477
4754
|
GEMINI_REASONING_EFFORTS,
|
|
4478
4755
|
GLM_REASONING_EFFORTS,
|
|
4479
4756
|
GlmAgent,
|
|
4480
4757
|
GoogleAgent,
|
|
4758
|
+
GoogleVoiceAgent,
|
|
4481
4759
|
Gpt5Agent,
|
|
4482
4760
|
GrokAgent,
|
|
4483
4761
|
KimiAgent,
|
|
@@ -4495,23 +4773,35 @@ var AgentFactory = class {
|
|
|
4495
4773
|
ModelRefusalError,
|
|
4496
4774
|
ModelUnavailableError,
|
|
4497
4775
|
OPENAI_REASONING_EFFORTS,
|
|
4776
|
+
OpenAiVoiceAgent,
|
|
4498
4777
|
QwenAgent,
|
|
4499
4778
|
REASONING_EFFORT_SCALE,
|
|
4779
|
+
SUPPORTED_VOICE_PROVIDERS,
|
|
4500
4780
|
SupportedAiKeyNames,
|
|
4501
4781
|
SupportedAiModels,
|
|
4782
|
+
VOICE_MODEL_CONSTANTS,
|
|
4783
|
+
VOICE_MODEL_PRICING,
|
|
4784
|
+
VOICE_PROVIDER_API_KEY,
|
|
4785
|
+
VoiceAgentFactory,
|
|
4502
4786
|
ZodSchemaConverter,
|
|
4787
|
+
buildGoogleTtsPrompt,
|
|
4503
4788
|
calculateAnthropicCost,
|
|
4504
4789
|
calculateCost,
|
|
4505
4790
|
calculateDeepSeekCost,
|
|
4791
|
+
calculateGeminiSttCost,
|
|
4792
|
+
calculateGeminiTtsCost,
|
|
4506
4793
|
calculateGoogleCost,
|
|
4507
4794
|
calculateGrokCost,
|
|
4508
4795
|
calculateKimiCost,
|
|
4509
4796
|
calculateMistralCost,
|
|
4510
4797
|
calculateModelCost,
|
|
4511
4798
|
calculateOpenAICost,
|
|
4799
|
+
calculateOpenAiSttCost,
|
|
4800
|
+
calculateOpenAiTtsCost,
|
|
4512
4801
|
clampReasoningEffort,
|
|
4513
4802
|
cleanResponse,
|
|
4514
4803
|
createCatalog,
|
|
4804
|
+
createVoiceAgent,
|
|
4515
4805
|
extractAnthropicTokenUsage,
|
|
4516
4806
|
extractAnthropicTokenUsageFromResponse,
|
|
4517
4807
|
extractDeepSeekTokenUsage,
|
|
@@ -4529,6 +4819,8 @@ var AgentFactory = class {
|
|
|
4529
4819
|
extractOpenAITokenUsageFromResponse,
|
|
4530
4820
|
extractTokenUsage,
|
|
4531
4821
|
extractUsageAndCalculateCost,
|
|
4822
|
+
generateGoogleTtsAudio,
|
|
4823
|
+
generateOpenAiTtsAudio,
|
|
4532
4824
|
generateSchemaInstructions,
|
|
4533
4825
|
getModelConfigByApiName,
|
|
4534
4826
|
getModelDisplayName,
|
|
@@ -4545,6 +4837,7 @@ var AgentFactory = class {
|
|
|
4545
4837
|
modelIsFast,
|
|
4546
4838
|
needsPromptBasedSchema,
|
|
4547
4839
|
parseAndValidateLlmJson,
|
|
4840
|
+
pcmToWav,
|
|
4548
4841
|
safeValidateResponse,
|
|
4549
4842
|
setLlmLogger,
|
|
4550
4843
|
stableHashHex,
|
|
@@ -4556,6 +4849,8 @@ var AgentFactory = class {
|
|
|
4556
4849
|
toGeminiEffort,
|
|
4557
4850
|
toGlmEffort,
|
|
4558
4851
|
toOpenAIEffort,
|
|
4852
|
+
transcribeWithGemini,
|
|
4853
|
+
transcribeWithOpenAi,
|
|
4559
4854
|
validateResponse
|
|
4560
4855
|
});
|
|
4561
4856
|
//# sourceMappingURL=index.js.map
|