mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-01 17:00:21 +08:00
guard legacy openai alias compatibility
This commit is contained in:
@@ -2724,3 +2724,106 @@ fn ai_pipeline_openai_cli_legacy_names_stay_out_of_primary_paths() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn openai_cli_legacy_alias_occurrences_are_whitelisted() {
|
||||
let workspace_root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../..")
|
||||
.canonicalize()
|
||||
.expect("workspace root should resolve");
|
||||
let mut files = Vec::new();
|
||||
for root in ["apps", "crates", "frontend/src"] {
|
||||
collect_alias_scan_files(&workspace_root.join(root), &mut files);
|
||||
}
|
||||
|
||||
let allowed_paths = [
|
||||
"apps/aether-gateway/src/ai_pipeline/conversion/mod.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/common.rs",
|
||||
"apps/aether-gateway/src/ai_pipeline/planner/standard/openai/chat/plans/sync.rs",
|
||||
"apps/aether-gateway/src/execution_runtime/tests.rs",
|
||||
"apps/aether-gateway/src/handlers/public/support/models/shared.rs",
|
||||
"apps/aether-gateway/src/scheduler/affinity.rs",
|
||||
"crates/aether-admin/src/system.rs",
|
||||
"crates/aether-ai-formats/src/canonical.rs",
|
||||
"crates/aether-ai-formats/src/formats.rs",
|
||||
"crates/aether-ai-formats/src/registry.rs",
|
||||
"crates/aether-ai-pipeline/src/contracts/report_kinds.rs",
|
||||
"crates/aether-ai-pipeline/src/conversion/registry.rs",
|
||||
"crates/aether-ai-pipeline/src/finalize/sync_products.rs",
|
||||
"crates/aether-ai-pipeline/src/planner/common.rs",
|
||||
"crates/aether-model-fetch/src/logic.rs",
|
||||
"crates/aether-usage-runtime/src/report.rs",
|
||||
"frontend/src/api/endpoints/types/api-format.ts",
|
||||
"frontend/src/features/models/components/RoutingTab.vue",
|
||||
"frontend/src/features/providers/components/EndpointFormDialog.vue",
|
||||
"frontend/src/features/providers/components/PriorityManagementDialog.vue",
|
||||
"frontend/src/features/usage/conversation/__tests__/stream.spec.ts",
|
||||
"frontend/src/features/usage/utils/__tests__/status.spec.ts",
|
||||
"frontend/src/features/usage/utils/status.ts",
|
||||
"frontend/src/mocks/data.ts",
|
||||
"frontend/src/mocks/handler.ts",
|
||||
];
|
||||
let allowed = allowed_paths
|
||||
.into_iter()
|
||||
.collect::<std::collections::BTreeSet<_>>();
|
||||
let patterns = [
|
||||
"openai:cli",
|
||||
"openai:compact",
|
||||
"openai_cli",
|
||||
"openai_compact",
|
||||
"OPENAI_CLI",
|
||||
"OPENAI_COMPACT",
|
||||
"OpenAI CLI",
|
||||
"OpenAI Compact",
|
||||
];
|
||||
|
||||
let mut violations = Vec::new();
|
||||
for file in files {
|
||||
let relative = file
|
||||
.strip_prefix(&workspace_root)
|
||||
.expect("file should be under workspace root")
|
||||
.to_string_lossy()
|
||||
.replace('\\', "/");
|
||||
if relative == "apps/aether-gateway/src/tests/architecture/ai_pipeline.rs" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let source = std::fs::read_to_string(&file).expect("source file should be readable");
|
||||
let hits = patterns
|
||||
.iter()
|
||||
.filter(|pattern| source.contains(**pattern))
|
||||
.copied()
|
||||
.collect::<Vec<_>>();
|
||||
if !hits.is_empty() && !allowed.contains(relative.as_str()) {
|
||||
violations.push(format!("{relative} -> {}", hits.join(", ")));
|
||||
}
|
||||
}
|
||||
|
||||
assert!(
|
||||
violations.is_empty(),
|
||||
"legacy OpenAI Responses aliases should stay confined to explicit compatibility files:\n{}",
|
||||
violations.join("\n")
|
||||
);
|
||||
}
|
||||
|
||||
fn collect_alias_scan_files(root: &std::path::Path, files: &mut Vec<std::path::PathBuf>) {
|
||||
for entry in std::fs::read_dir(root).expect("directory should be readable") {
|
||||
let entry = entry.expect("directory entry should be readable");
|
||||
let path = entry.path();
|
||||
if path.is_dir() {
|
||||
let name = path.file_name().and_then(|value| value.to_str());
|
||||
if matches!(name, Some("target" | "node_modules" | ".git")) {
|
||||
continue;
|
||||
}
|
||||
collect_alias_scan_files(&path, files);
|
||||
continue;
|
||||
}
|
||||
|
||||
if matches!(
|
||||
path.extension().and_then(|value| value.to_str()),
|
||||
Some("rs" | "ts" | "vue")
|
||||
) {
|
||||
files.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ export const API_FORMAT_LABELS: Record<string, string> = {
|
||||
CLAUDE: 'Claude Chat',
|
||||
CLAUDE_CLI: 'Claude CLI',
|
||||
OPENAI: 'OpenAI Chat',
|
||||
OPENAI_CLI: 'OpenAI Responses',
|
||||
OPENAI_COMPACT: 'OpenAI Responses Compact',
|
||||
LEGACY_OPENAI_CLI: 'OpenAI Responses',
|
||||
LEGACY_OPENAI_COMPACT: 'OpenAI Responses Compact',
|
||||
OPENAI_RESPONSES: 'OpenAI Responses',
|
||||
OPENAI_RESPONSES_COMPACT: 'OpenAI Responses Compact',
|
||||
OPENAI_IMAGE: 'OpenAI Image',
|
||||
@@ -56,8 +56,8 @@ export const API_FORMAT_SHORT: Record<string, string> = {
|
||||
[API_FORMATS.GEMINI_VIDEO]: 'GV',
|
||||
// legacy 兼容(仅用于展示历史数据)
|
||||
OPENAI: 'O',
|
||||
OPENAI_CLI: 'OR',
|
||||
OPENAI_COMPACT: 'ORC',
|
||||
LEGACY_OPENAI_CLI: 'OR',
|
||||
LEGACY_OPENAI_COMPACT: 'ORC',
|
||||
OPENAI_RESPONSES: 'OR',
|
||||
OPENAI_RESPONSES_COMPACT: 'ORC',
|
||||
OPENAI_IMAGE: 'OI',
|
||||
@@ -146,7 +146,23 @@ export function groupApiFormats(formats: string[]): ApiFormatGroup[] {
|
||||
export function formatApiFormat(format: string | null | undefined): string {
|
||||
if (!format) return '-'
|
||||
const raw = format.trim()
|
||||
return API_FORMAT_LABELS[raw] || API_FORMAT_LABELS[raw.toLowerCase()] || API_FORMAT_LABELS[raw.toUpperCase()] || raw
|
||||
const upper = raw.toUpperCase()
|
||||
return API_FORMAT_LABELS[raw]
|
||||
|| API_FORMAT_LABELS[raw.toLowerCase()]
|
||||
|| API_FORMAT_LABELS[legacyUppercaseApiFormatKey(upper)]
|
||||
|| API_FORMAT_LABELS[upper]
|
||||
|| raw
|
||||
}
|
||||
|
||||
function legacyUppercaseApiFormatKey(value: string): string {
|
||||
switch (value) {
|
||||
case 'OPENAI_CLI':
|
||||
return 'LEGACY_OPENAI_CLI'
|
||||
case 'OPENAI_COMPACT':
|
||||
return 'LEGACY_OPENAI_COMPACT'
|
||||
default:
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
// 工具函数:按标准顺序排序 API 格式数组
|
||||
|
||||
Reference in New Issue
Block a user