#8014: fix(media-understanding): support legacy {file} placeholder in CLI audio args
size: S
experienced-contributor
Cluster:
Media Handling Improvements
## Summary
Clean cherry-pick of #5925 - contains only the `{file}` placeholder fix without the 70+ unrelated commits.
Adds `normalizePlaceholders()` to convert intuitive single-brace placeholders to the standard double-brace format before template substitution.
## Problem
When using `tools.media.audio.models` with `type: "cli"`, the `{file}` placeholder in the `args` array was passed literally instead of being substituted with the actual audio file path.
```json
{
"tools": {
"media": {
"audio": {
"models": [{
"type": "cli",
"command": "whisper",
"args": ["{file}", "--model", "large-v3-turbo"]
}]
}
}
}
}
```
Error: `Error opening input file {file}.`
## Solution
Add legacy placeholder normalization that converts intuitive single-brace placeholders before `applyTemplate()` is called.
### Supported aliases:
- `{file}`, `{input}`, `{media}` → `{{MediaPath}}`
- `{output}`, `{output_dir}` → `{{OutputDir}}`
- `{output_base}` → `{{OutputBase}}`
- `{prompt}` → `{{Prompt}}`
- `{media_dir}` → `{{MediaDir}}`
Case-insensitive matching for user convenience.
## Testing
- Added comprehensive unit tests for `normalizePlaceholders()`
- All tests pass
- Build verified
## Replaces
This is a clean version of #5925, which had accumulated 70+ commits from various merges. This PR contains only the essential fix.
Fixes #5845
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR fixes CLI media-audio arg templating by normalizing legacy single-brace placeholders like `{file}`/`{output}` into the existing double-brace template format (e.g. `{{MediaPath}}`) before calling `applyTemplate()` in `runCliEntry`.
A new unit test file was added to validate placeholder normalization behavior across aliases and case-insensitive inputs.
<h3>Confidence Score: 2/5</h3>
- Not safe to merge as-is due to a parsing/compilation issue in the main runner module.
- The new helper is placed before an `import type` block in `runner.ts`, which is invalid in ESM/TypeScript and should break builds. The functional change is otherwise small and well-scoped, but the current file structure needs correction and the tests currently validate a duplicated implementation rather than the production one.
- src/media-understanding/runner.ts; src/media-understanding/runner.placeholders.test.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#8388: fix(media): auto-skip tiny/empty audio files before transcription (...
by Glucksberg · 2026-02-04
76.0%
#18811: fix(media): require file extension for ambiguous MEDIA: path detection
by aldoeliacim · 2026-02-17
75.6%
#14794: fix: parse inline MEDIA: tokens in agent replies
by explainanalyze · 2026-02-12
75.5%
#5040: fix(config): migrate audio.transcription with any CLI command
by shayan919293 · 2026-01-31
75.4%
#9177: feat(media): add parakeet-mlx CLI output support
by mac-110 · 2026-02-04
75.0%
#18890: fix(media): parse tool-result MEDIA directives with shared parser
by teededung · 2026-02-17
74.8%
#9817: fix(media): resolve relative paths before reading local files (#8759)
by lailoo · 2026-02-05
74.4%
#19868: fix: prevent media token regex from matching markdown bold text
by sanketgautam · 2026-02-18
74.3%
#21110: fix(tts): deliver audio via structured mediaUrl instead of MEDIA: t...
by hydro13 · 2026-02-19
73.5%
#22178: test(web): allow fixture roots in media local file tests
by Kansodata · 2026-02-20
73.5%