File size: 3,716 Bytes
3493993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from __future__ import annotations

from typing import Annotated

from fastapi import APIRouter, Header, Path, Query, Request, status

from app.copilot.schemas import (
    CopilotCapabilities,
    CopilotContextInput,
    CopilotExecuteRequest,
    CopilotRun,
    CopilotRunCreate,
    CopilotRunList,
)
from app.security.errors import ForbiddenError

router = APIRouter(prefix="/v1/copilot", tags=["copilot"])


def _identity(request: Request):
    context = request.state.auth
    if not context.workspace_id or not context.user_id:
        raise ForbiddenError
    return context


@router.post("/capabilities", response_model=CopilotCapabilities)
async def capabilities(request: Request, context: CopilotContextInput) -> CopilotCapabilities:
    identity = _identity(request)
    return await request.app.state.container.copilot.capabilities(
        workspace_id=identity.workspace_id,
        user_id=identity.user_id,
        context=context,
    )


@router.post("/runs", response_model=CopilotRun, status_code=status.HTTP_201_CREATED)
async def create_run(
    request: Request,
    payload: CopilotRunCreate,
    idempotency_key: Annotated[str, Header(alias="Idempotency-Key", min_length=8, max_length=255)],
) -> CopilotRun:
    identity = _identity(request)
    return await request.app.state.container.copilot.create_run(
        workspace_id=identity.workspace_id,
        user_id=identity.user_id,
        api_key_id=identity.api_key_id,
        request_id=request.state.request_id,
        payload=payload,
        idempotency_key=idempotency_key,
    )


@router.get("/runs", response_model=CopilotRunList)
async def list_runs(
    request: Request,
    offset: Annotated[int, Query(ge=0)] = 0,
    limit: Annotated[int, Query(ge=1, le=100)] = 25,
) -> CopilotRunList:
    identity = _identity(request)
    return await request.app.state.container.copilot.list(
        workspace_id=identity.workspace_id,
        user_id=identity.user_id,
        offset=offset,
        limit=limit,
    )


@router.get("/history", response_model=CopilotRunList)
async def history(
    request: Request,
    offset: Annotated[int, Query(ge=0)] = 0,
    limit: Annotated[int, Query(ge=1, le=100)] = 25,
) -> CopilotRunList:
    return await list_runs(request, offset, limit)


@router.get("/runs/{run_id}", response_model=CopilotRun)
async def get_run(
    request: Request,
    run_id: Annotated[str, Path(min_length=36, max_length=36)],
) -> CopilotRun:
    identity = _identity(request)
    return await request.app.state.container.copilot.get(
        workspace_id=identity.workspace_id,
        user_id=identity.user_id,
        run_id=run_id,
    )


@router.post("/runs/{run_id}/execute", response_model=CopilotRun)
async def execute_run(
    request: Request,
    payload: CopilotExecuteRequest,
    run_id: Annotated[str, Path(min_length=36, max_length=36)],
) -> CopilotRun:
    identity = _identity(request)
    return await request.app.state.container.copilot.execute(
        workspace_id=identity.workspace_id,
        user_id=identity.user_id,
        api_key_id=identity.api_key_id,
        request_id=request.state.request_id,
        run_id=run_id,
        payload=payload,
        permissions=identity.scopes,
    )


@router.post("/runs/{run_id}/cancel", response_model=CopilotRun)
async def cancel_run(
    request: Request,
    run_id: Annotated[str, Path(min_length=36, max_length=36)],
) -> CopilotRun:
    identity = _identity(request)
    return await request.app.state.container.copilot.cancel(
        workspace_id=identity.workspace_id,
        user_id=identity.user_id,
        api_key_id=identity.api_key_id,
        request_id=request.state.request_id,
        run_id=run_id,
    )