blob: 51cc9c369fe0c3fbd3a18bbaaecff8d60ea15f73 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Messages has no audio content type. Chat Completions supports WAV/MP3.
// Preserve an explicit observation instead of dropping media or fabricating bytes.
pub(super) fn audio_fallback(
messages: &mut [crate::prompt::Message],
language: maka_agent_facts::language::Language,
anthropic: bool,
) {
use crate::prompt::{ContentPart, FileData, Message, ToolOutput};
use maka_agent_facts::language::Language;
fn project(parts: &mut [ContentPart], language: Language, anthropic: bool) {
for part in parts {
if let ContentPart::File {
media_type,
data: FileData::Data(data),
..
} = part
&& media_type.starts_with("audio/")
&& (anthropic
|| !matches!(
media_type.as_str(),
"audio/wav" | "audio/mpeg" | "audio/mp3"
))
{
let length = data.len();
*part = ContentPart::text(match language {
Language::En => format!(
"Audio input ({media_type}, {length} base64 characters) is not supported by this model adapter. The audio remains in the tool evidence."
),
Language::ZhCn => format!(
"此模型适配器不支持音频输入({media_type},{length} 个 base64 字符)。音频仍保留在工具证据中。"
),
Language::ZhTw => format!(
"此模型介接器不支援音訊輸入({media_type},{length} 個 base64 字元)。音訊仍保留在工具證據中。"
),
});
}
}
}
for message in messages {
match message {
Message::User { content, .. } => project(content, language, anthropic),
Message::Tool { content, .. } => {
for result in content {
if let ToolOutput::Content(parts) = &mut result.output {
project(parts, language, anthropic);
}
}
}
_ => {}
}
}
}
#[cfg(test)]
mod language_tests {
use super::*;
use crate::prompt::{ContentPart, FileData, Message};
use maka_agent_facts::language::Language;
#[test]
fn unsupported_audio_reports_original_metadata_in_captured_language() {
for (language, expected) in [
(
Language::ZhCn,
"不支持音频输入(audio/ogg,8 个 base64 字符)",
),
(
Language::ZhTw,
"不支援音訊輸入(audio/ogg,8 個 base64 字元)",
),
] {
let mut messages = vec![Message::User {
content: vec![
ContentPart::text("Original user 原文"),
ContentPart::File {
data: FileData::Data("YXVkaW8=".into()),
media_type: "audio/ogg".into(),
provider_options: None,
},
],
provider_options: None,
}];
audio_fallback(&mut messages, language, false);
let Message::User { content, .. } = &messages[0] else {
panic!("user message")
};
assert_eq!(content[0], ContentPart::text("Original user 原文"));
let ContentPart::Text { text, .. } = &content[1] else {
panic!("unsupported audio observation")
};
assert!(text.contains(expected));
}
}
}