agentvibes 5.1.0 → 5.1.2

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.
@@ -10,21 +10,25 @@ param(
10
10
  [string]$Text,
11
11
 
12
12
  [Parameter(Mandatory = $false, Position = 1)]
13
- [string]$VoiceOverride
13
+ [string]$VoiceOverride,
14
+
15
+ [Parameter(Mandatory = $false)]
16
+ [string]$llm = ""
14
17
  )
15
18
 
16
19
  # Configuration paths
17
20
  # Priority: CLAUDE_PROJECT_DIR env var → script's parent project → user profile
21
+ # Local project settings ALWAYS override global (~/.claude)
18
22
  $ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
19
23
 
20
24
  if ($env:CLAUDE_PROJECT_DIR -and (Test-Path "$env:CLAUDE_PROJECT_DIR\.claude")) {
21
25
  $ClaudeDir = "$env:CLAUDE_PROJECT_DIR\.claude"
22
26
  } else {
23
27
  $PackageClaudeDir = Join-Path (Split-Path -Parent (Split-Path -Parent $ScriptPath)) ".claude"
24
- if (Test-Path "$env:USERPROFILE\.claude\tts-provider.txt") {
25
- $ClaudeDir = "$env:USERPROFILE\.claude"
26
- } elseif (Test-Path $PackageClaudeDir) {
28
+ if (Test-Path $PackageClaudeDir) {
27
29
  $ClaudeDir = $PackageClaudeDir
30
+ } elseif (Test-Path "$env:USERPROFILE\.claude\tts-provider.txt") {
31
+ $ClaudeDir = "$env:USERPROFILE\.claude"
28
32
  } else {
29
33
  $ClaudeDir = "$env:USERPROFILE\.claude"
30
34
  }
@@ -42,9 +46,88 @@ if (Test-Path $MuteFile) {
42
46
  }
43
47
  }
44
48
 
49
+ # Per-LLM config lookup: if --llm is passed, look up llm:<name> in audio-effects.cfg
50
+ # Format: llm:<name>|SOX_EFFECTS|BACKGROUND_FILE|BACKGROUND_VOLUME|VOICE|PRETEXT
51
+ $LlmVoice = ""
52
+ $LlmPretext = ""
53
+ $LlmReverb = ""
54
+ $LlmEngine = ""
55
+ $ProjectRoot = Split-Path -Parent $ClaudeDir
56
+ $ConfigDir = "$ClaudeDir\config"
57
+
58
+ if ($llm) {
59
+ $llmKey = "llm:$llm"
60
+ # Check project-local audio-effects.cfg first, then global
61
+ $cfgPaths = @(
62
+ "$ConfigDir\audio-effects.cfg",
63
+ "$env:USERPROFILE\.claude\config\audio-effects.cfg"
64
+ )
65
+ foreach ($cfgPath in $cfgPaths) {
66
+ if (-not $LlmVoice -and -not $LlmPretext -and (Test-Path $cfgPath)) {
67
+ foreach ($line in (Get-Content $cfgPath)) {
68
+ if ($line -match "^$([regex]::Escape($llmKey))\|") {
69
+ $parts = $line -split '\|'
70
+ # parts: [0]=key [1]=reverb_preset [2]=bg_file [3]=bg_vol [4]=voice [5]=pretext
71
+ if ($parts.Length -ge 2 -and $parts[1].Trim()) {
72
+ $LlmReverb = $parts[1].Trim()
73
+ }
74
+ if ($parts.Length -ge 5 -and $parts[4].Trim()) {
75
+ $LlmVoice = $parts[4].Trim()
76
+ }
77
+ if ($parts.Length -ge 6 -and $parts[5].Trim()) {
78
+ $LlmPretext = $parts[5].Trim()
79
+ }
80
+ if ($parts.Length -ge 7 -and $parts[6].Trim()) {
81
+ $LlmEngine = $parts[6].Trim()
82
+ }
83
+ break
84
+ }
85
+ }
86
+ }
87
+ }
88
+ # Apply LLM voice override (only if no explicit VoiceOverride was passed)
89
+ if ($LlmVoice -and -not $VoiceOverride) {
90
+ $VoiceOverride = $LlmVoice
91
+ }
92
+ # Export LLM key for child scripts (process-local, not system-wide)
93
+ $env:AGENTVIBES_LLM_KEY = "llm:$llm"
94
+ }
95
+
96
+ # Prepend pretext if configured
97
+ # Priority: LLM-specific pretext → project .agentvibes/config.json → project .claude/config/tts-pretext.txt
98
+ # → global ~/.agentvibes/config.json → global ~/.claude/config/tts-pretext.txt
99
+ $Pretext = $LlmPretext
100
+ if (-not $Pretext) {
101
+ $PretextSources = @(
102
+ (Join-Path $ProjectRoot ".agentvibes\config.json"),
103
+ "$ClaudeDir\config\tts-pretext.txt",
104
+ "$env:USERPROFILE\.agentvibes\config.json",
105
+ "$env:USERPROFILE\.claude\config\tts-pretext.txt"
106
+ )
107
+ foreach ($src in $PretextSources) {
108
+ if (-not $Pretext -and (Test-Path $src)) {
109
+ if ($src -match '\.json$') {
110
+ try {
111
+ $avCfg = Get-Content $src -Raw | ConvertFrom-Json
112
+ if ($avCfg.pretext) { $Pretext = $avCfg.pretext.Trim() }
113
+ } catch { }
114
+ } else {
115
+ $val = (Get-Content $src -Raw).Trim()
116
+ if ($val) { $Pretext = $val }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ if ($Pretext) {
122
+ $Text = "$Pretext, $Text"
123
+ }
124
+
45
125
  # Determine active provider
126
+ # LLM-specific engine overrides global provider
46
127
  $ActiveProvider = "sapi"
47
- if (Test-Path $ProviderFile) {
128
+ if ($LlmEngine) {
129
+ $ActiveProvider = $LlmEngine
130
+ } elseif (Test-Path $ProviderFile) {
48
131
  $ActiveProvider = (Get-Content $ProviderFile -Raw).Trim()
49
132
  }
50
133
 
@@ -101,12 +184,17 @@ if (Test-Path $AgentVibesConfig) {
101
184
  }
102
185
 
103
186
  # Check if reverb is enabled (allowlist validation)
187
+ # LLM-specific reverb overrides global setting
104
188
  $ReverbLevel = "off"
105
- $ReverbFile = "$ConfigDir\reverb-level.txt"
106
- if (Test-Path $ReverbFile) {
107
- $reverbVal = (Get-Content $ReverbFile -Raw).Trim()
108
- if ($reverbVal -in @("off", "light", "medium", "heavy", "cathedral")) {
109
- $ReverbLevel = $reverbVal
189
+ if ($LlmReverb -and $LlmReverb -in @("off", "light", "medium", "heavy", "cathedral")) {
190
+ $ReverbLevel = $LlmReverb
191
+ } else {
192
+ $ReverbFile = "$ConfigDir\reverb-level.txt"
193
+ if (Test-Path $ReverbFile) {
194
+ $reverbVal = (Get-Content $ReverbFile -Raw).Trim()
195
+ if ($reverbVal -in @("off", "light", "medium", "heavy", "cathedral")) {
196
+ $ReverbLevel = $reverbVal
197
+ }
110
198
  }
111
199
  }
112
200
  $HasReverb = $ReverbLevel -ne "off"
@@ -133,10 +221,6 @@ $PreSynthWav = $env:AGENTVIBES_PRESYNTHESIZED_WAV
133
221
  $UsePreSynth = $PreSynthWav -and (Test-Path $PreSynthWav) -and
134
222
  (Get-Item $PreSynthWav -ErrorAction SilentlyContinue).Length -gt 0
135
223
 
136
- # Tracks the path of the WAV the provider just synthesized.
137
- # Used to defend against playing stale cached audio when synthesis silently fails.
138
- $SynthesizedWavPath = $null
139
-
140
224
  # If background music or reverb enabled and ffmpeg available, tell provider to skip playback
141
225
  if (($BgEnabled -or $HasReverb) -and $HasFfmpeg) {
142
226
  $env:AGENTVIBES_NO_PLAY = "1"
@@ -171,25 +255,17 @@ if ($UsePreSynth) {
171
255
  $providerOutput = & $ProviderScript $Text 6>&1 2>&1
172
256
  }
173
257
  # Re-emit preserving colors from InformationRecords (Write-Host output)
174
- # Also extract the synthesized WAV path from the provider's OK line.
175
258
  foreach ($item in $providerOutput) {
176
- $lineText = $null
177
259
  if ($item -is [System.Management.Automation.InformationRecord]) {
178
260
  $msg = $item.MessageData
179
261
  if ($msg -is [System.Management.Automation.HostInformationMessage]) {
180
262
  Write-Host $msg.Message -ForegroundColor $msg.ForegroundColor -NoNewline:$msg.NoNewLine
181
263
  if (-not $msg.NoNewLine) { Write-Host }
182
- $lineText = $msg.Message
183
264
  } else {
184
265
  Write-Host "$item"
185
- $lineText = "$item"
186
266
  }
187
267
  } else {
188
268
  Write-Host "$item"
189
- $lineText = "$item"
190
- }
191
- if ($lineText -and $lineText -match '\[OK\]\s+Saved to:\s+(.+\.wav)') {
192
- $SynthesizedWavPath = $Matches[1].Trim()
193
269
  }
194
270
  }
195
271
  } else {
@@ -211,23 +287,13 @@ if ($UsePreSynth) {
211
287
  if (($BgEnabled -or $HasReverb) -and $HasFfmpeg) {
212
288
  Remove-Item env:AGENTVIBES_NO_PLAY -ErrorAction SilentlyContinue
213
289
 
214
- # Find the WAV to post-process. Never fall back to "most recent on disk"
215
- # because that plays a random stale cache file when synthesis silently fails.
290
+ # Find the WAV to post-process: use pre-synthesized file if available, else most recent
216
291
  $AudioDir = "$ClaudeDir\audio"
217
- $RecentWav = $null
218
- if ($UsePreSynth) {
219
- $RecentWav = Get-Item $PreSynthWav -ErrorAction SilentlyContinue
220
- }
221
- elseif ($SynthesizedWavPath -and (Test-Path $SynthesizedWavPath)) {
222
- $cand = Get-Item $SynthesizedWavPath -ErrorAction SilentlyContinue
223
- if ($cand -and $cand.Length -gt 0) {
224
- $RecentWav = $cand
225
- }
226
- }
227
- if (-not $RecentWav) {
228
- Write-Host "[ERROR] No fresh synthesized WAV - refusing stale cache" -ForegroundColor Red
229
- Remove-Item env:AGENTVIBES_NO_PLAY -ErrorAction SilentlyContinue
230
- exit 1
292
+ $RecentWav = if ($UsePreSynth) {
293
+ Get-Item $PreSynthWav -ErrorAction SilentlyContinue
294
+ } else {
295
+ Get-ChildItem -Path $AudioDir -Filter "tts-*.wav" -ErrorAction SilentlyContinue |
296
+ Sort-Object LastWriteTime -Descending | Select-Object -First 1
231
297
  }
232
298
 
233
299
  if ($RecentWav -and $RecentWav.Length -gt 0) {
@@ -263,6 +329,7 @@ if (($BgEnabled -or $HasReverb) -and $HasFfmpeg) {
263
329
  if (Test-Path $AudioEffectsCfg) {
264
330
  # Try agent-specific config first, then fall back to default
265
331
  # Format: AGENT_NAME|SOX_EFFECTS|BACKGROUND_FILE|BACKGROUND_VOLUME
332
+ # Lookup order: agent name → llm:<name> → default
266
333
  $agentName = $env:AGENTVIBES_AGENT_NAME
267
334
  $configLine = $null
268
335
 
@@ -275,6 +342,16 @@ if (($BgEnabled -or $HasReverb) -and $HasFfmpeg) {
275
342
  }
276
343
  }
277
344
  }
345
+ # Try LLM-specific config (--llm parameter)
346
+ if (-not $configLine -and $llm) {
347
+ $llmBgKey = "llm:$llm"
348
+ foreach ($line in $cfgLines) {
349
+ if ($line -match "^$([regex]::Escape($llmBgKey))\|") {
350
+ $configLine = $line
351
+ break
352
+ }
353
+ }
354
+ }
278
355
  # Fall back to default
279
356
  if (-not $configLine) {
280
357
  foreach ($line in $cfgLines) {
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
  [![Publish](https://github.com/paulpreibisch/AgentVibes/actions/workflows/publish.yml/badge.svg)](https://github.com/paulpreibisch/AgentVibes/actions/workflows/publish.yml)
12
12
  [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
13
13
 
14
- **Author**: Paul Preibisch ([@997Fire](https://x.com/997Fire)) | **Version**: v5.1.0
14
+ **Author**: Paul Preibisch ([@997Fire](https://x.com/997Fire)) | **Version**: v5.1.2
15
15
 
16
16
  ---
17
17
 
@@ -43,6 +43,22 @@ Whether you're using Claude Code, GitHub Copilot, OpenAI Codex, Claude Desktop,
43
43
 
44
44
  ---
45
45
 
46
+ ## 🔀 v5.1.2 — MCP Per-LLM Routing Hotfix
47
+
48
+ - **MCP server now reads `AGENTVIBES_LLM` env var** instead of hardcoding `copilot` — Codex / Copilot / Claude Code each get routed to their own per-LLM voice / pretext / music / effects config from `audio-effects.cfg`.
49
+ - **MCP launcher templates set the env var** automatically — `.codex/config.toml`, `.vscode/mcp.json`, and `.mcp.json` all include `AGENTVIBES_LLM` for the right provider.
50
+ - **24 new regression tests** prevent this class of bug from shipping again, including a `npm pack` content guard that fails the test suite if the working tree has uncommitted changes (the v5.1.0 disaster guard).
51
+
52
+ If you already have AgentVibes installed, re-run the per-provider configure step or add `"env": { "AGENTVIBES_LLM": "<your-llm>" }` manually to your MCP config.
53
+
54
+ ---
55
+
56
+ ## 🩹 v5.1.1 — Windows TTS Hook Hotfix
57
+
58
+ - **`play-tts.ps1 -llm` parameter restored** — npm-published v5.1.0 shipped a regressed copy without `-llm` support, breaking the Setup tab Preview button and the agentvibes MCP `text_to_speech` tool on Windows. Fixed in v5.1.1. If you hit the error, clear your npx cache: `npm cache clean --force` then reinstall.
59
+
60
+ ---
61
+
46
62
  ## 🎙️ NEW IN v5.1.0 — Voice Picker Overhaul + Auto-Save Agent Modal
47
63
 
48
64
  - **Auto-save in agent modal** — Voice/personality/music/reverb/pretext changes save automatically as you edit them. Brief "✓ Saved!" toast confirms each change.
package/RELEASE_NOTES.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # AgentVibes Release Notes
2
2
 
3
+ ## 🔀 v5.1.2 — MCP Per-LLM Routing Hotfix
4
+
5
+ **Release Date:** April 2026
6
+
7
+ ### Bug Fixes
8
+
9
+ - **MCP server no longer hardcodes `-llm copilot`** — `mcp-server/server.py` was passing `-llm copilot` for every caller, regardless of whether the actual client was Codex, Copilot, or Claude Code. This meant per-LLM voice/pretext/music routing in `audio-effects.cfg` was effectively broken: all three providers fell through to the same `llm:copilot` lookup (or worse, the global default config). The server now reads `AGENTVIBES_LLM` from the environment and forwards that as the `-llm` value, falling back to no `-llm` flag if unset.
10
+
11
+ - **MCP launcher templates set `AGENTVIBES_LLM`** — Each provider's MCP config now sets the env var so the server knows which LLM is calling:
12
+ - Codex: `.codex/config.toml` → `env = { AGENTVIBES_LLM = "codex" }`
13
+ - Copilot: `.vscode/mcp.json` → `"env": { "AGENTVIBES_LLM": "copilot" }`
14
+ - Claude Code: `.mcp.json` → `"env": { "AGENTVIBES_LLM": "claude-code" }`
15
+
16
+ Both freshly-installed configs and the manual-instruction snippets shown by the installer include the env var.
17
+
18
+ ### Testing & Hardening
19
+
20
+ - **24 new regression tests** in `test/unit/llm-provider-mcp-routing.test.js` and `test/unit/npm-pack-contents.test.js` enforce the contract end-to-end:
21
+ - Each MCP launcher template MUST set `AGENTVIBES_LLM` to the correct value
22
+ - `mcp-server/server.py` MUST read `AGENTVIBES_LLM` from env and MUST NOT hardcode `-llm copilot`
23
+ - `play-tts.ps1` MUST declare its `$llm` parameter, contain per-LLM lookup logic, export `AGENTVIBES_LLM_KEY`, and be at least 400 lines (catches the v5.1.0 mass-deletion regression)
24
+ - `play-tts.sh` MUST parse `--llm` and do per-LLM lookup against `audio-effects.cfg`
25
+ - **Working tree must be clean** before publishing (the v5.1.0 disaster guard — `npm publish` packs the working tree, not the git tag, so any uncommitted local edits get shipped)
26
+
27
+ - The contract tests are **mutation-tested**: temporarily replacing `play-tts.ps1` with a broken stub fires 4 assertions with clear messages, proving the exact v5.1.0 regression would now block publish.
28
+
29
+ ### How to Update
30
+
31
+ ```
32
+ npm cache clean --force
33
+ npx --yes agentvibes@5.1.2
34
+ ```
35
+
36
+ If you already have AgentVibes installed for one or more providers, re-run the installer's per-provider configure step (or manually add `"env": { "AGENTVIBES_LLM": "<your-llm>" }` to your `.mcp.json` / `.vscode/mcp.json` / `.codex/config.toml`).
37
+
38
+ ---
39
+
40
+ ## 🩹 v5.1.1 — Windows TTS Hook Hotfix
41
+
42
+ **Release Date:** April 2026
43
+
44
+ ### Bug Fixes
45
+
46
+ - **Windows `play-tts.ps1` `-llm` parameter restored** — A regression caused the npm-published v5.1.0 package to ship a `play-tts.ps1` that lacked the `-llm` parameter and the per-LLM config lookup. Per-LLM TTS routing on Windows failed with `A parameter cannot be found that matches parameter name 'llm'`. This affected:
47
+ - **Setup tab Preview button** for any provider configured with per-LLM voice/effects
48
+ - **agentvibes MCP `text_to_speech` tool** when called from Codex / Copilot / Claude Code
49
+ - Any code path that invokes `play-tts.ps1 ... -llm <provider>`
50
+
51
+ The git tag `v5.1.0` had the correct file all along — only the npm tarball was affected, because `npm publish` packs the working tree (which contained an uncommitted local regression) instead of the git tag.
52
+
53
+ ### How to Update
54
+
55
+ If you installed v5.1.0 from npm and hit the `-llm` error, clear your npx cache and reinstall:
56
+
57
+ ```
58
+ npm cache clean --force
59
+ npx --yes agentvibes@5.1.1
60
+ ```
61
+
62
+ ### Note for Maintainers
63
+
64
+ To prevent this kind of working-tree-vs-tag drift in future releases, the release workflow should run `npm publish` from a freshly checked-out clone of the tag, not from the development working directory.
65
+
66
+ ---
67
+
3
68
  ## 🎙️ v5.1.0 — Voice Picker Overhaul + Auto-Save Agent Modal
4
69
 
5
70
  **Release Date:** April 2026
@@ -194,18 +194,33 @@ class AgentVibesServer:
194
194
  original_language = await self._get_language()
195
195
  await self._run_script(self.LANGUAGE_MANAGER_SCRIPT, ["set", language])
196
196
 
197
- # Call the TTS script via appropriate shell
197
+ # Call the TTS script via appropriate shell.
198
+ #
199
+ # The LLM key is read from the AGENTVIBES_LLM env var so each
200
+ # caller (Claude Code, GitHub Copilot, OpenAI Codex) gets routed
201
+ # to its own per-LLM voice / pretext / music / effects config.
202
+ # The MCP launcher in each provider's config file should set
203
+ # this env var (e.g. .codex/config.toml [mcp_servers.agentvibes]
204
+ # env = { AGENTVIBES_LLM = "codex" }).
205
+ #
206
+ # If unset, no -llm flag is passed and play-tts falls back to
207
+ # the project / global default config — which is the correct
208
+ # behavior for ad-hoc / unconfigured callers.
209
+ llm_key = os.environ.get("AGENTVIBES_LLM", "").strip()
198
210
  tts_script = "play-tts.ps1" if self.is_windows else "play-tts.sh"
199
211
  play_tts = self.hooks_dir / tts_script
200
212
  if self.is_windows:
201
- args = ["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", str(play_tts), text, "-llm", "copilot"]
213
+ args = ["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", str(play_tts), text]
202
214
  if voice:
203
215
  args.extend(["-VoiceOverride", voice])
216
+ if llm_key:
217
+ args.extend(["-llm", llm_key])
204
218
  else:
205
219
  args = ["bash", str(play_tts), text]
206
220
  if voice:
207
221
  args.append(voice)
208
- args.extend(["--llm", "copilot"])
222
+ if llm_key:
223
+ args.extend(["--llm", llm_key])
209
224
 
210
225
  env = self._build_script_env()
211
226
  # Set agent name for audio effects lookup (audio-effects.cfg, background music config)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "agentvibes",
4
- "version": "5.1.0",
4
+ "version": "5.1.2",
5
5
  "description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code, Claude Desktop (via MCP), and Clawdbot with multi-provider support.",
6
6
  "homepage": "https://agentvibes.org",
7
7
  "keywords": [
package/src/installer.js CHANGED
@@ -4297,12 +4297,15 @@ function isPathSafe(targetPath, basePath) {
4297
4297
  async function handleMcpConfiguration(targetDir, options) {
4298
4298
  const mcpConfigPath = path.join(targetDir, '.mcp.json');
4299
4299
 
4300
- // MCP server configuration for AgentVibes
4300
+ // MCP server configuration for AgentVibes.
4301
+ // The AGENTVIBES_LLM env var tells the MCP server which LLM is calling
4302
+ // so per-LLM voice / pretext / music / effects routing works correctly.
4301
4303
  const mcpConfig = {
4302
4304
  mcpServers: {
4303
4305
  agentvibes: {
4304
4306
  command: 'npx',
4305
- args: ['-y', '--package=agentvibes', 'agentvibes-mcp-server']
4307
+ args: ['-y', '--package=agentvibes', 'agentvibes-mcp-server'],
4308
+ env: { AGENTVIBES_LLM: 'claude-code' }
4306
4309
  }
4307
4310
  }
4308
4311
  };
@@ -4337,7 +4340,8 @@ async function handleMcpConfiguration(targetDir, options) {
4337
4340
  console.log(
4338
4341
  '\n"agentvibes": {\n' +
4339
4342
  ' "command": "npx",\n' +
4340
- ' "args": ["-y", "--package=agentvibes", "agentvibes-mcp-server"]\n' +
4343
+ ' "args": ["-y", "--package=agentvibes", "agentvibes-mcp-server"],\n' +
4344
+ ' "env": { "AGENTVIBES_LLM": "claude-code" }\n' +
4341
4345
  '}\n'
4342
4346
  );
4343
4347
 
@@ -4442,7 +4446,8 @@ async function handleMcpConfiguration(targetDir, options) {
4442
4446
  ' "mcpServers": {\n' +
4443
4447
  ' "agentvibes": {\n' +
4444
4448
  ' "command": "npx",\n' +
4445
- ' "args": ["-y", "--package=agentvibes", "agentvibes-mcp-server"]\n' +
4449
+ ' "args": ["-y", "--package=agentvibes", "agentvibes-mcp-server"],\n' +
4450
+ ' "env": { "AGENTVIBES_LLM": "claude-code" }\n' +
4446
4451
  ' }\n' +
4447
4452
  ' }\n' +
4448
4453
  '}\n'
@@ -228,6 +228,9 @@ export async function installCopilotMcp(targetDir) {
228
228
  type: 'stdio',
229
229
  command: 'npx',
230
230
  args: ['-y', '--package=agentvibes', 'agentvibes-mcp-server'],
231
+ // Tells the MCP server which LLM is calling so per-LLM voice / pretext
232
+ // / music / effects routing in audio-effects.cfg works correctly.
233
+ env: { AGENTVIBES_LLM: 'copilot' },
231
234
  };
232
235
 
233
236
  try {
@@ -337,6 +340,9 @@ export function buildCodexToml(existingContent = '') {
337
340
  '[mcp_servers.agentvibes]',
338
341
  'command = "npx"',
339
342
  'args = ["-y", "--package=agentvibes", "agentvibes-mcp-server"]',
343
+ // Tells the MCP server which LLM is calling so per-LLM voice / pretext
344
+ // / music / effects routing in audio-effects.cfg works correctly.
345
+ 'env = { AGENTVIBES_LLM = "codex" }',
340
346
  ].join('\n');
341
347
 
342
348
  if (!existingContent.trim()) return serverBlock + '\n';