mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-04 16:37:46 +08:00
feat(codex): 按操作语义路由 Responses V2 压缩
(cherry picked from commit 2fc604e047)
This commit is contained in:
@@ -8,6 +8,34 @@ pub mod stream;
|
||||
|
||||
const TOOL_ERROR_PREFIX: &str = "[tool error]";
|
||||
|
||||
/// Semantic operation carried by an OpenAI Responses request that asks the
|
||||
/// service to compact a thread. The request still uses the Responses wire
|
||||
/// contract and transport endpoint.
|
||||
pub const OPENAI_RESPONSES_OPERATION_COMPACT: &str = "compact";
|
||||
|
||||
/// Resolves the operation expressed by an OpenAI Responses wire request.
|
||||
///
|
||||
/// `responses_compaction_v2` is represented by a `compaction_trigger` input
|
||||
/// item on the normal Responses request. The legacy Compact API format is
|
||||
/// retained as the same operation for observability and scoped model mapping.
|
||||
pub fn openai_responses_request_operation(api_format: &str, body: &Value) -> Option<&'static str> {
|
||||
if aether_ai_formats::is_openai_responses_compact_format(api_format) {
|
||||
return Some(OPENAI_RESPONSES_OPERATION_COMPACT);
|
||||
}
|
||||
if !aether_ai_formats::is_openai_responses_format(api_format) {
|
||||
return None;
|
||||
}
|
||||
|
||||
body.get("input")
|
||||
.and_then(Value::as_array)
|
||||
.is_some_and(|items| {
|
||||
items
|
||||
.iter()
|
||||
.any(|item| item.get("type").and_then(Value::as_str) == Some("compaction_trigger"))
|
||||
})
|
||||
.then_some(OPENAI_RESPONSES_OPERATION_COMPACT)
|
||||
}
|
||||
|
||||
fn encode_tool_result_error(output: Value, is_error: bool) -> Value {
|
||||
if !is_error {
|
||||
return output;
|
||||
@@ -23,3 +51,41 @@ fn encode_tool_result_error(output: Value, is_error: bool) -> Value {
|
||||
Value::String(format!("{TOOL_ERROR_PREFIX}\n{detail}"))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
|
||||
use super::{openai_responses_request_operation, OPENAI_RESPONSES_OPERATION_COMPACT};
|
||||
|
||||
#[test]
|
||||
fn resolves_compaction_trigger_as_compact_operation_on_responses_transport() {
|
||||
assert_eq!(
|
||||
openai_responses_request_operation(
|
||||
"openai:responses",
|
||||
&json!({
|
||||
"input": [
|
||||
{"role": "user", "content": "keep working"},
|
||||
{"type": "compaction_trigger"}
|
||||
]
|
||||
}),
|
||||
),
|
||||
Some(OPENAI_RESPONSES_OPERATION_COMPACT)
|
||||
);
|
||||
assert_eq!(
|
||||
openai_responses_request_operation(
|
||||
"openai:responses",
|
||||
&json!({"input": [{"role": "user", "content": "keep working"}]}),
|
||||
),
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolves_legacy_compact_contract_without_a_body_marker() {
|
||||
assert_eq!(
|
||||
openai_responses_request_operation("openai:responses:compact", &json!({})),
|
||||
Some(OPENAI_RESPONSES_OPERATION_COMPACT)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,9 @@ pub use formats::openai::responses::codex::{
|
||||
pub use formats::openai::responses::request::{
|
||||
validate_openai_responses_request_contract, OpenAiResponsesRequestContractViolation,
|
||||
};
|
||||
pub use formats::openai::responses::{
|
||||
openai_responses_request_operation, OPENAI_RESPONSES_OPERATION_COMPACT,
|
||||
};
|
||||
pub use formats::registry::{
|
||||
build_stream_transcoder, convert_request, convert_request_pure,
|
||||
convert_request_pure_with_context, convert_response, convert_response_pure, emit_request_pure,
|
||||
|
||||
Reference in New Issue
Block a user