@hiper2d/ai-agents 0.1.4 → 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 +316 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +295 -25
- 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,9 +2172,8 @@ ${msg.content}` };
|
|
|
1896
2172
|
};
|
|
1897
2173
|
|
|
1898
2174
|
// src/agents/gpt-5-agent.ts
|
|
1899
|
-
var
|
|
1900
|
-
var import_zod2 = require("zod");
|
|
1901
|
-
var import_zod3 = require("openai/helpers/zod");
|
|
2175
|
+
var import_openai3 = __toESM(require("openai"));
|
|
2176
|
+
var import_zod2 = require("openai/helpers/zod");
|
|
1902
2177
|
var Gpt5Agent = class extends AbstractAgent {
|
|
1903
2178
|
client;
|
|
1904
2179
|
// Log message templates
|
|
@@ -1913,7 +2188,7 @@ var Gpt5Agent = class extends AbstractAgent {
|
|
|
1913
2188
|
};
|
|
1914
2189
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
1915
2190
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
1916
|
-
this.client = new
|
|
2191
|
+
this.client = new import_openai3.default({
|
|
1917
2192
|
apiKey
|
|
1918
2193
|
});
|
|
1919
2194
|
}
|
|
@@ -1931,12 +2206,7 @@ var Gpt5Agent = class extends AbstractAgent {
|
|
|
1931
2206
|
`System: ${this.instruction}`,
|
|
1932
2207
|
...this.prepareMessages(messages).map((msg) => `${msg.role === "user" ? "User" : "Assistant"}: ${msg.content}`)
|
|
1933
2208
|
].join("\n\n");
|
|
1934
|
-
|
|
1935
|
-
if (this.enableThinking && zodSchema instanceof import_zod2.z.ZodObject) {
|
|
1936
|
-
schemaToSend = zodSchema.extend({
|
|
1937
|
-
thinking: import_zod2.z.string().describe("Your internal chain-of-thought reasoning process used to arrive at the final answer.")
|
|
1938
|
-
});
|
|
1939
|
-
}
|
|
2209
|
+
const schemaToSend = zodSchema;
|
|
1940
2210
|
let response;
|
|
1941
2211
|
try {
|
|
1942
2212
|
response = await this.client.responses.parse({
|
|
@@ -1945,7 +2215,7 @@ var Gpt5Agent = class extends AbstractAgent {
|
|
|
1945
2215
|
input,
|
|
1946
2216
|
max_output_tokens: this.maxOutputTokens,
|
|
1947
2217
|
text: {
|
|
1948
|
-
format: (0,
|
|
2218
|
+
format: (0, import_zod2.zodTextFormat)(schemaToSend, "response_schema")
|
|
1949
2219
|
}
|
|
1950
2220
|
});
|
|
1951
2221
|
} catch (error) {
|
|
@@ -2450,7 +2720,7 @@ ${schemaDescription}`;
|
|
|
2450
2720
|
};
|
|
2451
2721
|
|
|
2452
2722
|
// src/agents/google-agent.ts
|
|
2453
|
-
var
|
|
2723
|
+
var import_genai3 = require("@google/genai");
|
|
2454
2724
|
var GoogleAgent = class extends AbstractAgent {
|
|
2455
2725
|
client;
|
|
2456
2726
|
defaultConfig = {
|
|
@@ -2469,7 +2739,7 @@ var GoogleAgent = class extends AbstractAgent {
|
|
|
2469
2739
|
};
|
|
2470
2740
|
constructor(name, instruction, model, apiKey, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
2471
2741
|
super(name, instruction, model, 0.2, enableThinking, agentLoggingConfig);
|
|
2472
|
-
this.client = new
|
|
2742
|
+
this.client = new import_genai3.GoogleGenAI({
|
|
2473
2743
|
apiKey
|
|
2474
2744
|
});
|
|
2475
2745
|
}
|
|
@@ -3030,7 +3300,7 @@ ${schemaDescription}`
|
|
|
3030
3300
|
};
|
|
3031
3301
|
|
|
3032
3302
|
// src/agents/deepseek-v2-agent.ts
|
|
3033
|
-
var
|
|
3303
|
+
var import_openai4 = __toESM(require("openai"));
|
|
3034
3304
|
var DeepSeekV2Agent = class extends AbstractAgent {
|
|
3035
3305
|
client;
|
|
3036
3306
|
// Log message templates
|
|
@@ -3046,7 +3316,7 @@ var DeepSeekV2Agent = class extends AbstractAgent {
|
|
|
3046
3316
|
};
|
|
3047
3317
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
3048
3318
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
3049
|
-
this.client = new
|
|
3319
|
+
this.client = new import_openai4.default({
|
|
3050
3320
|
baseURL: "https://api.deepseek.com",
|
|
3051
3321
|
apiKey
|
|
3052
3322
|
});
|
|
@@ -3238,7 +3508,7 @@ ${schemaDescription}`
|
|
|
3238
3508
|
};
|
|
3239
3509
|
|
|
3240
3510
|
// src/agents/grok-agent.ts
|
|
3241
|
-
var
|
|
3511
|
+
var import_openai5 = require("openai");
|
|
3242
3512
|
var GrokAgent = class extends AbstractAgent {
|
|
3243
3513
|
client;
|
|
3244
3514
|
// Log message templates
|
|
@@ -3255,7 +3525,7 @@ var GrokAgent = class extends AbstractAgent {
|
|
|
3255
3525
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
3256
3526
|
const convId = stableHashHex(`${name}
|
|
3257
3527
|
${instruction}`);
|
|
3258
|
-
this.client = new
|
|
3528
|
+
this.client = new import_openai5.OpenAI({
|
|
3259
3529
|
apiKey,
|
|
3260
3530
|
baseURL: "https://api.x.ai/v1",
|
|
3261
3531
|
timeout: 12e5,
|
|
@@ -3428,7 +3698,7 @@ ${input[0].content}`;
|
|
|
3428
3698
|
};
|
|
3429
3699
|
|
|
3430
3700
|
// src/agents/kimi-agent.ts
|
|
3431
|
-
var
|
|
3701
|
+
var import_openai6 = require("openai");
|
|
3432
3702
|
var KimiAgent = class extends AbstractAgent {
|
|
3433
3703
|
client;
|
|
3434
3704
|
// kimi-k3 rejects any temperature other than 1, so we never send the field.
|
|
@@ -3455,7 +3725,7 @@ var KimiAgent = class extends AbstractAgent {
|
|
|
3455
3725
|
};
|
|
3456
3726
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
3457
3727
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
3458
|
-
this.client = new
|
|
3728
|
+
this.client = new import_openai6.OpenAI({
|
|
3459
3729
|
apiKey,
|
|
3460
3730
|
baseURL: "https://api.moonshot.ai/v1"
|
|
3461
3731
|
});
|
|
@@ -3646,7 +3916,7 @@ ${openAIMessages[0].content}`;
|
|
|
3646
3916
|
};
|
|
3647
3917
|
|
|
3648
3918
|
// src/agents/glm-agent.ts
|
|
3649
|
-
var
|
|
3919
|
+
var import_openai7 = require("openai");
|
|
3650
3920
|
var GlmAgent = class extends AbstractAgent {
|
|
3651
3921
|
client;
|
|
3652
3922
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
@@ -3672,7 +3942,7 @@ var GlmAgent = class extends AbstractAgent {
|
|
|
3672
3942
|
};
|
|
3673
3943
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
3674
3944
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
3675
|
-
this.client = new
|
|
3945
|
+
this.client = new import_openai7.OpenAI({
|
|
3676
3946
|
apiKey,
|
|
3677
3947
|
baseURL: "https://api.z.ai/api/paas/v4/"
|
|
3678
3948
|
});
|
|
@@ -3826,7 +4096,7 @@ ${openAIMessages[0].content}`;
|
|
|
3826
4096
|
};
|
|
3827
4097
|
|
|
3828
4098
|
// src/agents/fugu-agent.ts
|
|
3829
|
-
var
|
|
4099
|
+
var import_openai8 = require("openai");
|
|
3830
4100
|
var FuguAgent = class extends AbstractAgent {
|
|
3831
4101
|
client;
|
|
3832
4102
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
@@ -3850,7 +4120,7 @@ var FuguAgent = class extends AbstractAgent {
|
|
|
3850
4120
|
};
|
|
3851
4121
|
constructor(name, instruction, model, apiKey, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
3852
4122
|
super(name, instruction, model, 1, enableThinking, agentLoggingConfig);
|
|
3853
|
-
this.client = new
|
|
4123
|
+
this.client = new import_openai8.OpenAI({
|
|
3854
4124
|
apiKey,
|
|
3855
4125
|
baseURL: "https://api.sakana.ai/v1",
|
|
3856
4126
|
timeout: 12e5
|
|
@@ -4017,7 +4287,7 @@ ${schemaDescription}`;
|
|
|
4017
4287
|
};
|
|
4018
4288
|
|
|
4019
4289
|
// src/agents/qwen-agent.ts
|
|
4020
|
-
var
|
|
4290
|
+
var import_openai9 = require("openai");
|
|
4021
4291
|
var QwenAgent = class extends AbstractAgent {
|
|
4022
4292
|
client;
|
|
4023
4293
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
@@ -4042,7 +4312,7 @@ var QwenAgent = class extends AbstractAgent {
|
|
|
4042
4312
|
};
|
|
4043
4313
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
4044
4314
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
4045
|
-
this.client = new
|
|
4315
|
+
this.client = new import_openai9.OpenAI({
|
|
4046
4316
|
apiKey,
|
|
4047
4317
|
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
|
4048
4318
|
});
|
|
@@ -4217,7 +4487,7 @@ ${openAIMessages[0].content}`;
|
|
|
4217
4487
|
};
|
|
4218
4488
|
|
|
4219
4489
|
// src/agents/minimax-agent.ts
|
|
4220
|
-
var
|
|
4490
|
+
var import_openai10 = require("openai");
|
|
4221
4491
|
var MiniMaxAgent = class extends AbstractAgent {
|
|
4222
4492
|
client;
|
|
4223
4493
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
@@ -4242,7 +4512,7 @@ var MiniMaxAgent = class extends AbstractAgent {
|
|
|
4242
4512
|
};
|
|
4243
4513
|
constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
|
|
4244
4514
|
super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
|
|
4245
|
-
this.client = new
|
|
4515
|
+
this.client = new import_openai10.OpenAI({
|
|
4246
4516
|
apiKey,
|
|
4247
4517
|
baseURL: "https://api.minimax.io/v1"
|
|
4248
4518
|
});
|
|
@@ -4480,10 +4750,12 @@ var AgentFactory = class {
|
|
|
4480
4750
|
DeepSeekV2Agent,
|
|
4481
4751
|
FUGU_REASONING_EFFORTS,
|
|
4482
4752
|
FuguAgent,
|
|
4753
|
+
GEMINI_AUDIO_TOKENS_PER_SECOND,
|
|
4483
4754
|
GEMINI_REASONING_EFFORTS,
|
|
4484
4755
|
GLM_REASONING_EFFORTS,
|
|
4485
4756
|
GlmAgent,
|
|
4486
4757
|
GoogleAgent,
|
|
4758
|
+
GoogleVoiceAgent,
|
|
4487
4759
|
Gpt5Agent,
|
|
4488
4760
|
GrokAgent,
|
|
4489
4761
|
KimiAgent,
|
|
@@ -4501,23 +4773,35 @@ var AgentFactory = class {
|
|
|
4501
4773
|
ModelRefusalError,
|
|
4502
4774
|
ModelUnavailableError,
|
|
4503
4775
|
OPENAI_REASONING_EFFORTS,
|
|
4776
|
+
OpenAiVoiceAgent,
|
|
4504
4777
|
QwenAgent,
|
|
4505
4778
|
REASONING_EFFORT_SCALE,
|
|
4779
|
+
SUPPORTED_VOICE_PROVIDERS,
|
|
4506
4780
|
SupportedAiKeyNames,
|
|
4507
4781
|
SupportedAiModels,
|
|
4782
|
+
VOICE_MODEL_CONSTANTS,
|
|
4783
|
+
VOICE_MODEL_PRICING,
|
|
4784
|
+
VOICE_PROVIDER_API_KEY,
|
|
4785
|
+
VoiceAgentFactory,
|
|
4508
4786
|
ZodSchemaConverter,
|
|
4787
|
+
buildGoogleTtsPrompt,
|
|
4509
4788
|
calculateAnthropicCost,
|
|
4510
4789
|
calculateCost,
|
|
4511
4790
|
calculateDeepSeekCost,
|
|
4791
|
+
calculateGeminiSttCost,
|
|
4792
|
+
calculateGeminiTtsCost,
|
|
4512
4793
|
calculateGoogleCost,
|
|
4513
4794
|
calculateGrokCost,
|
|
4514
4795
|
calculateKimiCost,
|
|
4515
4796
|
calculateMistralCost,
|
|
4516
4797
|
calculateModelCost,
|
|
4517
4798
|
calculateOpenAICost,
|
|
4799
|
+
calculateOpenAiSttCost,
|
|
4800
|
+
calculateOpenAiTtsCost,
|
|
4518
4801
|
clampReasoningEffort,
|
|
4519
4802
|
cleanResponse,
|
|
4520
4803
|
createCatalog,
|
|
4804
|
+
createVoiceAgent,
|
|
4521
4805
|
extractAnthropicTokenUsage,
|
|
4522
4806
|
extractAnthropicTokenUsageFromResponse,
|
|
4523
4807
|
extractDeepSeekTokenUsage,
|
|
@@ -4535,6 +4819,8 @@ var AgentFactory = class {
|
|
|
4535
4819
|
extractOpenAITokenUsageFromResponse,
|
|
4536
4820
|
extractTokenUsage,
|
|
4537
4821
|
extractUsageAndCalculateCost,
|
|
4822
|
+
generateGoogleTtsAudio,
|
|
4823
|
+
generateOpenAiTtsAudio,
|
|
4538
4824
|
generateSchemaInstructions,
|
|
4539
4825
|
getModelConfigByApiName,
|
|
4540
4826
|
getModelDisplayName,
|
|
@@ -4551,6 +4837,7 @@ var AgentFactory = class {
|
|
|
4551
4837
|
modelIsFast,
|
|
4552
4838
|
needsPromptBasedSchema,
|
|
4553
4839
|
parseAndValidateLlmJson,
|
|
4840
|
+
pcmToWav,
|
|
4554
4841
|
safeValidateResponse,
|
|
4555
4842
|
setLlmLogger,
|
|
4556
4843
|
stableHashHex,
|
|
@@ -4562,6 +4849,8 @@ var AgentFactory = class {
|
|
|
4562
4849
|
toGeminiEffort,
|
|
4563
4850
|
toGlmEffort,
|
|
4564
4851
|
toOpenAIEffort,
|
|
4852
|
+
transcribeWithGemini,
|
|
4853
|
+
transcribeWithOpenAi,
|
|
4565
4854
|
validateResponse
|
|
4566
4855
|
});
|
|
4567
4856
|
//# sourceMappingURL=index.js.map
|