feat: AI proxy via papa-app (Anthropic from RU), env and docker-compose
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
25be90de7b
commit
9d49c9bb6b
@ -7,3 +7,9 @@ NODE_ENV=development
|
|||||||
# AI — Anthropic Claude (единственный AI-провайдер). Бэкенд: ANTHROPIC_API_KEY
|
# AI — Anthropic Claude (единственный AI-провайдер). Бэкенд: ANTHROPIC_API_KEY
|
||||||
# OPENAI_API_KEY не используется
|
# OPENAI_API_KEY не используется
|
||||||
ANTHROPIC_API_KEY=
|
ANTHROPIC_API_KEY=
|
||||||
|
|
||||||
|
# Прокси Anthropic через papa-app на Railway (если Anthropic блокирует с РФ IP)
|
||||||
|
# AI_PROXY_URL=https://papa-app-production.up.railway.app/api/proxy/anthropic
|
||||||
|
# AI_PROXY_SECRET=klg-refly-proxy-2026
|
||||||
|
AI_PROXY_URL=
|
||||||
|
AI_PROXY_SECRET=
|
||||||
|
|||||||
@ -21,8 +21,11 @@ class ChatResponse(BaseModel):
|
|||||||
@router.post("/chat", response_model=ChatResponse)
|
@router.post("/chat", response_model=ChatResponse)
|
||||||
async def ai_chat(req: ChatRequest, user=Depends(get_current_user)):
|
async def ai_chat(req: ChatRequest, user=Depends(get_current_user)):
|
||||||
api_key = getattr(settings, "ANTHROPIC_API_KEY", None) or ""
|
api_key = getattr(settings, "ANTHROPIC_API_KEY", None) or ""
|
||||||
if not api_key or api_key == "":
|
proxy_url = getattr(settings, "AI_PROXY_URL", "") or ""
|
||||||
raise HTTPException(400, "AI assistant not configured")
|
proxy_secret = getattr(settings, "AI_PROXY_SECRET", "") or ""
|
||||||
|
if not proxy_url or not proxy_secret:
|
||||||
|
if not api_key or api_key == "":
|
||||||
|
raise HTTPException(400, "AI assistant not configured (set ANTHROPIC_API_KEY or AI_PROXY_URL+AI_PROXY_SECRET)")
|
||||||
|
|
||||||
db = SessionLocal()
|
db = SessionLocal()
|
||||||
try:
|
try:
|
||||||
@ -52,21 +55,33 @@ async def ai_chat(req: ChatRequest, user=Depends(get_current_user)):
|
|||||||
Отвечай на русском языке. Будь конкретным и профессиональным.
|
Отвечай на русском языке. Будь конкретным и профессиональным.
|
||||||
Используй авиационную терминологию где уместно."""
|
Используй авиационную терминологию где уместно."""
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"model": getattr(settings, "ANTHROPIC_MODEL", "claude-sonnet-4-20250514"),
|
||||||
|
"max_tokens": 1024,
|
||||||
|
"system": system_prompt,
|
||||||
|
"messages": [{"role": "user", "content": req.message}],
|
||||||
|
}
|
||||||
|
|
||||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||||
resp = await client.post(
|
if proxy_url and proxy_secret:
|
||||||
"https://api.anthropic.com/v1/messages",
|
resp = await client.post(
|
||||||
headers={
|
proxy_url,
|
||||||
"x-api-key": api_key,
|
headers={
|
||||||
"anthropic-version": "2023-06-01",
|
"x-proxy-secret": proxy_secret,
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
},
|
},
|
||||||
json={
|
json=payload,
|
||||||
"model": getattr(settings, "ANTHROPIC_MODEL", "claude-sonnet-4-20250514"),
|
)
|
||||||
"max_tokens": 1024,
|
else:
|
||||||
"system": system_prompt,
|
resp = await client.post(
|
||||||
"messages": [{"role": "user", "content": req.message}],
|
"https://api.anthropic.com/v1/messages",
|
||||||
},
|
headers={
|
||||||
)
|
"x-api-key": api_key,
|
||||||
|
"anthropic-version": "2023-06-01",
|
||||||
|
"content-type": "application/json",
|
||||||
|
},
|
||||||
|
json=payload,
|
||||||
|
)
|
||||||
|
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
raise HTTPException(502, f"AI service error: {resp.status_code}")
|
raise HTTPException(502, f"AI service error: {resp.status_code}")
|
||||||
|
|||||||
@ -67,6 +67,9 @@ class Settings(BaseSettings):
|
|||||||
# AI (Anthropic Claude)
|
# AI (Anthropic Claude)
|
||||||
ANTHROPIC_API_KEY: str = ""
|
ANTHROPIC_API_KEY: str = ""
|
||||||
ANTHROPIC_MODEL: str = "claude-sonnet-4-20250514"
|
ANTHROPIC_MODEL: str = "claude-sonnet-4-20250514"
|
||||||
|
# Прокси Anthropic через papa-app (Railway) — для обхода блокировки с российских IP
|
||||||
|
AI_PROXY_URL: str = ""
|
||||||
|
AI_PROXY_SECRET: str = ""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def database_url(self) -> str:
|
def database_url(self) -> str:
|
||||||
|
|||||||
@ -95,6 +95,9 @@ services:
|
|||||||
FGIS_ORG_ID: ${FGIS_ORG_ID:-}
|
FGIS_ORG_ID: ${FGIS_ORG_ID:-}
|
||||||
FGIS_API_KEY: ${FGIS_API_KEY:-}
|
FGIS_API_KEY: ${FGIS_API_KEY:-}
|
||||||
FGIS_CERT_PATH: /etc/ssl/fgis/client.pem
|
FGIS_CERT_PATH: /etc/ssl/fgis/client.pem
|
||||||
|
# Прокси Anthropic через papa-app (Railway) — обход блокировки с российских IP
|
||||||
|
AI_PROXY_URL: ${AI_PROXY_URL:-}
|
||||||
|
AI_PROXY_SECRET: ${AI_PROXY_SECRET:-}
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user