File size: 2,657 Bytes
1397957
 
 
 
 
 
dd651c4
1397957
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d3620d
 
1397957
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dd651c4
1397957
 
 
 
 
 
 
 
1d3620d
 
 
1397957
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from contextlib import asynccontextmanager
import os

from src.opencode_api.routes import session_router, provider_router, event_router, question_router, agent_router, docs_router
from src.opencode_api.provider import (
    register_provider, 
    AnthropicProvider, 
    OpenAIProvider, 
    LiteLLMProvider, 
    GeminiProvider,
    BlabladorProvider
)
from src.opencode_api.tool import register_tool, WebSearchTool, WebFetchTool, TodoTool, QuestionTool, SkillTool
from src.opencode_api.core.config import settings


@asynccontextmanager
async def lifespan(app: FastAPI):
    register_provider(BlabladorProvider())
    register_provider(LiteLLMProvider())
    register_provider(AnthropicProvider())
    register_provider(OpenAIProvider())
    register_provider(GeminiProvider(api_key=settings.google_api_key))
    
    # Register tools
    register_tool(WebSearchTool())
    register_tool(WebFetchTool())
    register_tool(TodoTool())
    register_tool(QuestionTool())
    register_tool(SkillTool())
    
    yield


app = FastAPI(
    title="OpenCode API",
    description="LLM Agent API Server - ported from TypeScript opencode",
    version="0.1.0",
    lifespan=lifespan,
    docs_url="/swagger-docs",
    redoc_url="/redoc-docs",
)

# CORS settings for aicampus frontend
ALLOWED_ORIGINS = [
    "https://aicampus.kr",
    "https://www.aicampus.kr",
    "https://aicampus.vercel.app",
    "http://localhost:3000",
    "http://127.0.0.1:3000",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=ALLOWED_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    return JSONResponse(
        status_code=500,
        content={"error": str(exc), "type": type(exc).__name__}
    )


app.include_router(session_router)
app.include_router(provider_router)
app.include_router(event_router)
app.include_router(question_router)
app.include_router(agent_router)
app.include_router(docs_router)


@app.get("/")
async def root():
    return {
        "name": "OpenCode API",
        "version": "0.1.0",
        "status": "running",
        "docs": "/docs",
        "swagger": "/swagger-docs",
        "redoc": "/redoc-docs"
    }


@app.get("/health")
async def health():
    return {"status": "healthy"}


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "app:app",
        host=settings.host,
        port=settings.port,
        reload=settings.debug,
    )