codex·agy OAuth 계정 연결 지원 (ChatGPT/Antigravity 네이티브 어댑터)
Some checks failed
API contract / OpenAPI type drift (push) Failing after 1m0s

omniroute와 동일하게 공개 클라이언트 자격증명으로 서버사이드 OAuth 교환을
제공한다. 관리자가 제공자 로그인 후 브라우저에 남는 code를 붙여넣으면
토큰·refresh token·메타데이터(account-id, Code Assist project)를 저장하고
게이트웨이에 push한다.

- codex_api 어댑터: chatgpt.com/backend-api/codex/responses (Responses SSE,
  401 시 refresh token으로 자가 갱신)
- antigravity_api 어댑터: cloudcode-pa v1internal:streamGenerateContent
  (Gemini 형식 SSE, loadCodeAssist로 프로젝트 발급, 401 자가 갱신)
- 자격증명 저장소에 refresh_token_encrypted·extra 컬럼 추가(부트스트랩
  SQL 포함), 게이트웨이 push가 구조화 자격증명을 전달
This commit is contained in:
Yun Chan 2026-09-11 19:01:35 +09:00
parent 1a925b33e0
commit 45b84faa0d
10 changed files with 581 additions and 18 deletions

View file

@ -45,7 +45,7 @@ from engine_gateway.provider_registry import (
clear_capability_cache,
discover_capabilities,
generate_with_provider,
set_provider_auth_kind,
set_provider_credential,
stream_with_provider,
)
@ -454,6 +454,8 @@ _PROVIDER_CREDENTIAL_ENV_VARS: dict[str, tuple[str, ...]] = {
class ProviderCredentialEntry(BaseModel):
token: str
auth_kind: str = "api_key"
refresh_token: str = ""
extra: dict[str, Any] = {}
class ProviderCredentialsPush(BaseModel):
@ -495,9 +497,19 @@ async def internal_push_provider_credentials(payload: ProviderCredentialsPush):
else:
os.environ.pop("ANTHROPIC_AUTH_TOKEN", None)
os.environ["ANTHROPIC_API_KEY"] = token
elif provider in {"codex", "agy"} and entry.auth_kind == "oauth_token":
# ChatGPT/Google OAuth 토큰은 OPENAI/AGY API 키로 쓸 수 없다.
# 구조화 자격증명으로만 보관하고 해당 어댑터가 읽는다.
pass
else:
os.environ[env_names[0]] = token
set_provider_auth_kind(provider, entry.auth_kind)
set_provider_credential(
provider,
token=token,
auth_kind=entry.auth_kind,
refresh_token=entry.refresh_token,
extra=entry.extra,
)
applied.append(provider)
clear_capability_cache()
return {