@hiper2d/ai-agents 0.1.5 → 0.2.1

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.mjs CHANGED
@@ -1618,6 +1618,263 @@ function extractTokenUsageFromResponse7(response) {
1618
1618
  return extractMistralTokenUsage(response);
1619
1619
  }
1620
1620
 
1621
+ // src/voice/voice-catalog.ts
1622
+ var VOICE_MODEL_CONSTANTS = {
1623
+ OPENAI_TTS: "gpt-4o-mini-tts",
1624
+ OPENAI_STT: "whisper-1",
1625
+ // ai.google.dev/gemini-api/docs/speech-generation
1626
+ GOOGLE_TTS: "gemini-3.1-flash-tts-preview",
1627
+ // ai.google.dev/gemini-api/docs/transcribe — Interactions API only (see google-stt.ts)
1628
+ GOOGLE_STT: "gemini-3.5-transcribe"
1629
+ };
1630
+ var SUPPORTED_VOICE_PROVIDERS = ["openai", "google"];
1631
+ var VOICE_PROVIDER_API_KEY = {
1632
+ openai: API_KEY_CONSTANTS.OPENAI,
1633
+ google: API_KEY_CONSTANTS.GOOGLE
1634
+ };
1635
+ var VOICE_MODEL_PRICING = {
1636
+ [VOICE_MODEL_CONSTANTS.OPENAI_TTS]: { pricePerMillionCharacters: 15 },
1637
+ [VOICE_MODEL_CONSTANTS.OPENAI_STT]: { pricePerMinute: 6e-3 },
1638
+ // Measured 2026-09-05: ~32 audio tokens per second of speech, so a 15-second
1639
+ // line is ~$0.01 — about 3-5x an OpenAI line of the same length.
1640
+ [VOICE_MODEL_CONSTANTS.GOOGLE_TTS]: { textInputPricePerM: 1, audioOutputPricePerM: 20 },
1641
+ // ~25 audio tokens per second in, ~175 text tokens per minute out: ≈ $0.005/min.
1642
+ [VOICE_MODEL_CONSTANTS.GOOGLE_STT]: { audioInputPricePerM: 2, textOutputPricePerM: 12 }
1643
+ };
1644
+
1645
+ // src/voice/voice-pricing.ts
1646
+ function roundUSD(value) {
1647
+ return parseFloat((value || 0).toFixed(6));
1648
+ }
1649
+ function calculateOpenAiTtsCost(characterCount) {
1650
+ const rate = VOICE_MODEL_PRICING[VOICE_MODEL_CONSTANTS.OPENAI_TTS]?.pricePerMillionCharacters ?? 0;
1651
+ if (!characterCount || characterCount <= 0 || rate <= 0) return 0;
1652
+ return roundUSD(characterCount / 1e6 * rate);
1653
+ }
1654
+ function calculateOpenAiSttCost(durationSeconds) {
1655
+ const rate = VOICE_MODEL_PRICING[VOICE_MODEL_CONSTANTS.OPENAI_STT]?.pricePerMinute ?? 0;
1656
+ if (!durationSeconds || durationSeconds <= 0 || rate <= 0) return 0;
1657
+ return roundUSD(durationSeconds / 60 * rate);
1658
+ }
1659
+ function calculateGeminiTtsCost(usage) {
1660
+ const pricing = VOICE_MODEL_PRICING[VOICE_MODEL_CONSTANTS.GOOGLE_TTS];
1661
+ return tokenPairCost(usage, pricing?.textInputPricePerM ?? 0, pricing?.audioOutputPricePerM ?? 0);
1662
+ }
1663
+ function calculateGeminiSttCost(usage) {
1664
+ const pricing = VOICE_MODEL_PRICING[VOICE_MODEL_CONSTANTS.GOOGLE_STT];
1665
+ return tokenPairCost(usage, pricing?.audioInputPricePerM ?? 0, pricing?.textOutputPricePerM ?? 0);
1666
+ }
1667
+ function tokenPairCost(usage, inputRate, outputRate) {
1668
+ const inputTokens = Math.max(0, usage.inputTokens || 0);
1669
+ const outputTokens = Math.max(0, usage.outputTokens || 0);
1670
+ return inputTokens / 1e6 * inputRate + outputTokens / 1e6 * outputRate;
1671
+ }
1672
+
1673
+ // src/voice/openai-tts.ts
1674
+ import { OpenAI } from "openai";
1675
+ async function generateOpenAiTtsAudio(text, apiKey, options = {}) {
1676
+ const client = new OpenAI({ apiKey });
1677
+ const speechOptions = {
1678
+ model: VOICE_MODEL_CONSTANTS.OPENAI_TTS,
1679
+ voice: options.voice || "alloy",
1680
+ input: text,
1681
+ speed: options.speed || 1,
1682
+ response_format: options.format || "wav"
1683
+ };
1684
+ if (options.instructions) {
1685
+ speechOptions.instructions = options.instructions;
1686
+ }
1687
+ const response = await client.audio.speech.create(speechOptions);
1688
+ return await response.arrayBuffer();
1689
+ }
1690
+
1691
+ // src/voice/openai-stt.ts
1692
+ import { OpenAI as OpenAI2 } from "openai";
1693
+ async function transcribeWithOpenAi(audioBuffer, apiKey, options = {}) {
1694
+ const client = new OpenAI2({ apiKey });
1695
+ const audioFile = new File([new Uint8Array(audioBuffer)], options.fileName || "audio.webm", { type: options.mimeType || "audio/webm" });
1696
+ const transcription = await client.audio.transcriptions.create({
1697
+ file: audioFile,
1698
+ model: VOICE_MODEL_CONSTANTS.OPENAI_STT,
1699
+ language: options.language || "en",
1700
+ prompt: options.prompt,
1701
+ temperature: options.temperature || 0,
1702
+ response_format: "verbose_json"
1703
+ });
1704
+ const explicitDuration = Number(transcription?.duration) || 0;
1705
+ const segments = Array.isArray(transcription?.segments) ? transcription.segments : [];
1706
+ const segmentsDuration = segments.reduce((max, segment) => {
1707
+ const end = Number(segment?.end);
1708
+ return end > max ? end : max;
1709
+ }, 0);
1710
+ const text = typeof transcription?.text === "string" ? transcription.text : segments.map((segment) => segment?.text || "").join(" ");
1711
+ return { text: text.trim(), durationSeconds: explicitDuration || segmentsDuration };
1712
+ }
1713
+
1714
+ // src/voice/openai-voice-agent.ts
1715
+ var OpenAiVoiceAgent = class {
1716
+ constructor(apiKey) {
1717
+ this.apiKey = apiKey;
1718
+ }
1719
+ apiKey;
1720
+ provider = "openai";
1721
+ ttsModel = VOICE_MODEL_CONSTANTS.OPENAI_TTS;
1722
+ sttModel = VOICE_MODEL_CONSTANTS.OPENAI_STT;
1723
+ async speak(request) {
1724
+ const audio = await generateOpenAiTtsAudio(request.text, this.apiKey, {
1725
+ voice: request.voice,
1726
+ instructions: request.voiceStyle || void 0
1727
+ });
1728
+ const characters = request.text.length;
1729
+ return { audio, costUSD: calculateOpenAiTtsCost(characters), usage: { characters } };
1730
+ }
1731
+ async transcribe(request) {
1732
+ const { text, durationSeconds } = await transcribeWithOpenAi(request.audio, this.apiKey, {
1733
+ language: request.language,
1734
+ prompt: request.prompt,
1735
+ fileName: request.fileName,
1736
+ mimeType: request.mimeType
1737
+ });
1738
+ return { text, durationSeconds, costUSD: calculateOpenAiSttCost(durationSeconds), usage: { audioSeconds: durationSeconds } };
1739
+ }
1740
+ };
1741
+
1742
+ // src/voice/google-tts.ts
1743
+ import { GoogleGenAI } from "@google/genai";
1744
+ var AUDIO_TOKENS_PER_SECOND = 32;
1745
+ var SAMPLE_RATE = 24e3;
1746
+ var PCM_BYTES_PER_SECOND = SAMPLE_RATE * 2;
1747
+ function buildGoogleTtsPrompt(text, voiceStyle) {
1748
+ const style = voiceStyle?.trim().replace(/[:.!,;\s]+$/, "");
1749
+ if (!style) return text;
1750
+ const isShort = style.split(/\s+/).length <= 3 && !/[.!?,;]/.test(style);
1751
+ return isShort ? `Say ${style}: ${text}` : `${style}:
1752
+ ${text}`;
1753
+ }
1754
+ function pcmToWav(pcmData, sampleRate = SAMPLE_RATE) {
1755
+ const numChannels = 1;
1756
+ const bitsPerSample = 16;
1757
+ const blockAlign = numChannels * (bitsPerSample / 8);
1758
+ const byteRate = sampleRate * blockAlign;
1759
+ const headerSize = 44;
1760
+ const buffer = new ArrayBuffer(headerSize + pcmData.length);
1761
+ const view = new DataView(buffer);
1762
+ const writeString = (offset, str) => {
1763
+ for (let i = 0; i < str.length; i++) view.setUint8(offset + i, str.charCodeAt(i));
1764
+ };
1765
+ writeString(0, "RIFF");
1766
+ view.setUint32(4, 36 + pcmData.length, true);
1767
+ writeString(8, "WAVE");
1768
+ writeString(12, "fmt ");
1769
+ view.setUint32(16, 16, true);
1770
+ view.setUint16(20, 1, true);
1771
+ view.setUint16(22, numChannels, true);
1772
+ view.setUint32(24, sampleRate, true);
1773
+ view.setUint32(28, byteRate, true);
1774
+ view.setUint16(32, blockAlign, true);
1775
+ view.setUint16(34, bitsPerSample, true);
1776
+ writeString(36, "data");
1777
+ view.setUint32(40, pcmData.length, true);
1778
+ new Uint8Array(buffer, headerSize).set(pcmData);
1779
+ return buffer;
1780
+ }
1781
+ async function generateGoogleTtsAudio(text, apiKey, options) {
1782
+ const client = new GoogleGenAI({ apiKey });
1783
+ const response = await client.models.generateContent({
1784
+ model: VOICE_MODEL_CONSTANTS.GOOGLE_TTS,
1785
+ contents: [{ parts: [{ text: buildGoogleTtsPrompt(text, options.voiceStyle) }] }],
1786
+ config: {
1787
+ responseModalities: ["AUDIO"],
1788
+ speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: options.voiceName } } }
1789
+ }
1790
+ });
1791
+ const parts = response.candidates?.[0]?.content?.parts ?? [];
1792
+ const audioPart = parts.find((part) => part.inlineData?.mimeType?.startsWith("audio/"));
1793
+ if (!audioPart?.inlineData?.data) {
1794
+ throw new Error("No audio data in Google TTS response");
1795
+ }
1796
+ const pcmData = new Uint8Array(Buffer.from(audioPart.inlineData.data, "base64"));
1797
+ const usageMetadata = response.usageMetadata ?? {};
1798
+ const inputTokens = usageMetadata.promptTokenCount ?? 0;
1799
+ const reportedOutput = usageMetadata.candidatesTokenCount;
1800
+ const outputTokens = reportedOutput && reportedOutput > 0 ? reportedOutput : Math.ceil(pcmData.length / PCM_BYTES_PER_SECOND * AUDIO_TOKENS_PER_SECOND);
1801
+ return { audio: pcmToWav(pcmData), usage: { inputTokens, outputTokens } };
1802
+ }
1803
+
1804
+ // src/voice/google-stt.ts
1805
+ import { GoogleGenAI as GoogleGenAI2 } from "@google/genai";
1806
+ var GEMINI_AUDIO_TOKENS_PER_SECOND = 25;
1807
+ async function transcribeWithGemini(audioBuffer, apiKey, options = {}) {
1808
+ const client = new GoogleGenAI2({ apiKey });
1809
+ const interaction = await client.interactions.create({
1810
+ model: VOICE_MODEL_CONSTANTS.GOOGLE_STT,
1811
+ input: [{ type: "audio", data: Buffer.from(audioBuffer).toString("base64"), mime_type: options.mimeType || "audio/webm" }]
1812
+ });
1813
+ const text = typeof interaction?.output_text === "string" ? interaction.output_text.trim() : "";
1814
+ const usage = interaction?.usage ?? {};
1815
+ const byModality = (rows, modality) => (rows ?? []).filter((r) => r?.modality === modality).reduce((sum, r) => sum + (Number(r?.tokens) || 0), 0);
1816
+ const inputTokens = byModality(usage.input_tokens_by_modality, "audio") || usage.total_input_tokens || 0;
1817
+ 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);
1818
+ const outputTokens = usage.total_output_tokens || invocationOutput || Math.ceil(text.length / 4);
1819
+ return { text, durationSeconds: inputTokens / GEMINI_AUDIO_TOKENS_PER_SECOND, usage: { inputTokens, outputTokens } };
1820
+ }
1821
+
1822
+ // src/voice/google-voice-agent.ts
1823
+ var GoogleVoiceAgent = class {
1824
+ constructor(apiKey) {
1825
+ this.apiKey = apiKey;
1826
+ }
1827
+ apiKey;
1828
+ provider = "google";
1829
+ ttsModel = VOICE_MODEL_CONSTANTS.GOOGLE_TTS;
1830
+ sttModel = VOICE_MODEL_CONSTANTS.GOOGLE_STT;
1831
+ async speak(request) {
1832
+ const { audio, usage } = await generateGoogleTtsAudio(request.text, this.apiKey, {
1833
+ voiceName: request.voice,
1834
+ voiceStyle: request.voiceStyle
1835
+ });
1836
+ return { audio, costUSD: calculateGeminiTtsCost(usage), usage };
1837
+ }
1838
+ async transcribe(request) {
1839
+ const { text, durationSeconds, usage } = await transcribeWithGemini(request.audio, this.apiKey, { mimeType: request.mimeType });
1840
+ return { text, durationSeconds, costUSD: calculateGeminiSttCost(usage), usage };
1841
+ }
1842
+ };
1843
+
1844
+ // src/voice/voice-agent-factory.ts
1845
+ var VoiceAgentFactory = class _VoiceAgentFactory {
1846
+ /** Build an agent from a key already resolved by the caller. */
1847
+ static createAgent(provider, apiKey) {
1848
+ switch (provider) {
1849
+ case "openai":
1850
+ return new OpenAiVoiceAgent(apiKey);
1851
+ case "google":
1852
+ return new GoogleVoiceAgent(apiKey);
1853
+ default:
1854
+ throw new Error(`Unknown voice provider: ${provider}`);
1855
+ }
1856
+ }
1857
+ /**
1858
+ * Build an agent from a key map (the shape AgentFactory takes), reading the
1859
+ * provider's key by its API_KEY_CONSTANTS name. Throws when the key is missing
1860
+ * so the host can report a misconfiguration before any SDK is touched.
1861
+ */
1862
+ static createAgentFromKeys(provider, apiKeys) {
1863
+ if (!SUPPORTED_VOICE_PROVIDERS.includes(provider)) {
1864
+ throw new Error(`Unknown voice provider: ${provider}`);
1865
+ }
1866
+ const keyName = VOICE_PROVIDER_API_KEY[provider];
1867
+ const apiKey = apiKeys[keyName];
1868
+ if (!apiKey) {
1869
+ throw new Error(`Missing API key ${keyName} for voice provider ${provider}`);
1870
+ }
1871
+ return _VoiceAgentFactory.createAgent(provider, apiKey);
1872
+ }
1873
+ };
1874
+ function createVoiceAgent(provider, apiKey) {
1875
+ return VoiceAgentFactory.createAgent(provider, apiKey);
1876
+ }
1877
+
1621
1878
  // src/agents/abstract-agent.ts
1622
1879
  var AbstractAgent = class {
1623
1880
  name;
@@ -1764,10 +2021,15 @@ ${msg.content}` };
1764
2021
  };
1765
2022
 
1766
2023
  // src/agents/gpt-5-agent.ts
1767
- import OpenAI from "openai";
2024
+ import OpenAI3 from "openai";
1768
2025
  import { zodTextFormat } from "openai/helpers/zod";
1769
2026
  var Gpt5Agent = class extends AbstractAgent {
1770
2027
  client;
2028
+ // Routing hint for OpenAI's prefix cache (same scheme as the Mistral/Grok agents): one
2029
+ // key per agent+instruction, so an agent's own calls group together instead of every
2030
+ // agent that shares a static prefix hashing to the same route. Keys influence routing
2031
+ // only; they do not guarantee a hit.
2032
+ promptCacheKey;
1771
2033
  // Log message templates
1772
2034
  logTemplates = {
1773
2035
  error: (name, error) => `Error in ${name} agent: ${error}`
@@ -1780,7 +2042,9 @@ var Gpt5Agent = class extends AbstractAgent {
1780
2042
  };
1781
2043
  constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
1782
2044
  super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
1783
- this.client = new OpenAI({
2045
+ this.promptCacheKey = stableHashHex(`${name}
2046
+ ${instruction}`);
2047
+ this.client = new OpenAI3({
1784
2048
  apiKey
1785
2049
  });
1786
2050
  }
@@ -1794,10 +2058,7 @@ var Gpt5Agent = class extends AbstractAgent {
1794
2058
  try {
1795
2059
  this.logAsking(messages);
1796
2060
  this.logMessages(messages);
1797
- const input = [
1798
- `System: ${this.instruction}`,
1799
- ...this.prepareMessages(messages).map((msg) => `${msg.role === "user" ? "User" : "Assistant"}: ${msg.content}`)
1800
- ].join("\n\n");
2061
+ const input = this.prepareMessages(messages).map((msg) => `${msg.role === "user" ? "User" : "Assistant"}: ${msg.content}`).join("\n\n");
1801
2062
  const schemaToSend = zodSchema;
1802
2063
  let response;
1803
2064
  try {
@@ -1806,6 +2067,7 @@ var Gpt5Agent = class extends AbstractAgent {
1806
2067
  instructions: this.instruction,
1807
2068
  input,
1808
2069
  max_output_tokens: this.maxOutputTokens,
2070
+ prompt_cache_key: this.promptCacheKey,
1809
2071
  text: {
1810
2072
  format: zodTextFormat(schemaToSend, "response_schema")
1811
2073
  }
@@ -1884,15 +2146,13 @@ var Gpt5Agent = class extends AbstractAgent {
1884
2146
  try {
1885
2147
  this.logAsking(messages);
1886
2148
  this.logMessages(messages);
1887
- const input = [
1888
- `System: ${this.instruction}`,
1889
- ...this.prepareMessages(messages).map((msg) => `${msg.role === "user" ? "User" : "Assistant"}: ${msg.content}`)
1890
- ].join("\n\n");
2149
+ const input = this.prepareMessages(messages).map((msg) => `${msg.role === "user" ? "User" : "Assistant"}: ${msg.content}`).join("\n\n");
1891
2150
  const response = await this.client.responses.create({
1892
2151
  model: this.model,
1893
2152
  instructions: this.instruction,
1894
2153
  input,
1895
- max_output_tokens: this.maxOutputTokens
2154
+ max_output_tokens: this.maxOutputTokens,
2155
+ prompt_cache_key: this.promptCacheKey
1896
2156
  });
1897
2157
  const content = response.output_text;
1898
2158
  if (!content) {
@@ -1948,13 +2208,24 @@ var Gpt5Agent = class extends AbstractAgent {
1948
2208
  import { Anthropic } from "@anthropic-ai/sdk";
1949
2209
  var ClaudeAgent = class extends AbstractAgent {
1950
2210
  client;
2211
+ /**
2212
+ * TTL for every breakpoint this agent places (system tiers and the message anchor).
2213
+ * Anthropic bills a 5m write at 1.25x input, a 1h write at 2x, reads at 0.1x, and a read
2214
+ * refreshes the timer on either TTL. Default '1h' because the main consumer runs at human
2215
+ * pace: consecutive calls for one agent measured 12-78 minutes apart, so 5m entries
2216
+ * expired before they were ever read (0-16% hit rate over 30 days, hits only on gaps
2217
+ * under five minutes). Set '5m' for continuous traffic where every call lands inside the
2218
+ * window; there the cheaper write wins. One knob for all breakpoints on purpose: Anthropic
2219
+ * requires 1h entries to precede 5m ones, and a single TTL keeps that trivially true.
2220
+ */
2221
+ cacheTtl = "1h";
1951
2222
  // System-prompt breakpoints, one per cache tier (see CACHE_TIER_MARKER):
1952
- // block 1 shared static rules, byte-identical across all bots and games with the
1953
- // same rule set, so one org-level entry serves everyone and ANY bot's call
1954
- // refreshes its TTL;
1955
- // block 2 per-bot identity + game state + summaries, byte-stable from the start of
1956
- // a game day through the end of its night (deaths/role knowledge/summaries
1957
- // only change in startNewDay), so every call within a day reads it.
2223
+ // block 1 - shared static rules, byte-identical across all bots and games with the
2224
+ // same rule set. Caches are scoped per model, so one entry serves every bot
2225
+ // ON THAT MODEL (not the whole lobby), and any of their calls refreshes it;
2226
+ // block 2 - per-bot identity + game state + summaries, byte-stable between the game's
2227
+ // state writes (a lynch, the night resolution, the summary rewrite, the new
2228
+ // day), so every call inside one of those windows reads it.
1958
2229
  // GM prompts have no marker → single block, same behavior as before. Haiku 4.5 needs a
1959
2230
  // 4096-token cacheable prefix, so tiers below that silently no-op on Haiku — expected.
1960
2231
  // A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
@@ -1962,7 +2233,7 @@ var ClaudeAgent = class extends AbstractAgent {
1962
2233
  get defaultParams() {
1963
2234
  return {
1964
2235
  max_tokens: this.maxOutputTokens,
1965
- system: this.instructionParts.map((part) => ({ type: "text", text: part, cache_control: { type: "ephemeral" } })),
2236
+ system: this.instructionParts.map((part) => ({ type: "text", text: part, cache_control: { type: "ephemeral", ttl: this.cacheTtl } })),
1966
2237
  model: this.model
1967
2238
  };
1968
2239
  }
@@ -2067,14 +2338,14 @@ var ClaudeAgent = class extends AbstractAgent {
2067
2338
  const anchor = messages[messages.length - 2];
2068
2339
  if (typeof anchor.content === "string") {
2069
2340
  if (anchor.content.length > 0) {
2070
- anchor.content = [{ type: "text", text: anchor.content, cache_control: { type: "ephemeral" } }];
2341
+ anchor.content = [{ type: "text", text: anchor.content, cache_control: { type: "ephemeral", ttl: this.cacheTtl } }];
2071
2342
  }
2072
2343
  return;
2073
2344
  }
2074
2345
  for (let i = anchor.content.length - 1; i >= 0; i--) {
2075
2346
  const block = anchor.content[i];
2076
2347
  if (block.type === "text" && block.text.length > 0) {
2077
- block.cache_control = { type: "ephemeral" };
2348
+ block.cache_control = { type: "ephemeral", ttl: this.cacheTtl };
2078
2349
  return;
2079
2350
  }
2080
2351
  }
@@ -2312,7 +2583,7 @@ ${schemaDescription}`;
2312
2583
  };
2313
2584
 
2314
2585
  // src/agents/google-agent.ts
2315
- import { GoogleGenAI } from "@google/genai";
2586
+ import { GoogleGenAI as GoogleGenAI3 } from "@google/genai";
2316
2587
  var GoogleAgent = class extends AbstractAgent {
2317
2588
  client;
2318
2589
  defaultConfig = {
@@ -2331,7 +2602,7 @@ var GoogleAgent = class extends AbstractAgent {
2331
2602
  };
2332
2603
  constructor(name, instruction, model, apiKey, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
2333
2604
  super(name, instruction, model, 0.2, enableThinking, agentLoggingConfig);
2334
- this.client = new GoogleGenAI({
2605
+ this.client = new GoogleGenAI3({
2335
2606
  apiKey
2336
2607
  });
2337
2608
  }
@@ -2892,7 +3163,7 @@ ${schemaDescription}`
2892
3163
  };
2893
3164
 
2894
3165
  // src/agents/deepseek-v2-agent.ts
2895
- import OpenAI2 from "openai";
3166
+ import OpenAI4 from "openai";
2896
3167
  var DeepSeekV2Agent = class extends AbstractAgent {
2897
3168
  client;
2898
3169
  // Log message templates
@@ -2908,7 +3179,7 @@ var DeepSeekV2Agent = class extends AbstractAgent {
2908
3179
  };
2909
3180
  constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
2910
3181
  super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
2911
- this.client = new OpenAI2({
3182
+ this.client = new OpenAI4({
2912
3183
  baseURL: "https://api.deepseek.com",
2913
3184
  apiKey
2914
3185
  });
@@ -3100,7 +3371,7 @@ ${schemaDescription}`
3100
3371
  };
3101
3372
 
3102
3373
  // src/agents/grok-agent.ts
3103
- import { OpenAI as OpenAI3 } from "openai";
3374
+ import { OpenAI as OpenAI5 } from "openai";
3104
3375
  var GrokAgent = class extends AbstractAgent {
3105
3376
  client;
3106
3377
  // Log message templates
@@ -3117,7 +3388,7 @@ var GrokAgent = class extends AbstractAgent {
3117
3388
  super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
3118
3389
  const convId = stableHashHex(`${name}
3119
3390
  ${instruction}`);
3120
- this.client = new OpenAI3({
3391
+ this.client = new OpenAI5({
3121
3392
  apiKey,
3122
3393
  baseURL: "https://api.x.ai/v1",
3123
3394
  timeout: 12e5,
@@ -3290,7 +3561,7 @@ ${input[0].content}`;
3290
3561
  };
3291
3562
 
3292
3563
  // src/agents/kimi-agent.ts
3293
- import { OpenAI as OpenAI4 } from "openai";
3564
+ import { OpenAI as OpenAI6 } from "openai";
3294
3565
  var KimiAgent = class extends AbstractAgent {
3295
3566
  client;
3296
3567
  // kimi-k3 rejects any temperature other than 1, so we never send the field.
@@ -3317,7 +3588,7 @@ var KimiAgent = class extends AbstractAgent {
3317
3588
  };
3318
3589
  constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
3319
3590
  super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
3320
- this.client = new OpenAI4({
3591
+ this.client = new OpenAI6({
3321
3592
  apiKey,
3322
3593
  baseURL: "https://api.moonshot.ai/v1"
3323
3594
  });
@@ -3508,7 +3779,7 @@ ${openAIMessages[0].content}`;
3508
3779
  };
3509
3780
 
3510
3781
  // src/agents/glm-agent.ts
3511
- import { OpenAI as OpenAI5 } from "openai";
3782
+ import { OpenAI as OpenAI7 } from "openai";
3512
3783
  var GlmAgent = class extends AbstractAgent {
3513
3784
  client;
3514
3785
  // A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
@@ -3534,7 +3805,7 @@ var GlmAgent = class extends AbstractAgent {
3534
3805
  };
3535
3806
  constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
3536
3807
  super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
3537
- this.client = new OpenAI5({
3808
+ this.client = new OpenAI7({
3538
3809
  apiKey,
3539
3810
  baseURL: "https://api.z.ai/api/paas/v4/"
3540
3811
  });
@@ -3688,7 +3959,7 @@ ${openAIMessages[0].content}`;
3688
3959
  };
3689
3960
 
3690
3961
  // src/agents/fugu-agent.ts
3691
- import { OpenAI as OpenAI6 } from "openai";
3962
+ import { OpenAI as OpenAI8 } from "openai";
3692
3963
  var FuguAgent = class extends AbstractAgent {
3693
3964
  client;
3694
3965
  // A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
@@ -3712,7 +3983,7 @@ var FuguAgent = class extends AbstractAgent {
3712
3983
  };
3713
3984
  constructor(name, instruction, model, apiKey, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
3714
3985
  super(name, instruction, model, 1, enableThinking, agentLoggingConfig);
3715
- this.client = new OpenAI6({
3986
+ this.client = new OpenAI8({
3716
3987
  apiKey,
3717
3988
  baseURL: "https://api.sakana.ai/v1",
3718
3989
  timeout: 12e5
@@ -3879,7 +4150,7 @@ ${schemaDescription}`;
3879
4150
  };
3880
4151
 
3881
4152
  // src/agents/qwen-agent.ts
3882
- import { OpenAI as OpenAI7 } from "openai";
4153
+ import { OpenAI as OpenAI9 } from "openai";
3883
4154
  var QwenAgent = class extends AbstractAgent {
3884
4155
  client;
3885
4156
  // A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
@@ -3904,7 +4175,7 @@ var QwenAgent = class extends AbstractAgent {
3904
4175
  };
3905
4176
  constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
3906
4177
  super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
3907
- this.client = new OpenAI7({
4178
+ this.client = new OpenAI9({
3908
4179
  apiKey,
3909
4180
  baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
3910
4181
  });
@@ -4079,7 +4350,7 @@ ${openAIMessages[0].content}`;
4079
4350
  };
4080
4351
 
4081
4352
  // src/agents/minimax-agent.ts
4082
- import { OpenAI as OpenAI8 } from "openai";
4353
+ import { OpenAI as OpenAI10 } from "openai";
4083
4354
  var MiniMaxAgent = class extends AbstractAgent {
4084
4355
  client;
4085
4356
  // A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
@@ -4104,7 +4375,7 @@ var MiniMaxAgent = class extends AbstractAgent {
4104
4375
  };
4105
4376
  constructor(name, instruction, model, apiKey, temperature, enableThinking = false, agentLoggingConfig = DEFAULT_LOGGING_CONFIG.agents) {
4106
4377
  super(name, instruction, model, temperature, enableThinking, agentLoggingConfig);
4107
- this.client = new OpenAI8({
4378
+ this.client = new OpenAI10({
4108
4379
  apiKey,
4109
4380
  baseURL: "https://api.minimax.io/v1"
4110
4381
  });
@@ -4341,10 +4612,12 @@ export {
4341
4612
  DeepSeekV2Agent,
4342
4613
  FUGU_REASONING_EFFORTS,
4343
4614
  FuguAgent,
4615
+ GEMINI_AUDIO_TOKENS_PER_SECOND,
4344
4616
  GEMINI_REASONING_EFFORTS,
4345
4617
  GLM_REASONING_EFFORTS,
4346
4618
  GlmAgent,
4347
4619
  GoogleAgent,
4620
+ GoogleVoiceAgent,
4348
4621
  Gpt5Agent,
4349
4622
  GrokAgent,
4350
4623
  KimiAgent,
@@ -4362,23 +4635,35 @@ export {
4362
4635
  ModelRefusalError,
4363
4636
  ModelUnavailableError,
4364
4637
  OPENAI_REASONING_EFFORTS,
4638
+ OpenAiVoiceAgent,
4365
4639
  QwenAgent,
4366
4640
  REASONING_EFFORT_SCALE,
4641
+ SUPPORTED_VOICE_PROVIDERS,
4367
4642
  SupportedAiKeyNames,
4368
4643
  SupportedAiModels,
4644
+ VOICE_MODEL_CONSTANTS,
4645
+ VOICE_MODEL_PRICING,
4646
+ VOICE_PROVIDER_API_KEY,
4647
+ VoiceAgentFactory,
4369
4648
  ZodSchemaConverter,
4649
+ buildGoogleTtsPrompt,
4370
4650
  calculateAnthropicCost,
4371
4651
  calculateCost,
4372
4652
  calculateDeepSeekCost,
4653
+ calculateGeminiSttCost,
4654
+ calculateGeminiTtsCost,
4373
4655
  calculateGoogleCost,
4374
4656
  calculateGrokCost,
4375
4657
  calculateKimiCost,
4376
4658
  calculateMistralCost,
4377
4659
  calculateModelCost,
4378
4660
  calculateOpenAICost,
4661
+ calculateOpenAiSttCost,
4662
+ calculateOpenAiTtsCost,
4379
4663
  clampReasoningEffort,
4380
4664
  cleanResponse,
4381
4665
  createCatalog,
4666
+ createVoiceAgent,
4382
4667
  extractAnthropicTokenUsage,
4383
4668
  extractTokenUsageFromResponse5 as extractAnthropicTokenUsageFromResponse,
4384
4669
  extractDeepSeekTokenUsage,
@@ -4396,6 +4681,8 @@ export {
4396
4681
  extractTokenUsageFromResponse as extractOpenAITokenUsageFromResponse,
4397
4682
  extractTokenUsage,
4398
4683
  extractUsageAndCalculateCost,
4684
+ generateGoogleTtsAudio,
4685
+ generateOpenAiTtsAudio,
4399
4686
  generateSchemaInstructions,
4400
4687
  getModelConfigByApiName,
4401
4688
  getModelDisplayName,
@@ -4412,6 +4699,7 @@ export {
4412
4699
  modelIsFast,
4413
4700
  needsPromptBasedSchema,
4414
4701
  parseAndValidateLlmJson,
4702
+ pcmToWav,
4415
4703
  safeValidateResponse,
4416
4704
  setLlmLogger,
4417
4705
  stableHashHex,
@@ -4423,6 +4711,8 @@ export {
4423
4711
  toGeminiEffort,
4424
4712
  toGlmEffort,
4425
4713
  toOpenAIEffort,
4714
+ transcribeWithGemini,
4715
+ transcribeWithOpenAi,
4426
4716
  validateResponse
4427
4717
  };
4428
4718
  //# sourceMappingURL=index.mjs.map