Вроде работает
This commit is contained in:
@@ -397,4 +397,59 @@ async def get_repository_diff(
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
# [/DEF:get_repository_diff:Function]
|
||||
|
||||
# [DEF:generate_commit_message:Function]
|
||||
# @PURPOSE: Generate a suggested commit message using LLM.
|
||||
# @PRE: Repository for `dashboard_id` is initialized.
|
||||
# @POST: Returns a suggested commit message string.
|
||||
@router.post("/repositories/{dashboard_id}/generate-message")
|
||||
async def generate_commit_message(
|
||||
dashboard_id: int,
|
||||
db: Session = Depends(get_db),
|
||||
_ = Depends(has_permission("plugin:git", "EXECUTE"))
|
||||
):
|
||||
with belief_scope("generate_commit_message"):
|
||||
try:
|
||||
# 1. Get Diff
|
||||
diff = git_service.get_diff(dashboard_id, staged=True)
|
||||
if not diff:
|
||||
diff = git_service.get_diff(dashboard_id, staged=False)
|
||||
|
||||
if not diff:
|
||||
return {"message": "No changes detected"}
|
||||
|
||||
# 2. Get History
|
||||
history_objs = git_service.get_commit_history(dashboard_id, limit=5)
|
||||
history = [h.message for h in history_objs if hasattr(h, 'message')]
|
||||
|
||||
# 3. Get LLM Client
|
||||
from ...services.llm_provider import LLMProviderService
|
||||
from ...plugins.llm_analysis.service import LLMClient
|
||||
from ...plugins.llm_analysis.models import LLMProviderType
|
||||
|
||||
llm_service = LLMProviderService(db)
|
||||
providers = llm_service.get_all_providers()
|
||||
provider = next((p for p in providers if p.is_active), None)
|
||||
|
||||
if not provider:
|
||||
raise HTTPException(status_code=400, detail="No active LLM provider found")
|
||||
|
||||
api_key = llm_service.get_decrypted_api_key(provider.id)
|
||||
client = LLMClient(
|
||||
provider_type=LLMProviderType(provider.provider_type),
|
||||
api_key=api_key,
|
||||
base_url=provider.base_url,
|
||||
default_model=provider.default_model
|
||||
)
|
||||
|
||||
# 4. Generate Message
|
||||
from ...plugins.git.llm_extension import GitLLMExtension
|
||||
extension = GitLLMExtension(client)
|
||||
message = await extension.suggest_commit_message(diff, history)
|
||||
|
||||
return {"message": message}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to generate commit message: {e}")
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
# [/DEF:generate_commit_message:Function]
|
||||
|
||||
# [/DEF:backend.src.api.routes.git:Module]
|
||||
191
backend/src/api/routes/llm.py
Normal file
191
backend/src/api/routes/llm.py
Normal file
@@ -0,0 +1,191 @@
|
||||
# [DEF:backend/src/api/routes/llm.py:Module]
|
||||
# @TIER: STANDARD
|
||||
# @SEMANTICS: api, routes, llm
|
||||
# @PURPOSE: API routes for LLM provider configuration and management.
|
||||
# @LAYER: UI (API)
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from typing import List
|
||||
from ...core.logger import logger
|
||||
from ...schemas.auth import User
|
||||
from ...dependencies import get_current_user as get_current_active_user
|
||||
from ...plugins.llm_analysis.models import LLMProviderConfig, LLMProviderType
|
||||
from ...services.llm_provider import LLMProviderService
|
||||
from ...core.database import get_db
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
# [DEF:router:Global]
|
||||
# @PURPOSE: APIRouter instance for LLM routes.
|
||||
router = APIRouter(prefix="/api/llm", tags=["LLM"])
|
||||
# [/DEF:router:Global]
|
||||
|
||||
# [DEF:get_providers:Function]
|
||||
# @PURPOSE: Retrieve all LLM provider configurations.
|
||||
# @PRE: User is authenticated.
|
||||
# @POST: Returns list of LLMProviderConfig.
|
||||
@router.get("/providers", response_model=List[LLMProviderConfig])
|
||||
async def get_providers(
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Get all LLM provider configurations.
|
||||
"""
|
||||
logger.info(f"[llm_routes][get_providers][Action] Fetching providers for user: {current_user.username}")
|
||||
service = LLMProviderService(db)
|
||||
providers = service.get_all_providers()
|
||||
return [
|
||||
LLMProviderConfig(
|
||||
id=p.id,
|
||||
provider_type=LLMProviderType(p.provider_type),
|
||||
name=p.name,
|
||||
base_url=p.base_url,
|
||||
api_key="********",
|
||||
default_model=p.default_model,
|
||||
is_active=p.is_active
|
||||
) for p in providers
|
||||
]
|
||||
# [/DEF:get_providers:Function]
|
||||
|
||||
# [DEF:create_provider:Function]
|
||||
# @PURPOSE: Create a new LLM provider configuration.
|
||||
# @PRE: User is authenticated and has admin permissions.
|
||||
# @POST: Returns the created LLMProviderConfig.
|
||||
@router.post("/providers", response_model=LLMProviderConfig, status_code=status.HTTP_201_CREATED)
|
||||
async def create_provider(
|
||||
config: LLMProviderConfig,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Create a new LLM provider configuration.
|
||||
"""
|
||||
service = LLMProviderService(db)
|
||||
provider = service.create_provider(config)
|
||||
return LLMProviderConfig(
|
||||
id=provider.id,
|
||||
provider_type=LLMProviderType(provider.provider_type),
|
||||
name=provider.name,
|
||||
base_url=provider.base_url,
|
||||
api_key="********",
|
||||
default_model=provider.default_model,
|
||||
is_active=provider.is_active
|
||||
)
|
||||
# [/DEF:create_provider:Function]
|
||||
|
||||
# [DEF:update_provider:Function]
|
||||
# @PURPOSE: Update an existing LLM provider configuration.
|
||||
# @PRE: User is authenticated and has admin permissions.
|
||||
# @POST: Returns the updated LLMProviderConfig.
|
||||
@router.put("/providers/{provider_id}", response_model=LLMProviderConfig)
|
||||
async def update_provider(
|
||||
provider_id: str,
|
||||
config: LLMProviderConfig,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Update an existing LLM provider configuration.
|
||||
"""
|
||||
service = LLMProviderService(db)
|
||||
provider = service.update_provider(provider_id, config)
|
||||
if not provider:
|
||||
raise HTTPException(status_code=404, detail="Provider not found")
|
||||
|
||||
return LLMProviderConfig(
|
||||
id=provider.id,
|
||||
provider_type=LLMProviderType(provider.provider_type),
|
||||
name=provider.name,
|
||||
base_url=provider.base_url,
|
||||
api_key="********",
|
||||
default_model=provider.default_model,
|
||||
is_active=provider.is_active
|
||||
)
|
||||
# [/DEF:update_provider:Function]
|
||||
|
||||
# [DEF:delete_provider:Function]
|
||||
# @PURPOSE: Delete an LLM provider configuration.
|
||||
# @PRE: User is authenticated and has admin permissions.
|
||||
# @POST: Returns success status.
|
||||
@router.delete("/providers/{provider_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_provider(
|
||||
provider_id: str,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Delete an LLM provider configuration.
|
||||
"""
|
||||
service = LLMProviderService(db)
|
||||
if not service.delete_provider(provider_id):
|
||||
raise HTTPException(status_code=404, detail="Provider not found")
|
||||
return
|
||||
# [/DEF:delete_provider:Function]
|
||||
|
||||
# [DEF:test_connection:Function]
|
||||
# @PURPOSE: Test connection to an LLM provider.
|
||||
# @PRE: User is authenticated.
|
||||
# @POST: Returns success status and message.
|
||||
@router.post("/providers/{provider_id}/test")
|
||||
async def test_connection(
|
||||
provider_id: str,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
logger.info(f"[llm_routes][test_connection][Action] Testing connection for provider_id: {provider_id}")
|
||||
"""
|
||||
Test connection to an LLM provider.
|
||||
"""
|
||||
from ...plugins.llm_analysis.service import LLMClient
|
||||
service = LLMProviderService(db)
|
||||
db_provider = service.get_provider(provider_id)
|
||||
if not db_provider:
|
||||
raise HTTPException(status_code=404, detail="Provider not found")
|
||||
|
||||
api_key = service.get_decrypted_api_key(provider_id)
|
||||
client = LLMClient(
|
||||
provider_type=LLMProviderType(db_provider.provider_type),
|
||||
api_key=api_key,
|
||||
base_url=db_provider.base_url,
|
||||
default_model=db_provider.default_model
|
||||
)
|
||||
|
||||
try:
|
||||
# Simple test call
|
||||
await client.client.models.list()
|
||||
return {"success": True, "message": "Connection successful"}
|
||||
except Exception as e:
|
||||
return {"success": False, "error": str(e)}
|
||||
# [/DEF:test_connection:Function]
|
||||
|
||||
# [DEF:test_provider_config:Function]
|
||||
# @PURPOSE: Test connection with a provided configuration (not yet saved).
|
||||
# @PRE: User is authenticated.
|
||||
# @POST: Returns success status and message.
|
||||
@router.post("/providers/test")
|
||||
async def test_provider_config(
|
||||
config: LLMProviderConfig,
|
||||
current_user: User = Depends(get_current_active_user)
|
||||
):
|
||||
"""
|
||||
Test connection with a provided configuration.
|
||||
"""
|
||||
from ...plugins.llm_analysis.service import LLMClient
|
||||
logger.info(f"[llm_routes][test_provider_config][Action] Testing config for {config.name}")
|
||||
|
||||
client = LLMClient(
|
||||
provider_type=config.provider_type,
|
||||
api_key=config.api_key,
|
||||
base_url=config.base_url,
|
||||
default_model=config.default_model
|
||||
)
|
||||
|
||||
try:
|
||||
# Simple test call
|
||||
await client.client.models.list()
|
||||
return {"success": True, "message": "Connection successful"}
|
||||
except Exception as e:
|
||||
return {"success": False, "error": str(e)}
|
||||
# [/DEF:test_provider_config:Function]
|
||||
|
||||
# [/DEF:backend/src/api/routes/llm.py]
|
||||
@@ -9,7 +9,7 @@ from pydantic import BaseModel
|
||||
from ...core.logger import belief_scope
|
||||
|
||||
from ...core.task_manager import TaskManager, Task, TaskStatus, LogEntry
|
||||
from ...dependencies import get_task_manager, has_permission
|
||||
from ...dependencies import get_task_manager, has_permission, get_current_user
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -34,13 +34,30 @@ class ResumeTaskRequest(BaseModel):
|
||||
async def create_task(
|
||||
request: CreateTaskRequest,
|
||||
task_manager: TaskManager = Depends(get_task_manager),
|
||||
_ = Depends(lambda req: has_permission(f"plugin:{req.plugin_id}", "EXECUTE"))
|
||||
current_user = Depends(get_current_user)
|
||||
):
|
||||
# Dynamic permission check based on plugin_id
|
||||
has_permission(f"plugin:{request.plugin_id}", "EXECUTE")(current_user)
|
||||
"""
|
||||
Create and start a new task for a given plugin.
|
||||
"""
|
||||
with belief_scope("create_task"):
|
||||
try:
|
||||
# Special handling for validation task to include provider config
|
||||
if request.plugin_id == "llm_dashboard_validation":
|
||||
from ...core.database import SessionLocal
|
||||
from ...services.llm_provider import LLMProviderService
|
||||
db = SessionLocal()
|
||||
try:
|
||||
llm_service = LLMProviderService(db)
|
||||
provider_id = request.params.get("provider_id")
|
||||
if provider_id:
|
||||
db_provider = llm_service.get_provider(provider_id)
|
||||
if not db_provider:
|
||||
raise ValueError(f"LLM Provider {provider_id} not found")
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
task = await task_manager.create_task(
|
||||
plugin_id=request.plugin_id,
|
||||
params=request.params
|
||||
|
||||
Reference in New Issue
Block a user