Подключен workspace API и frontend runtime

Этот коммит содержится в:
Виктор
2026-05-11 23:30:56 +09:00
родитель 0769c52a51
Коммит 1966eb1c0d
+16 -51
Просмотреть файл
@@ -15,11 +15,12 @@ from backend.config_store import (
from backend.openai_client import OpenAIConfigurationError, ask_ai from backend.openai_client import OpenAIConfigurationError, ask_ai
from backend.project_analyzer import analyze_github_project from backend.project_analyzer import analyze_github_project
from backend.shell_runner import run_command from backend.shell_runner import run_command
from backend.workspace_api import router as workspace_router
ROOT_DIR = Path(__file__).resolve().parent.parent ROOT_DIR = Path(__file__).resolve().parent.parent
FRONTEND_DIR = ROOT_DIR / 'frontend' FRONTEND_DIR = ROOT_DIR / 'frontend'
app = FastAPI(title='DevConsole', version='0.1.0') app = FastAPI(title='DevConsole', version='0.2.0')
app.add_middleware( app.add_middleware(
CORSMiddleware, CORSMiddleware,
@@ -29,6 +30,8 @@ app.add_middleware(
allow_headers=['*'], allow_headers=['*'],
) )
app.include_router(workspace_router)
if FRONTEND_DIR.exists(): if FRONTEND_DIR.exists():
app.mount('/assets', StaticFiles(directory=FRONTEND_DIR / 'assets'), name='assets') app.mount('/assets', StaticFiles(directory=FRONTEND_DIR / 'assets'), name='assets')
@@ -49,26 +52,24 @@ class ProjectAnalyzeRequest(BaseModel):
class WorkspaceRequest(BaseModel): class WorkspaceRequest(BaseModel):
workspace: str workspace: str
device: str | None = None
@app.get('/') @app.get('/')
async def root(): async def root():
index_file = FRONTEND_DIR / 'index.html' return FileResponse(FRONTEND_DIR / 'index.html')
if index_file.exists():
return FileResponse(index_file)
return {
'project': 'DevConsole', @app.get('/workspace.js')
'version': '0.1.0', async def workspace_js():
'status': 'running', return FileResponse(FRONTEND_DIR / 'workspace.js')
'openai_configured': has_openai_key(),
}
@app.get('/health') @app.get('/health')
async def health(): async def health():
return { return {
'status': 'ok', 'status': 'ok',
'version': '0.2.0',
'openai_configured': has_openai_key(), 'openai_configured': has_openai_key(),
} }
@@ -77,21 +78,13 @@ async def health():
async def system_status(): async def system_status():
return { return {
'project': 'DevConsole', 'project': 'DevConsole',
'version': '0.1.0', 'version': '0.2.0',
'status': 'running', 'status': 'running',
'openai_configured': has_openai_key(), 'openai_configured': has_openai_key(),
'openai_model': get_openai_model(), 'openai_model': get_openai_model(),
} }
@app.get('/api/settings/openai')
async def openai_status():
return {
'configured': has_openai_key(),
'model': get_openai_model(),
}
@app.post('/api/settings/openai') @app.post('/api/settings/openai')
async def save_openai_settings(payload: OpenAIConfigRequest): async def save_openai_settings(payload: OpenAIConfigRequest):
api_key = payload.api_key.strip() api_key = payload.api_key.strip()
@@ -128,20 +121,6 @@ async def test_prompt(payload: PromptTestRequest):
} }
@app.post('/api/settings/openai/test')
async def test_openai_connection():
try:
result = await ask_ai('Reply with exactly: DevConsole AI connection OK', 'test')
except OpenAIConfigurationError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
return {
'success': True,
'model': result['model'],
'answer': result['answer'],
}
@app.post('/api/projects/analyze') @app.post('/api/projects/analyze')
async def analyze_project(payload: ProjectAnalyzeRequest): async def analyze_project(payload: ProjectAnalyzeRequest):
repo_url = payload.repo_url.strip() repo_url = payload.repo_url.strip()
@@ -149,10 +128,7 @@ async def analyze_project(payload: ProjectAnalyzeRequest):
if not repo_url.startswith('http'): if not repo_url.startswith('http'):
raise HTTPException(status_code=400, detail='Invalid repository URL') raise HTTPException(status_code=400, detail='Invalid repository URL')
try:
analysis = analyze_github_project(repo_url) analysis = analyze_github_project(repo_url)
except Exception as exc:
raise HTTPException(status_code=500, detail=str(exc)) from exc
return { return {
'success': True, 'success': True,
@@ -162,13 +138,12 @@ async def analyze_project(payload: ProjectAnalyzeRequest):
@app.post('/api/projects/install-dependencies') @app.post('/api/projects/install-dependencies')
async def install_dependencies(payload: ProjectAnalyzeRequest): async def install_dependencies(payload: ProjectAnalyzeRequest):
try:
analysis = analyze_github_project(payload.repo_url.strip()) analysis = analyze_github_project(payload.repo_url.strip())
outputs = [] outputs = []
for step in analysis.dependency_steps: for step in analysis.dependency_steps:
outputs.append(run_command(step.command, step.cwd, 1800)) outputs.append(run_command(step.command, step.cwd, 1800))
except Exception as exc:
raise HTTPException(status_code=500, detail=str(exc)) from exc
return { return {
'success': True, 'success': True,
@@ -179,21 +154,13 @@ async def install_dependencies(payload: ProjectAnalyzeRequest):
@app.post('/api/android/devices') @app.post('/api/android/devices')
async def android_devices(): async def android_devices():
try: return list_devices()
result = list_devices()
except Exception as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
return result
@app.post('/api/android/build') @app.post('/api/android/build')
async def android_build(payload: WorkspaceRequest): async def android_build(payload: WorkspaceRequest):
try:
result = build_android(payload.workspace) result = build_android(payload.workspace)
apks = find_apks(payload.workspace) apks = find_apks(payload.workspace)
except Exception as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
return { return {
'success': result['returncode'] == 0, 'success': result['returncode'] == 0,
@@ -204,12 +171,10 @@ async def android_build(payload: WorkspaceRequest):
@app.post('/api/android/install-latest') @app.post('/api/android/install-latest')
async def android_install_latest(payload: WorkspaceRequest): async def android_install_latest(payload: WorkspaceRequest):
try:
result = install_latest_apk(payload.workspace) result = install_latest_apk(payload.workspace)
except Exception as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
return { return {
'success': result['returncode'] == 0, 'success': result['returncode'] == 0,
'result': result, 'result': result,
'device': payload.device,
} }