mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
refactor(kiro): 拆分 auth_region/api_region,统一 region 解析逻辑
KiroAuthConfig 新增 auth_region(token 刷新端点)和 api_region(q.{region} 服务端点)字段,
通过 effective_auth_region() / effective_api_region() 方法统一各处散落的 region 回退逻辑,
与 kiro.rs 的 region 语义对齐。
This commit is contained in:
@@ -337,7 +337,7 @@ async def _fetch_kiro_email(
|
|||||||
if parsed and parsed.get("email"):
|
if parsed and parsed.get("email"):
|
||||||
return parsed["email"]
|
return parsed["email"]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning("[KIRO] 获取用户邮箱失败: {}", e)
|
logger.warning("[KIRO] 获取用户邮箱失败: {} | {}", type(e).__name__, e, exc_info=True)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -358,11 +358,12 @@ class HandlerAdapterBase(ApiAdapter):
|
|||||||
# ---- URL ----
|
# ---- URL ----
|
||||||
if is_kiro:
|
if is_kiro:
|
||||||
from src.services.provider.adapters.kiro.constants import (
|
from src.services.provider.adapters.kiro.constants import (
|
||||||
DEFAULT_REGION,
|
|
||||||
KIRO_GENERATE_ASSISTANT_PATH,
|
KIRO_GENERATE_ASSISTANT_PATH,
|
||||||
)
|
)
|
||||||
|
from src.services.provider.adapters.kiro.models.credentials import KiroAuthConfig
|
||||||
|
|
||||||
region = (decrypted_auth_config or {}).get("region") or DEFAULT_REGION
|
_kiro_cfg = KiroAuthConfig.from_dict(decrypted_auth_config or {})
|
||||||
|
region = _kiro_cfg.effective_api_region()
|
||||||
effective_base_url = (
|
effective_base_url = (
|
||||||
base_url.replace("{region}", region) if "{region}" in base_url else base_url
|
base_url.replace("{region}", region) if "{region}" in base_url else base_url
|
||||||
)
|
)
|
||||||
@@ -401,7 +402,7 @@ class HandlerAdapterBase(ApiAdapter):
|
|||||||
from src.services.provider.adapters.kiro.token_manager import generate_machine_id
|
from src.services.provider.adapters.kiro.token_manager import generate_machine_id
|
||||||
|
|
||||||
kiro_cfg = KiroAuthConfig.from_dict(decrypted_auth_config or {})
|
kiro_cfg = KiroAuthConfig.from_dict(decrypted_auth_config or {})
|
||||||
region = kiro_cfg.region or DEFAULT_REGION
|
region = kiro_cfg.effective_api_region()
|
||||||
machine_id = generate_machine_id(kiro_cfg)
|
machine_id = generate_machine_id(kiro_cfg)
|
||||||
kiro_headers = build_generate_assistant_headers(
|
kiro_headers = build_generate_assistant_headers(
|
||||||
host=f"q.{region}.amazonaws.com",
|
host=f"q.{region}.amazonaws.com",
|
||||||
|
|||||||
@@ -22,10 +22,8 @@ from src.services.provider.adapters.kiro.token_manager import generate_machine_i
|
|||||||
|
|
||||||
|
|
||||||
def _resolve_region(cfg: KiroAuthConfig) -> str:
|
def _resolve_region(cfg: KiroAuthConfig) -> str:
|
||||||
from src.services.provider.adapters.kiro.constants import DEFAULT_REGION
|
"""解析 API 服务端点的 region(q.{region}.amazonaws.com)。"""
|
||||||
|
return cfg.effective_api_region()
|
||||||
region = str(cfg.region or "").strip()
|
|
||||||
return region or DEFAULT_REGION
|
|
||||||
|
|
||||||
|
|
||||||
def _is_thinking_enabled(request_body: dict[str, Any]) -> bool:
|
def _is_thinking_enabled(request_body: dict[str, Any]) -> bool:
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ def _get_str(raw: dict[str, Any], *keys: str) -> str | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _nonempty(s: str | None) -> str | None:
|
||||||
|
"""Return *s* if it's a non-empty stripped string, else ``None``."""
|
||||||
|
if isinstance(s, str) and s.strip():
|
||||||
|
return s.strip()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _parse_iso_to_epoch_seconds(value: object) -> int | None:
|
def _parse_iso_to_epoch_seconds(value: object) -> int | None:
|
||||||
if not isinstance(value, str) or not value.strip():
|
if not isinstance(value, str) or not value.strip():
|
||||||
return None
|
return None
|
||||||
@@ -54,7 +61,13 @@ class KiroAuthConfig:
|
|||||||
expires_at: int = 0
|
expires_at: int = 0
|
||||||
|
|
||||||
profile_arn: str | None = None
|
profile_arn: str | None = None
|
||||||
region: str | None = None
|
region: str | None = None # OIDC region(IdC token 刷新用)
|
||||||
|
|
||||||
|
# 独立的 auth / api region(与 kiro.rs 对齐)
|
||||||
|
# auth_region: token 刷新端点,未设置时回退到 region
|
||||||
|
# api_region: q.{region} 服务端点,未设置时回退到 DEFAULT_REGION
|
||||||
|
auth_region: str | None = None
|
||||||
|
api_region: str | None = None
|
||||||
|
|
||||||
client_id: str | None = None
|
client_id: str | None = None
|
||||||
client_secret: str | None = None
|
client_secret: str | None = None
|
||||||
@@ -69,6 +82,26 @@ class KiroAuthConfig:
|
|||||||
# 缓存的 access_token(可选,用于避免频繁刷新)
|
# 缓存的 access_token(可选,用于避免频繁刷新)
|
||||||
access_token: str | None = None
|
access_token: str | None = None
|
||||||
|
|
||||||
|
def effective_auth_region(self) -> str:
|
||||||
|
"""Token 刷新用的 region。
|
||||||
|
|
||||||
|
优先级: auth_region > region > DEFAULT_REGION
|
||||||
|
"""
|
||||||
|
from src.services.provider.adapters.kiro.constants import DEFAULT_REGION
|
||||||
|
|
||||||
|
return _nonempty(self.auth_region) or _nonempty(self.region) or DEFAULT_REGION
|
||||||
|
|
||||||
|
def effective_api_region(self) -> str:
|
||||||
|
"""API 服务端点(q.{region})用的 region。
|
||||||
|
|
||||||
|
优先级: api_region > DEFAULT_REGION
|
||||||
|
注意: 不从 region 继承,因为 region 通常是 OIDC region(如 eu-north-1),
|
||||||
|
而 q.{region} 端点目前仅 us-east-1 可用。
|
||||||
|
"""
|
||||||
|
from src.services.provider.adapters.kiro.constants import DEFAULT_REGION
|
||||||
|
|
||||||
|
return _nonempty(self.api_region) or DEFAULT_REGION
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def infer_auth_method(raw: dict[str, Any]) -> str:
|
def infer_auth_method(raw: dict[str, Any]) -> str:
|
||||||
"""
|
"""
|
||||||
@@ -140,6 +173,8 @@ class KiroAuthConfig:
|
|||||||
expires_at=int(expires_at),
|
expires_at=int(expires_at),
|
||||||
profile_arn=_get_str(raw, "profile_arn", "profileArn"),
|
profile_arn=_get_str(raw, "profile_arn", "profileArn"),
|
||||||
region=_get_str(raw, "region"),
|
region=_get_str(raw, "region"),
|
||||||
|
auth_region=_get_str(raw, "auth_region", "authRegion"),
|
||||||
|
api_region=_get_str(raw, "api_region", "apiRegion"),
|
||||||
client_id=_get_str(raw, "client_id", "clientId"),
|
client_id=_get_str(raw, "client_id", "clientId"),
|
||||||
client_secret=_get_str(raw, "client_secret", "clientSecret"),
|
client_secret=_get_str(raw, "client_secret", "clientSecret"),
|
||||||
machine_id=_get_str(raw, "machine_id", "machineId"),
|
machine_id=_get_str(raw, "machine_id", "machineId"),
|
||||||
@@ -164,6 +199,8 @@ class KiroAuthConfig:
|
|||||||
"expires_at": self.expires_at,
|
"expires_at": self.expires_at,
|
||||||
"profile_arn": self.profile_arn,
|
"profile_arn": self.profile_arn,
|
||||||
"region": self.region,
|
"region": self.region,
|
||||||
|
"auth_region": self.auth_region,
|
||||||
|
"api_region": self.api_region,
|
||||||
"client_id": self.client_id,
|
"client_id": self.client_id,
|
||||||
"client_secret": self.client_secret,
|
"client_secret": self.client_secret,
|
||||||
"machine_id": self.machine_id,
|
"machine_id": self.machine_id,
|
||||||
|
|||||||
@@ -76,13 +76,13 @@ def is_token_expired(expires_at: int | None, *, skew_seconds: int = 120) -> bool
|
|||||||
|
|
||||||
|
|
||||||
def _resolve_region(cfg: KiroAuthConfig) -> str:
|
def _resolve_region(cfg: KiroAuthConfig) -> str:
|
||||||
region = str(cfg.region or "").strip()
|
"""解析 token 刷新端点的 region。"""
|
||||||
if region and _REGION_RE.fullmatch(region):
|
region = cfg.effective_auth_region()
|
||||||
|
if _REGION_RE.fullmatch(region):
|
||||||
return region
|
return region
|
||||||
# Keep best-effort fallback; actual host parsing happens in transport hook.
|
|
||||||
from src.services.provider.adapters.kiro.constants import DEFAULT_REGION
|
from src.services.provider.adapters.kiro.constants import DEFAULT_REGION
|
||||||
|
|
||||||
return region or DEFAULT_REGION
|
return DEFAULT_REGION
|
||||||
|
|
||||||
|
|
||||||
def _try_extract_email_from_jwt(token: str) -> str | None:
|
def _try_extract_email_from_jwt(token: str) -> str | None:
|
||||||
|
|||||||
@@ -80,22 +80,23 @@ async def fetch_kiro_usage_limits(
|
|||||||
raise RuntimeError("无法获取 Kiro access_token")
|
raise RuntimeError("无法获取 Kiro access_token")
|
||||||
|
|
||||||
# 构建请求
|
# 构建请求
|
||||||
from src.services.provider.adapters.kiro.constants import DEFAULT_REGION
|
effective_cfg = updated_cfg or cfg
|
||||||
|
region = effective_cfg.effective_api_region()
|
||||||
region = (updated_cfg.region if updated_cfg else cfg.region) or DEFAULT_REGION
|
|
||||||
host = f"q.{region}.amazonaws.com"
|
host = f"q.{region}.amazonaws.com"
|
||||||
machine_id = generate_machine_id(updated_cfg or cfg)
|
machine_id = generate_machine_id(effective_cfg)
|
||||||
kiro_version = (updated_cfg.kiro_version if updated_cfg else cfg.kiro_version) or "0.8.0"
|
kiro_version = (effective_cfg.kiro_version or "0.8.0").strip() or "0.8.0"
|
||||||
|
|
||||||
# 构建 URL(添加 isEmailRequired=true 获取邮箱)
|
# 构建 URL(添加 isEmailRequired=true 获取邮箱)
|
||||||
url = f"https://{host}/getUsageLimits?origin=AI_EDITOR&resourceType=AGENTIC_REQUEST&isEmailRequired=true"
|
url = f"https://{host}/getUsageLimits?origin=AI_EDITOR&resourceType=AGENTIC_REQUEST&isEmailRequired=true"
|
||||||
|
|
||||||
profile_arn = updated_cfg.profile_arn if updated_cfg else cfg.profile_arn
|
profile_arn = effective_cfg.profile_arn
|
||||||
if profile_arn:
|
if profile_arn:
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
|
|
||||||
url += f"&profileArn={quote(profile_arn, safe='')}"
|
url += f"&profileArn={quote(profile_arn, safe='')}"
|
||||||
|
|
||||||
|
logger.debug("[KIRO_QUOTA] 请求 URL: {}", url)
|
||||||
|
|
||||||
# 构建 headers
|
# 构建 headers
|
||||||
headers = {
|
headers = {
|
||||||
"x-amz-user-agent": build_x_amz_user_agent_usage(
|
"x-amz-user-agent": build_x_amz_user_agent_usage(
|
||||||
@@ -141,9 +142,7 @@ async def fetch_kiro_usage_limits(
|
|||||||
if response.status_code == 423:
|
if response.status_code == 423:
|
||||||
ban_reason = response_text[:200] if response_text else "HTTP 423 Locked"
|
ban_reason = response_text[:200] if response_text else "HTTP 423 Locked"
|
||||||
else:
|
else:
|
||||||
ban_reason = (
|
ban_reason = response_text[:200] if response_text else "HTTP 403 权限被拒绝"
|
||||||
response_text[:200] if response_text else "HTTP 403 权限被拒绝"
|
|
||||||
)
|
|
||||||
|
|
||||||
error_msg = {
|
error_msg = {
|
||||||
401: "认证失败,Token 无效或已过期",
|
401: "认证失败,Token 无效或已过期",
|
||||||
|
|||||||
Reference in New Issue
Block a user