File size: 3,003 Bytes
a10e62e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""
Auto-Install API Routes - Automatic package installation.

Endpoints:
- POST /auto-install/install - Install dependencies for a skill
- POST /auto-install/batch - Batch install for multiple skills
- GET /auto-install/status/{skill_id} - Get installation status

Reference: Phase 60 Plan 04
"""

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from typing import List, Optional

from core.database import get_db
from core.auto_installer_service import AutoInstallerService

router = APIRouter(prefix="/auto-install", tags=["auto-install"])


class InstallRequest(BaseModel):
    skill_id: str = Field(..., description="Skill ID for installation")
    packages: List[str] = Field(..., min_items=1, description="Package specifiers")
    package_type: str = Field("python", description="Package type: python or npm")
    agent_id: str = Field(..., description="Agent ID requesting installation")
    scan_for_vulnerabilities: bool = Field(True, description="Run security scan")


class BatchInstallRequest(BaseModel):
    installations: List[InstallRequest] = Field(..., min_items=1, description="Installation specs")
    agent_id: str = Field(..., description="Agent ID requesting installations")


@router.post("/install")
async def install_skill_dependencies(
    request: InstallRequest,
    db: Session = Depends(get_db)
):
    """Install dependencies for a single skill."""
    service = AutoInstallerService(db)

    result = await service.install_dependencies(
        skill_id=request.skill_id,
        packages=request.packages,
        package_type=request.package_type,
        agent_id=request.agent_id,
        scan_for_vulnerabilities=request.scan_for_vulnerabilities
    )

    if not result["success"]:
        raise HTTPException(status_code=400, detail=result)

    return result


@router.post("/batch")
async def batch_install_dependencies(
    request: BatchInstallRequest,
    db: Session = Depends(get_db)
):
    """Install dependencies for multiple skills."""
    service = AutoInstallerService(db)

    installations = [
        {
            "skill_id": req.skill_id,
            "packages": req.packages,
            "package_type": req.package_type
        }
        for req in request.installations
    ]

    result = await service.batch_install(
        installations=installations,
        agent_id=request.agent_id
    )

    return result


@router.get("/status/{skill_id}")
def get_installation_status(
    skill_id: str,
    package_type: str = "python",
    db: Session = Depends(get_db)
):
    """Check if skill packages are installed (image exists)."""
    service = AutoInstallerService(db)

    image_tag = service._get_image_tag(skill_id, package_type)
    exists = service._image_exists(image_tag, package_type)

    return {
        "skill_id": skill_id,
        "package_type": package_type,
        "installed": exists,
        "image_tag": image_tag if exists else None
    }