mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
feat: configure auth channel mismatch formats
This commit is contained in:
@@ -470,6 +470,7 @@ CREATE TABLE IF NOT EXISTS public.provider_api_keys (
|
||||
note character varying(500),
|
||||
internal_priority integer DEFAULT 50,
|
||||
rpm_limit integer,
|
||||
concurrent_limit integer,
|
||||
allowed_models json,
|
||||
capabilities json,
|
||||
learned_rpm_limit integer,
|
||||
@@ -497,6 +498,7 @@ CREATE TABLE IF NOT EXISTS public.provider_api_keys (
|
||||
provider_id character varying(36) NOT NULL,
|
||||
api_formats json,
|
||||
auth_type_by_format json,
|
||||
allow_auth_channel_mismatch_formats json,
|
||||
rate_multipliers json,
|
||||
health_by_format jsonb,
|
||||
circuit_breaker_by_format jsonb,
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
ALTER TABLE public.provider_api_keys
|
||||
ADD COLUMN IF NOT EXISTS allow_auth_channel_mismatch_formats json;
|
||||
|
||||
ALTER TABLE public.provider_api_keys
|
||||
ADD COLUMN IF NOT EXISTS concurrent_limit integer;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.aether_default_auth_mismatch_api_format(value text)
|
||||
RETURNS text
|
||||
LANGUAGE sql
|
||||
IMMUTABLE
|
||||
AS $$
|
||||
SELECT CASE LOWER(BTRIM(COALESCE(value, '')))
|
||||
WHEN 'openai:cli' THEN 'openai:responses'
|
||||
WHEN 'openai:compact' THEN 'openai:responses:compact'
|
||||
WHEN 'claude:chat' THEN 'claude:messages'
|
||||
WHEN 'claude:cli' THEN 'claude:messages'
|
||||
WHEN 'gemini:chat' THEN 'gemini:generate_content'
|
||||
WHEN 'gemini:cli' THEN 'gemini:generate_content'
|
||||
ELSE LOWER(BTRIM(COALESCE(value, '')))
|
||||
END
|
||||
$$;
|
||||
|
||||
WITH supported_formats AS (
|
||||
SELECT
|
||||
pak.id,
|
||||
public.aether_default_auth_mismatch_api_format(format.value) AS api_format,
|
||||
0 AS source_priority,
|
||||
MIN(format.ordinality) AS first_ordinality
|
||||
FROM public.provider_api_keys AS pak
|
||||
CROSS JOIN LATERAL json_array_elements_text(
|
||||
CASE
|
||||
WHEN pak.api_formats IS NOT NULL
|
||||
AND json_typeof(pak.api_formats) = 'array'
|
||||
THEN pak.api_formats
|
||||
ELSE '[]'::json
|
||||
END
|
||||
) WITH ORDINALITY AS format(value, ordinality)
|
||||
WHERE pak.api_formats IS NOT NULL
|
||||
AND json_typeof(pak.api_formats) = 'array'
|
||||
GROUP BY pak.id, api_format
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
pak.id,
|
||||
public.aether_default_auth_mismatch_api_format(endpoint.api_format) AS api_format,
|
||||
1 AS source_priority,
|
||||
0 AS first_ordinality
|
||||
FROM public.provider_api_keys AS pak
|
||||
INNER JOIN public.provider_endpoints AS endpoint
|
||||
ON endpoint.provider_id = pak.provider_id
|
||||
WHERE pak.api_formats IS NULL
|
||||
OR json_typeof(pak.api_formats) <> 'array'
|
||||
),
|
||||
deduplicated_formats AS (
|
||||
SELECT
|
||||
id,
|
||||
api_format,
|
||||
MIN(source_priority) AS source_priority,
|
||||
MIN(first_ordinality) AS first_ordinality
|
||||
FROM supported_formats
|
||||
WHERE api_format <> ''
|
||||
GROUP BY id, api_format
|
||||
),
|
||||
rebuilt AS (
|
||||
SELECT
|
||||
id,
|
||||
json_agg(api_format ORDER BY source_priority, first_ordinality, api_format) AS api_formats
|
||||
FROM deduplicated_formats
|
||||
GROUP BY id
|
||||
)
|
||||
UPDATE public.provider_api_keys AS pak
|
||||
SET
|
||||
allow_auth_channel_mismatch_formats = rebuilt.api_formats,
|
||||
updated_at = NOW()
|
||||
FROM rebuilt
|
||||
WHERE pak.id = rebuilt.id
|
||||
AND pak.allow_auth_channel_mismatch_formats IS NULL;
|
||||
|
||||
DROP FUNCTION public.aether_default_auth_mismatch_api_format(text);
|
||||
@@ -8,7 +8,7 @@ use tracing::{error, info, warn};
|
||||
|
||||
static MIGRATOR: Migrator = sqlx::migrate!("./migrations");
|
||||
static BASELINE_V2_SQL: &str = include_str!("../bootstrap/20260413020000_baseline_v2.sql");
|
||||
const BASELINE_V2_CUTOFF_VERSION: i64 = 20260428000000;
|
||||
const BASELINE_V2_CUTOFF_VERSION: i64 = 20260502000000;
|
||||
const MIGRATIONS_TABLE_EXISTS_SQL: &str =
|
||||
"SELECT to_regclass('public._sqlx_migrations') IS NOT NULL";
|
||||
const PUBLIC_BASE_TABLE_COUNT_SQL: &str = r#"
|
||||
@@ -665,6 +665,7 @@ SELECT EXISTS (
|
||||
20260423000000,
|
||||
20260424000000,
|
||||
20260428000000,
|
||||
20260502000000,
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -732,7 +733,20 @@ SELECT EXISTS (
|
||||
.sql
|
||||
.contains("api_formats json DEFAULT '[]'::json NOT NULL"));
|
||||
assert!(BASELINE_V2_SQL.contains("api_formats json,"));
|
||||
assert!(BASELINE_V2_SQL.contains("concurrent_limit integer,"));
|
||||
assert!(BASELINE_V2_SQL.contains("allow_auth_channel_mismatch_formats json,"));
|
||||
assert!(!BASELINE_V2_SQL.contains("api_formats json DEFAULT '[]'::json NOT NULL"));
|
||||
|
||||
let auth_mismatch_migration = MIGRATOR
|
||||
.iter()
|
||||
.find(|migration| migration.version == 20260502000000)
|
||||
.expect("auth mismatch migration should be embedded");
|
||||
assert!(auth_mismatch_migration
|
||||
.sql
|
||||
.contains("allow_auth_channel_mismatch_formats = rebuilt.api_formats"));
|
||||
assert!(auth_mismatch_migration
|
||||
.sql
|
||||
.contains("pak.allow_auth_channel_mismatch_formats IS NULL"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1256,6 +1270,7 @@ ORDER BY id
|
||||
20260423000000,
|
||||
20260424000000,
|
||||
20260428000000,
|
||||
20260502000000,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -141,6 +141,7 @@ SELECT
|
||||
is_active,
|
||||
api_formats,
|
||||
auth_type_by_format,
|
||||
allow_auth_channel_mismatch_formats,
|
||||
api_key,
|
||||
auth_config,
|
||||
note,
|
||||
@@ -198,6 +199,7 @@ SELECT
|
||||
is_active,
|
||||
api_formats,
|
||||
auth_type_by_format,
|
||||
allow_auth_channel_mismatch_formats,
|
||||
api_key,
|
||||
auth_config,
|
||||
note,
|
||||
@@ -1234,7 +1236,8 @@ INSERT INTO provider_api_keys (
|
||||
circuit_breaker_by_format,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
updated_at,
|
||||
allow_auth_channel_mismatch_formats
|
||||
) VALUES (
|
||||
$1,
|
||||
$2,
|
||||
@@ -1310,7 +1313,8 @@ INSERT INTO provider_api_keys (
|
||||
CASE
|
||||
WHEN $51::double precision IS NULL THEN NOW()
|
||||
ELSE TO_TIMESTAMP($51::double precision)
|
||||
END
|
||||
END,
|
||||
$52
|
||||
)
|
||||
"#,
|
||||
)
|
||||
@@ -1373,7 +1377,7 @@ INSERT INTO provider_api_keys (
|
||||
.bind(key.is_active)
|
||||
.bind(key.created_at_unix_ms.map(|value| value as f64))
|
||||
.bind(key.updated_at_unix_secs.map(|value| value as f64))
|
||||
.bind(key.expires_at_unix_secs.map(|value| value as f64))
|
||||
.bind(&key.allow_auth_channel_mismatch_formats)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_postgres_err()?;
|
||||
@@ -1723,6 +1727,7 @@ SET
|
||||
provider_id = $2,
|
||||
api_formats = $3,
|
||||
auth_type_by_format = $39,
|
||||
allow_auth_channel_mismatch_formats = $40,
|
||||
auth_type = $4,
|
||||
api_key = $5,
|
||||
auth_config = $6,
|
||||
@@ -1818,6 +1823,7 @@ WHERE id = $1
|
||||
.bind(key.updated_at_unix_secs.map(|value| value as f64))
|
||||
.bind(key.expires_at_unix_secs.map(|value| value as f64))
|
||||
.bind(&key.auth_type_by_format)
|
||||
.bind(&key.allow_auth_channel_mismatch_formats)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_postgres_err()?
|
||||
@@ -2479,6 +2485,8 @@ fn map_key_row(row: &PgRow) -> Result<StoredProviderCatalogKey, DataLayerError>
|
||||
);
|
||||
key.note = row.try_get("note").ok();
|
||||
key.auth_type_by_format = row.try_get("auth_type_by_format").ok();
|
||||
key.allow_auth_channel_mismatch_formats =
|
||||
row.try_get("allow_auth_channel_mismatch_formats").ok();
|
||||
key.internal_priority = row.try_get("internal_priority").unwrap_or(50);
|
||||
key.cache_ttl_minutes = row.try_get("cache_ttl_minutes").unwrap_or(5);
|
||||
key.max_probe_interval_minutes = row.try_get("max_probe_interval_minutes").unwrap_or(32);
|
||||
|
||||
Reference in New Issue
Block a user