Добавлены web UI и API для промтов и тестов

Этот коммит содержится в:
Виктор
2026-05-11 22:19:20 +09:00
родитель 2b69956d0f
Коммит 26166950e7
+72 -3
Просмотреть файл
@@ -1,5 +1,9 @@
from fastapi import FastAPI from pathlib import Path
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel from pydantic import BaseModel
from backend.config_store import ( from backend.config_store import (
@@ -7,6 +11,10 @@ from backend.config_store import (
has_openai_key, has_openai_key,
set_setting, set_setting,
) )
from backend.openai_client import OpenAIConfigurationError, ask_ai
ROOT_DIR = Path(__file__).resolve().parent.parent
FRONTEND_DIR = ROOT_DIR / 'frontend'
app = FastAPI(title='DevConsole', version='0.1.0') app = FastAPI(title='DevConsole', version='0.1.0')
@@ -18,14 +26,25 @@ app.add_middleware(
allow_headers=['*'], allow_headers=['*'],
) )
if FRONTEND_DIR.exists():
app.mount('/assets', StaticFiles(directory=FRONTEND_DIR / 'assets'), name='assets')
class OpenAIConfigRequest(BaseModel): class OpenAIConfigRequest(BaseModel):
api_key: str api_key: str
model: str = 'gpt-5' model: str = 'gpt-5'
class PromptTestRequest(BaseModel):
prompt: str
@app.get('/') @app.get('/')
async def root(): async def root():
index_file = FRONTEND_DIR / 'index.html'
if index_file.exists():
return FileResponse(index_file)
return { return {
'project': 'DevConsole', 'project': 'DevConsole',
'version': '0.1.0', 'version': '0.1.0',
@@ -42,6 +61,17 @@ async def health():
} }
@app.get('/api/system/status')
async def system_status():
return {
'project': 'DevConsole',
'version': '0.1.0',
'status': 'running',
'openai_configured': has_openai_key(),
'openai_model': get_openai_model(),
}
@app.get('/api/settings/openai') @app.get('/api/settings/openai')
async def openai_status(): async def openai_status():
return { return {
@@ -52,10 +82,49 @@ async def openai_status():
@app.post('/api/settings/openai') @app.post('/api/settings/openai')
async def save_openai_settings(payload: OpenAIConfigRequest): async def save_openai_settings(payload: OpenAIConfigRequest):
set_setting('OPENAI_API_KEY', payload.api_key.strip()) api_key = payload.api_key.strip()
set_setting('OPENAI_MODEL', payload.model.strip()) model = payload.model.strip() or 'gpt-5'
if not api_key:
raise HTTPException(status_code=400, detail='API key is empty')
set_setting('OPENAI_API_KEY', api_key)
set_setting('OPENAI_MODEL', model)
return { return {
'success': True, 'success': True,
'message': 'OpenAI settings saved', 'message': 'OpenAI settings saved',
} }
@app.post('/api/prompts/test')
async def test_prompt(payload: PromptTestRequest):
prompt = payload.prompt.strip()
if not prompt:
raise HTTPException(status_code=400, detail='Prompt is empty')
try:
answer = await ask_ai(prompt)
except OpenAIConfigurationError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
return {
'success': True,
'model': get_openai_model(),
'answer': answer,
}
@app.post('/api/settings/openai/test')
async def test_openai_connection():
try:
answer = await ask_ai('Reply with exactly: DevConsole AI connection OK')
except OpenAIConfigurationError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
return {
'success': True,
'model': get_openai_model(),
'answer': answer,
}