transcribeAudioTool function
Creates the transcribe_audio tool.
Parameters:
path(string, required): path to the audio file.language(string, optional): ISO-639-1 language hint, overriding the configured default.
Implementation
AgentTool transcribeAudioTool(ExecutionEnv env, TranscribeAudioConfig config) {
return AgentTool(
name: 'transcribe_audio',
label: 'transcribe_audio',
tier: ApprovalTier.read,
description:
'Transcribe a local audio file to text using a Whisper-compatible '
'transcription endpoint. Returns the transcript; the audio itself '
'does not enter the chat context. Supported formats: WAV, MP3, M4A, '
'OGG, WebM, FLAC. Maximum file size: 25MB.',
parameters: const {
'type': 'object',
'properties': {
'path': {
'type': 'string',
'description': 'Path to the audio file (relative or absolute)',
},
'language': {
'type': 'string',
'description':
'Optional ISO-639-1 language hint (e.g. "en", "de"); overrides '
'the configured default',
},
},
'required': ['path'],
},
execute: (arguments, cancelToken, onUpdate) async {
cancelToken?.throwIfCancelled();
final path = arguments['path'] as String;
final language = (arguments['language'] as String?) ?? config.language;
final filename = path.split(RegExp(r'[/\\]')).last;
final dot = filename.lastIndexOf('.');
final extension = dot >= 0
? filename.substring(dot + 1).toLowerCase()
: '';
if (!supportedAudioExtensions.contains(extension)) {
throw StateError(
'Unsupported audio format: $filename (supported: '
'${(supportedAudioExtensions.toList()..sort()).join(', ')})',
);
}
final read = await env.readBinaryFile(path);
if (read.isErr) {
throw StateError('${read.errorOrNull}');
}
final bytes = read.valueOrNull!;
cancelToken?.throwIfCancelled();
if (bytes.length > maxTranscribeAudioBytes) {
throw StateError(
'Audio file too large: ${bytes.length} bytes exceeds the 25MB '
'transcription limit',
);
}
final transcript = await _transcribe(config, bytes, filename, language);
return ToolExecutionResult(content: [TextContent(text: transcript)]);
},
);
}