fix(litellm): gate OAuth routes on real credentials
This commit is contained in:
@@ -29,6 +29,8 @@ Google AI Studio key 尚未取得;latest 自动维护尚未实现。
|
||||
只使用单个代理 worker,降低 OAuth refresh token 竞争的风险。
|
||||
所有配置从 Git 生成,不允许 UI 中的模型配置成为另一份权威。
|
||||
未提供 key 或未完成 OAuth 登录的路线不会进入运行配置。
|
||||
OAuth 判定检查 auth.json 中 access_token,不仅检查文件存在性:
|
||||
Codex 设备授权期间会先写入冷却占位文件,这不代表已经授权。
|
||||
|
||||
## Provider 与缓存
|
||||
|
||||
@@ -100,6 +102,8 @@ bash oauth-login.sh xai
|
||||
登录 helper 使用 host network 仅供本地 OAuth 回调,生产代理仍使用独立 bridge。
|
||||
|
||||
确认账号实际支持的模型 ID 后,在 `models.yaml` 的 `chatgpt`/`xai` 表添加别名。
|
||||
已预置的 OAuth 候选为 gpt-luna-latest/gpt-sol-latest/grok-latest,
|
||||
只是先前 Hindsight 使用过的模型,不代表本代理独立账号已授权。
|
||||
Codex 路线由 `chatgpt/` 访问,优先 `/v1/responses`;
|
||||
xAI 路线使用 `xai/` 与 `use_xai_oauth: true`,不能设置 XAI API key 覆盖它。
|
||||
新增 token 后需重启代理,运行时 refresh 会写回同一个持久卷。
|
||||
|
||||
@@ -10,6 +10,10 @@ openrouter:
|
||||
kimi-latest: moonshotai/kimi-k3
|
||||
mimo-flash-latest: xiaomi/mimo-v2.6-flash
|
||||
google_ai_studio: {}
|
||||
# OAuth 模型需完成独立登录,并根据账号实际模型目录确认后启用。
|
||||
chatgpt: {}
|
||||
xai: {}
|
||||
# 已有 Hindsight 部署用过的候选模型;本代理仍需独立授权与请求验收。
|
||||
# renderer 在实际 token 出现前排除这些路线。
|
||||
chatgpt:
|
||||
gpt-luna-latest: gpt-6-luna
|
||||
gpt-sol-latest: gpt-6-sol
|
||||
xai:
|
||||
grok-latest: grok-4.7
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
"""Render only credential-ready routes; credentials remain environment references."""
|
||||
import os
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
def oauth_ready(path):
|
||||
try:
|
||||
record = json.loads(path.read_text())
|
||||
return isinstance(record, dict) and bool(record.get('access_token'))
|
||||
except (OSError, ValueError):
|
||||
return False
|
||||
|
||||
|
||||
def build_config(catalog, env, exists):
|
||||
routes = []
|
||||
|
||||
@@ -49,7 +58,7 @@ def build_config(catalog, env, exists):
|
||||
|
||||
if __name__ == '__main__':
|
||||
catalog = yaml.safe_load(Path('/etc/litellm/models.yaml').read_text())
|
||||
config = build_config(catalog, os.environ, Path.is_file)
|
||||
config = build_config(catalog, os.environ, oauth_ready)
|
||||
output = Path('/tmp/litellm.yaml')
|
||||
output.write_text(yaml.safe_dump(config, allow_unicode=True, sort_keys=False))
|
||||
output.chmod(0o600)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import unittest
|
||||
from render_config import build_config
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from render_config import build_config, oauth_ready
|
||||
|
||||
|
||||
class ConfigTests(unittest.TestCase):
|
||||
@@ -33,6 +35,15 @@ class ConfigTests(unittest.TestCase):
|
||||
self.assertTrue(routes[0]['litellm_params']['use_xai_oauth'])
|
||||
self.assertNotIn('api_key', routes[0]['litellm_params'])
|
||||
|
||||
def test_pending_oauth_is_not_ready(self):
|
||||
with TemporaryDirectory() as folder:
|
||||
path = Path(folder) / 'auth.json'
|
||||
self.assertFalse(oauth_ready(path))
|
||||
path.write_text('{"device_code_requested_at": 1}')
|
||||
self.assertFalse(oauth_ready(path))
|
||||
path.write_text('{"access_token": "fixture-only"}')
|
||||
self.assertTrue(oauth_ready(path))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user