mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
migrate ai format conversion to responses adapters
This commit is contained in:
@@ -534,8 +534,8 @@ async fn gateway_locally_denies_openai_responses_after_execution_runtime_miss_wi
|
||||
assert_ai_route_locally_denied_after_execution_runtime_miss(
|
||||
"/v1/responses",
|
||||
"openai",
|
||||
"cli",
|
||||
"openai:cli",
|
||||
"responses",
|
||||
"openai:responses",
|
||||
"{\"model\":\"gpt-5\",\"input\":\"hello\"}",
|
||||
"请求缺少有效的用户或 API Key 认证上下文,无法选择上游提供商",
|
||||
)
|
||||
@@ -562,8 +562,8 @@ async fn gateway_locally_denies_openai_responses_stream_after_execution_runtime_
|
||||
assert_ai_route_locally_denied_after_execution_runtime_miss(
|
||||
"/v1/responses",
|
||||
"openai",
|
||||
"cli",
|
||||
"openai:cli",
|
||||
"responses",
|
||||
"openai:responses",
|
||||
"{\"model\":\"gpt-5\",\"input\":\"hello\",\"stream\":true}",
|
||||
"请求缺少有效的用户或 API Key 认证上下文,无法选择上游提供商",
|
||||
)
|
||||
@@ -590,8 +590,8 @@ async fn gateway_locally_denies_openai_compact_after_execution_runtime_miss_with
|
||||
assert_ai_route_locally_denied_after_execution_runtime_miss(
|
||||
"/v1/responses/compact",
|
||||
"openai",
|
||||
"compact",
|
||||
"openai:compact",
|
||||
"responses:compact",
|
||||
"openai:responses:compact",
|
||||
"{\"model\":\"gpt-5\",\"input\":\"hello\"}",
|
||||
"请求缺少有效的用户或 API Key 认证上下文,无法选择上游提供商",
|
||||
)
|
||||
@@ -604,8 +604,8 @@ async fn gateway_locally_denies_openai_compact_stream_after_execution_runtime_mi
|
||||
assert_ai_route_locally_denied_after_execution_runtime_miss(
|
||||
"/v1/responses/compact",
|
||||
"openai",
|
||||
"compact",
|
||||
"openai:compact",
|
||||
"responses:compact",
|
||||
"openai:responses:compact",
|
||||
"{\"model\":\"gpt-5\",\"input\":\"hello\",\"stream\":true}",
|
||||
"请求缺少有效的用户或 API Key 认证上下文,无法选择上游提供商",
|
||||
)
|
||||
|
||||
@@ -442,6 +442,7 @@ async fn gateway_executes_openai_cli_sync_via_local_decision_gate_with_local_syn
|
||||
.await
|
||||
.expect("request should succeed");
|
||||
|
||||
eprintln!("codex oauth response status: {}", response.status());
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
response
|
||||
|
||||
@@ -479,7 +479,7 @@ fn ai_pipeline_candidate_preparation_owns_shared_auth_and_mapped_model_resolutio
|
||||
|
||||
for path in [
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision/request.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/request.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/request.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/image/request.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/request.rs",
|
||||
] {
|
||||
@@ -555,7 +555,7 @@ fn ai_pipeline_candidate_materialization_owns_affinity_and_candidate_runtime_per
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/candidates.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/passthrough/provider/family/candidates.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/files/support.rs",
|
||||
] {
|
||||
@@ -586,7 +586,7 @@ fn ai_pipeline_candidate_materialization_owns_affinity_and_candidate_runtime_per
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/passthrough/provider/family/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/files/support.rs",
|
||||
] {
|
||||
@@ -611,8 +611,8 @@ fn ai_pipeline_candidate_materialization_owns_affinity_and_candidate_runtime_per
|
||||
"LocalExecutionCandidateAttempt as LocalOpenAiChatCandidateAttempt",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"LocalExecutionCandidateAttempt as LocalOpenAiCliCandidateAttempt",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"LocalExecutionCandidateAttempt as LocalOpenAiResponsesCandidateAttempt",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/support.rs",
|
||||
@@ -649,7 +649,7 @@ fn ai_pipeline_materialization_policy_owns_local_candidate_persistence_modes() {
|
||||
"LocalCandidatePersistencePolicyKind::StandardDecision",
|
||||
"LocalCandidatePersistencePolicyKind::SameFormatProviderDecision",
|
||||
"LocalCandidatePersistencePolicyKind::OpenAiChatDecision",
|
||||
"LocalCandidatePersistencePolicyKind::OpenAiCliDecision",
|
||||
"LocalCandidatePersistencePolicyKind::OpenAiResponsesDecision",
|
||||
"LocalCandidatePersistencePolicyKind::GeminiFilesDecision",
|
||||
"LocalCandidatePersistencePolicyKind::VideoDecision",
|
||||
] {
|
||||
@@ -663,7 +663,7 @@ fn ai_pipeline_materialization_policy_owns_local_candidate_persistence_modes() {
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/candidates.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/passthrough/provider/family/candidates.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/files/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/payload.rs",
|
||||
@@ -716,7 +716,7 @@ fn ai_pipeline_candidate_metadata_owns_local_execution_candidate_extra_data_shap
|
||||
for path in [
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/candidates.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/passthrough/provider/family/candidates.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/files/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/support.rs",
|
||||
@@ -1116,7 +1116,7 @@ fn ai_pipeline_payload_metadata_owns_local_execution_decision_response_shape() {
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/passthrough/provider/family/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/decision.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/files/decision.rs",
|
||||
] {
|
||||
@@ -1156,7 +1156,7 @@ fn ai_pipeline_report_context_owns_local_execution_context_shape() {
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/passthrough/provider/family/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/payload.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/decision.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/files/decision.rs",
|
||||
] {
|
||||
@@ -1188,13 +1188,13 @@ fn ai_pipeline_standard_attempts_consume_eligible_local_candidates_without_trans
|
||||
"openai chat attempts should reuse shared LocalExecutionCandidateAttempt"
|
||||
);
|
||||
|
||||
let openai_cli_support = read_workspace_file(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
let openai_responses_support = read_workspace_file(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
);
|
||||
assert!(
|
||||
openai_cli_support
|
||||
.contains("LocalExecutionCandidateAttempt as LocalOpenAiCliCandidateAttempt"),
|
||||
"openai cli attempts should reuse shared LocalExecutionCandidateAttempt"
|
||||
openai_responses_support
|
||||
.contains("LocalExecutionCandidateAttempt as LocalOpenAiResponsesCandidateAttempt"),
|
||||
"openai responses attempts should reuse shared LocalExecutionCandidateAttempt"
|
||||
);
|
||||
|
||||
let standard_family_mod =
|
||||
@@ -1208,7 +1208,7 @@ fn ai_pipeline_standard_attempts_consume_eligible_local_candidates_without_trans
|
||||
for path in [
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision/request.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/request.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/request.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/request.rs",
|
||||
] {
|
||||
let source = read_workspace_file(path);
|
||||
@@ -1266,7 +1266,7 @@ fn ai_pipeline_candidate_sources_share_cross_format_auth_filter_helper() {
|
||||
|
||||
for path in [
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/plans/candidates.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/candidates.rs",
|
||||
] {
|
||||
let source = read_workspace_file(path);
|
||||
@@ -1294,7 +1294,7 @@ fn ai_pipeline_spec_metadata_owns_family_requested_model_and_plan_builder_routin
|
||||
"pub(crate) fn requested_model_family_for_video_create(",
|
||||
"pub(crate) fn local_standard_spec_metadata(",
|
||||
"pub(crate) fn local_same_format_provider_spec_metadata(",
|
||||
"pub(crate) fn local_openai_cli_spec_metadata(",
|
||||
"pub(crate) fn local_openai_responses_spec_metadata(",
|
||||
"pub(crate) fn local_gemini_files_spec_metadata(",
|
||||
"pub(crate) fn local_video_create_spec_metadata(",
|
||||
"pub(crate) fn build_sync_plan_from_requested_model_family(",
|
||||
@@ -1364,20 +1364,20 @@ fn ai_pipeline_spec_metadata_owns_family_requested_model_and_plan_builder_routin
|
||||
"local_gemini_files_spec_metadata(",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/plans.rs",
|
||||
"local_openai_cli_spec_metadata(",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/plans.rs",
|
||||
"local_openai_responses_spec_metadata(",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"local_openai_cli_spec_metadata(",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"local_openai_responses_spec_metadata(",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/request.rs",
|
||||
"local_openai_cli_spec_metadata(",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/request.rs",
|
||||
"local_openai_responses_spec_metadata(",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/payload.rs",
|
||||
"local_openai_cli_spec_metadata(",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/payload.rs",
|
||||
"local_openai_responses_spec_metadata(",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/build.rs",
|
||||
@@ -1487,7 +1487,7 @@ fn ai_pipeline_decision_inputs_share_authenticated_input_helper() {
|
||||
for path in [
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/family/candidates.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/passthrough/provider/family/candidates.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/plans/resolve.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/files/support.rs",
|
||||
@@ -1497,7 +1497,7 @@ fn ai_pipeline_decision_inputs_share_authenticated_input_helper() {
|
||||
source.contains("resolve_local_authenticated_decision_input("),
|
||||
"{path} should use the shared authenticated decision input helper"
|
||||
);
|
||||
if path.ends_with("/standard/openai/cli/decision/support.rs")
|
||||
if path.ends_with("/standard/openai/responses/decision/support.rs")
|
||||
|| path.ends_with("/standard/openai/chat/plans/resolve.rs")
|
||||
{
|
||||
assert!(
|
||||
@@ -1537,8 +1537,8 @@ fn ai_pipeline_decision_inputs_share_authenticated_input_helper() {
|
||||
"LocalRequestedModelDecisionInput as LocalOpenAiChatDecisionInput",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"LocalRequestedModelDecisionInput as LocalOpenAiCliDecisionInput",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"LocalRequestedModelDecisionInput as LocalOpenAiResponsesDecisionInput",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/support.rs",
|
||||
@@ -1570,7 +1570,7 @@ fn ai_pipeline_decision_inputs_share_authenticated_input_helper() {
|
||||
"build_local_requested_model_decision_input(",
|
||||
),
|
||||
(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
"build_local_requested_model_decision_input(",
|
||||
),
|
||||
(
|
||||
@@ -1596,7 +1596,7 @@ fn ai_pipeline_leaf_planner_owners_route_contract_specs_through_gateway_seams()
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/files/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/specialized/video/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision/support.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision/support.rs",
|
||||
] {
|
||||
let source = read_workspace_file(path);
|
||||
assert!(
|
||||
@@ -1900,15 +1900,15 @@ fn ai_pipeline_finalize_standard_sync_response_converters_are_owned_by_pipeline_
|
||||
for (candidate_paths, symbol) in [
|
||||
(
|
||||
vec!["apps/aether-gateway/src/ai_pipeline/finalize/standard/mod.rs"],
|
||||
"convert_openai_cli_response_to_openai_chat",
|
||||
"convert_openai_responses_response_to_openai_chat",
|
||||
),
|
||||
(
|
||||
vec!["apps/aether-gateway/src/ai_pipeline/finalize/standard/mod.rs"],
|
||||
"build_openai_cli_response",
|
||||
"build_openai_responses_response",
|
||||
),
|
||||
(
|
||||
vec!["apps/aether-gateway/src/ai_pipeline/finalize/standard/mod.rs"],
|
||||
"convert_openai_chat_response_to_openai_cli",
|
||||
"convert_openai_chat_response_to_openai_responses",
|
||||
),
|
||||
(
|
||||
vec!["apps/aether-gateway/src/ai_pipeline/finalize/standard/mod.rs"],
|
||||
@@ -1920,7 +1920,7 @@ fn ai_pipeline_finalize_standard_sync_response_converters_are_owned_by_pipeline_
|
||||
),
|
||||
(
|
||||
vec!["apps/aether-gateway/src/ai_pipeline/finalize/standard/mod.rs"],
|
||||
"convert_claude_cli_response_to_openai_cli",
|
||||
"convert_claude_response_to_openai_responses",
|
||||
),
|
||||
(
|
||||
vec!["apps/aether-gateway/src/ai_pipeline/finalize/standard/mod.rs"],
|
||||
@@ -1932,7 +1932,7 @@ fn ai_pipeline_finalize_standard_sync_response_converters_are_owned_by_pipeline_
|
||||
),
|
||||
(
|
||||
vec!["apps/aether-gateway/src/ai_pipeline/finalize/standard/mod.rs"],
|
||||
"convert_gemini_cli_response_to_openai_cli",
|
||||
"convert_gemini_response_to_openai_responses",
|
||||
),
|
||||
] {
|
||||
let sources = candidate_paths
|
||||
@@ -2032,14 +2032,14 @@ fn ai_pipeline_finalize_standard_sync_products_are_owned_by_pipeline_crate() {
|
||||
for expected in [
|
||||
"pub fn maybe_build_standard_cross_format_sync_product_from_normalized_payload(",
|
||||
"pub fn maybe_build_standard_same_format_sync_body_from_normalized_payload(",
|
||||
"pub fn maybe_build_openai_cli_same_family_sync_body_from_normalized_payload(",
|
||||
"pub fn maybe_build_openai_responses_same_family_sync_body_from_normalized_payload(",
|
||||
"pub fn maybe_build_openai_chat_cross_format_sync_product_from_normalized_payload(",
|
||||
"pub fn maybe_build_openai_cli_cross_format_sync_product_from_normalized_payload(",
|
||||
"pub fn maybe_build_openai_responses_cross_format_sync_product_from_normalized_payload(",
|
||||
"pub fn maybe_build_standard_sync_finalize_product_from_normalized_payload(",
|
||||
"pub fn aggregate_standard_chat_stream_sync_response(",
|
||||
"pub fn aggregate_standard_cli_stream_sync_response(",
|
||||
"pub fn aggregate_openai_chat_stream_sync_response(",
|
||||
"pub fn aggregate_openai_cli_stream_sync_response(",
|
||||
"pub fn aggregate_openai_responses_stream_sync_response(",
|
||||
"pub fn aggregate_claude_stream_sync_response(",
|
||||
"pub fn aggregate_gemini_stream_sync_response(",
|
||||
"pub fn convert_standard_chat_response(",
|
||||
@@ -2315,7 +2315,7 @@ fn ai_pipeline_planner_standard_normalize_is_owned_by_pipeline_crate() {
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/normalize/chat.rs",
|
||||
);
|
||||
let gateway_normalize_cli = read_workspace_file(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/normalize/cli.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/normalize/responses.rs",
|
||||
);
|
||||
assert!(
|
||||
gateway_normalize_chat.contains("crate::ai_pipeline::")
|
||||
@@ -2325,7 +2325,7 @@ fn ai_pipeline_planner_standard_normalize_is_owned_by_pipeline_crate() {
|
||||
|
||||
for forbidden in [
|
||||
"serde_json::Map::from_iter",
|
||||
"normalize_openai_cli_request_to_openai_chat_request",
|
||||
"normalize_openai_responses_request_to_openai_chat_request",
|
||||
"parse_openai_tool_result_content",
|
||||
] {
|
||||
assert!(
|
||||
@@ -2648,41 +2648,41 @@ fn ai_pipeline_specialized_video_specs_are_owned_by_pipeline_crate() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ai_pipeline_openai_cli_specs_are_owned_by_pipeline_crate() {
|
||||
fn ai_pipeline_openai_responses_specs_are_owned_by_pipeline_crate() {
|
||||
assert!(
|
||||
workspace_file_exists("crates/aether-ai-pipeline/src/planner/standard/openai_cli.rs"),
|
||||
"planner/standard/openai_cli pure spec owner should live in aether-ai-pipeline"
|
||||
workspace_file_exists("crates/aether-ai-pipeline/src/planner/standard/openai_responses.rs"),
|
||||
"planner/standard/openai_responses pure spec owner should live in aether-ai-pipeline"
|
||||
);
|
||||
|
||||
let decision = read_workspace_file(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/decision.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/decision.rs",
|
||||
);
|
||||
assert!(
|
||||
decision.contains("pub(super) use crate::ai_pipeline::LocalOpenAiCliSpec;"),
|
||||
"gateway planner/standard/openai/cli/decision.rs should re-export pure openai-cli spec type through the ai_pipeline root seam"
|
||||
decision.contains("pub(super) use crate::ai_pipeline::LocalOpenAiResponsesSpec;"),
|
||||
"gateway planner/standard/openai/responses/decision.rs should re-export pure openai-responses spec type through the ai_pipeline root seam"
|
||||
);
|
||||
assert!(
|
||||
!decision.contains("pub(super) struct LocalOpenAiCliSpec"),
|
||||
"gateway planner/standard/openai/cli/decision.rs should not own LocalOpenAiCliSpec"
|
||||
!decision.contains("pub(super) struct LocalOpenAiResponsesSpec"),
|
||||
"gateway planner/standard/openai/responses/decision.rs should not own LocalOpenAiResponsesSpec"
|
||||
);
|
||||
|
||||
let plans = read_workspace_file(
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/cli/plans.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/responses/plans.rs",
|
||||
);
|
||||
assert!(
|
||||
plans.contains("crate::ai_pipeline::"),
|
||||
"gateway planner/standard/openai/cli/plans.rs should delegate openai-cli spec resolution through the ai_pipeline root seam"
|
||||
"gateway planner/standard/openai/responses/plans.rs should delegate openai-responses spec resolution through the ai_pipeline root seam"
|
||||
);
|
||||
for forbidden in [
|
||||
"fn resolve_sync_spec(",
|
||||
"fn resolve_stream_spec(",
|
||||
"OPENAI_CLI_SYNC_PLAN_KIND",
|
||||
"OPENAI_COMPACT_STREAM_PLAN_KIND",
|
||||
"LocalOpenAiCliSpec {",
|
||||
"LocalOpenAiResponsesSpec {",
|
||||
] {
|
||||
assert!(
|
||||
!plans.contains(forbidden),
|
||||
"gateway planner/standard/openai/cli/plans.rs should not keep pure openai-cli resolver detail {forbidden}"
|
||||
"gateway planner/standard/openai/responses/plans.rs should not keep pure openai-responses resolver detail {forbidden}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ async fn gateway_refreshes_admin_provider_quota_locally_for_codex_with_trusted_a
|
||||
);
|
||||
assert_eq!(
|
||||
seen_execution_runtime_request.provider_api_format,
|
||||
"openai:cli"
|
||||
"openai:responses"
|
||||
);
|
||||
assert_eq!(seen_execution_runtime_request.total_ms, Some(30_000));
|
||||
|
||||
|
||||
@@ -566,7 +566,7 @@ async fn gateway_handles_admin_default_body_rules_locally_with_trusted_admin_pri
|
||||
let upstream_hits = Arc::new(Mutex::new(0usize));
|
||||
let upstream_hits_clone = Arc::clone(&upstream_hits);
|
||||
let upstream = Router::new().route(
|
||||
"/api/admin/endpoints/defaults/openai:cli/body-rules",
|
||||
"/api/admin/endpoints/defaults/openai:responses/body-rules",
|
||||
any(move |_request: Request| {
|
||||
let upstream_hits_inner = Arc::clone(&upstream_hits_clone);
|
||||
async move {
|
||||
@@ -582,7 +582,7 @@ async fn gateway_handles_admin_default_body_rules_locally_with_trusted_admin_pri
|
||||
|
||||
let response = reqwest::Client::new()
|
||||
.get(format!(
|
||||
"{gateway_url}/api/admin/endpoints/defaults/openai:cli/body-rules?provider_type=codex"
|
||||
"{gateway_url}/api/admin/endpoints/defaults/openai:responses/body-rules?provider_type=codex"
|
||||
))
|
||||
.header(crate::constants::GATEWAY_HEADER, "rust-phase3b")
|
||||
.header(TRUSTED_ADMIN_USER_ID_HEADER, "admin-user-123")
|
||||
@@ -594,7 +594,7 @@ async fn gateway_handles_admin_default_body_rules_locally_with_trusted_admin_pri
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let payload: serde_json::Value = response.json().await.expect("json body should parse");
|
||||
assert_eq!(payload["api_format"], "openai:cli");
|
||||
assert_eq!(payload["api_format"], "openai:responses");
|
||||
let rules = payload["body_rules"]
|
||||
.as_array()
|
||||
.expect("body_rules should be an array");
|
||||
|
||||
@@ -329,16 +329,17 @@ async fn gateway_handles_admin_provider_query_models_with_openai_responses_endpo
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let payload: serde_json::Value = response.json().await.expect("json body should parse");
|
||||
assert_eq!(payload["success"], json!(false));
|
||||
assert_eq!(
|
||||
payload["data"]["error"],
|
||||
json!("No active endpoints found for this provider")
|
||||
);
|
||||
assert_eq!(payload["success"], json!(true));
|
||||
assert_eq!(payload["data"]["error"], serde_json::Value::Null);
|
||||
assert_eq!(payload["data"]["from_cache"], json!(false));
|
||||
assert_eq!(payload["data"]["models"], json!([]));
|
||||
assert_eq!(payload["data"]["models"][0]["id"], json!("gpt-4.1"));
|
||||
assert_eq!(
|
||||
payload["data"]["models"][0]["api_formats"],
|
||||
json!(["openai:responses"])
|
||||
);
|
||||
assert_eq!(
|
||||
*execution_runtime_hits.lock().expect("mutex should lock"),
|
||||
0
|
||||
1
|
||||
);
|
||||
|
||||
gateway_handle.abort();
|
||||
@@ -465,7 +466,7 @@ async fn gateway_handles_admin_provider_query_models_respecting_key_api_formats(
|
||||
assert_eq!(payload["data"]["from_cache"], json!(false));
|
||||
assert_eq!(
|
||||
payload["data"]["models"][0]["api_formats"],
|
||||
json!(["openai:cli"])
|
||||
json!(["openai:responses"])
|
||||
);
|
||||
assert_eq!(
|
||||
*execution_runtime_hits.lock().expect("mutex should lock"),
|
||||
@@ -1596,7 +1597,7 @@ async fn gateway_handles_openai_cli_test_model_locally() {
|
||||
"choices": [{
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": "Hello from OpenAI CLI"
|
||||
"content": "Hello from OpenAI Responses"
|
||||
}
|
||||
}]
|
||||
}
|
||||
@@ -1660,7 +1661,7 @@ async fn gateway_handles_openai_cli_test_model_locally() {
|
||||
assert_eq!(payload["success"], json!(true));
|
||||
assert_eq!(
|
||||
payload["data"]["response"]["choices"][0]["message"]["content"],
|
||||
json!("Hello from OpenAI CLI")
|
||||
json!("Hello from OpenAI Responses")
|
||||
);
|
||||
|
||||
gateway_handle.abort();
|
||||
@@ -2236,7 +2237,7 @@ async fn gateway_handles_openai_cli_test_model_failover_locally() {
|
||||
"choices": [{
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": "OpenAI CLI failover path succeeded"
|
||||
"content": "OpenAI Responses failover path succeeded"
|
||||
}
|
||||
}]
|
||||
}
|
||||
@@ -2299,7 +2300,7 @@ async fn gateway_handles_openai_cli_test_model_failover_locally() {
|
||||
assert_eq!(payload["total_attempts"], json!(1));
|
||||
assert_eq!(
|
||||
payload["data"]["response"]["choices"][0]["message"]["content"],
|
||||
json!("OpenAI CLI failover path succeeded")
|
||||
json!("OpenAI Responses failover path succeeded")
|
||||
);
|
||||
|
||||
gateway_handle.abort();
|
||||
|
||||
@@ -943,20 +943,20 @@ async fn gateway_creates_admin_provider_locally_with_trusted_admin_principal() {
|
||||
.await
|
||||
.expect("endpoints should list");
|
||||
assert_eq!(endpoints.len(), 3);
|
||||
let cli_endpoint = endpoints
|
||||
let responses_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:cli")
|
||||
.expect("cli endpoint should exist");
|
||||
.find(|endpoint| endpoint.api_format == "openai:responses")
|
||||
.expect("responses endpoint should exist");
|
||||
let compact_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:compact")
|
||||
.find(|endpoint| endpoint.api_format == "openai:responses:compact")
|
||||
.expect("compact endpoint should exist");
|
||||
let image_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:image")
|
||||
.expect("image endpoint should exist");
|
||||
assert_eq!(
|
||||
cli_endpoint.base_url,
|
||||
responses_endpoint.base_url,
|
||||
"https://chatgpt.com/backend-api/codex"
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -967,11 +967,11 @@ async fn gateway_creates_admin_provider_locally_with_trusted_admin_principal() {
|
||||
image_endpoint.base_url,
|
||||
"https://chatgpt.com/backend-api/codex"
|
||||
);
|
||||
assert_eq!(cli_endpoint.max_retries, Some(7));
|
||||
assert_eq!(responses_endpoint.max_retries, Some(7));
|
||||
assert_eq!(compact_endpoint.max_retries, Some(7));
|
||||
assert_eq!(image_endpoint.max_retries, Some(7));
|
||||
assert_eq!(
|
||||
cli_endpoint
|
||||
responses_endpoint
|
||||
.config
|
||||
.as_ref()
|
||||
.and_then(|value| value.get("upstream_stream_policy"))
|
||||
@@ -986,7 +986,7 @@ async fn gateway_creates_admin_provider_locally_with_trusted_admin_principal() {
|
||||
.and_then(serde_json::Value::as_str),
|
||||
Some("force_stream")
|
||||
);
|
||||
assert!(cli_endpoint.body_rules.is_none());
|
||||
assert!(responses_endpoint.body_rules.is_none());
|
||||
assert!(compact_endpoint.body_rules.is_none());
|
||||
assert!(image_endpoint.body_rules.is_none());
|
||||
assert_eq!(*upstream_hits.lock().expect("mutex should lock"), 0);
|
||||
@@ -1079,24 +1079,24 @@ async fn gateway_updates_fixed_provider_and_reconciles_template_managed_endpoint
|
||||
.await
|
||||
.expect("endpoints should list");
|
||||
assert_eq!(endpoints.len(), 3);
|
||||
let cli_endpoint = endpoints
|
||||
let responses_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:cli")
|
||||
.expect("cli endpoint should exist");
|
||||
.find(|endpoint| endpoint.api_format == "openai:responses")
|
||||
.expect("responses endpoint should exist");
|
||||
let compact_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:compact")
|
||||
.find(|endpoint| endpoint.api_format == "openai:responses:compact")
|
||||
.expect("compact endpoint should exist");
|
||||
let image_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:image")
|
||||
.expect("image endpoint should exist");
|
||||
|
||||
assert_eq!(cli_endpoint.max_retries, Some(9));
|
||||
assert_eq!(responses_endpoint.max_retries, Some(9));
|
||||
assert_eq!(compact_endpoint.max_retries, Some(9));
|
||||
assert_eq!(image_endpoint.max_retries, Some(9));
|
||||
assert_eq!(
|
||||
cli_endpoint
|
||||
responses_endpoint
|
||||
.config
|
||||
.as_ref()
|
||||
.and_then(|value| value.get("_aether_fixed_provider_template"))
|
||||
|
||||
Reference in New Issue
Block a user