Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: webchat #256

Merged
merged 14 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions self_hosting_machinery/webgui/selfhost_lsp_proxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from fastapi import APIRouter
from starlette.requests import Request
from starlette.responses import StreamingResponse
from starlette.background import BackgroundTask
from fastapi import APIRouter
from self_hosting_machinery import env
import os
import json
import httpx

__all__ = ["LspProxy"]


def get_lsp_url() -> str:
lsp_cfg = json.load(open(os.path.join(env.DIR_WATCHDOG_TEMPLATES, "lsp.cfg")))
lsp_cmdline = lsp_cfg["command_line"]
lsp_port = "8001"

if "--port" in lsp_cmdline:
maybe_port:str = lsp_cmdline[lsp_cmdline.index("--port") + 1]
if maybe_port.isnumeric():
lsp_port = maybe_port

return "http://127.0.0.1:" + lsp_port


class LspProxy(APIRouter):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
super().add_route("/lsp/v1/caps", self._reverse_proxy, methods=["GET"])
super().add_route("/lsp/v1/chat", self._reverse_proxy, methods=["POST"])
lsp_address = get_lsp_url()
self._client = httpx.AsyncClient(base_url=lsp_address)

async def _reverse_proxy(self, request: Request):
path = request.url.path.replace("/lsp", "")
url = httpx.URL(path=path, query=request.url.query.encode("utf-8"))

rp_req = self._client.build_request(
request.method, url, headers=request.headers.raw, content=await request.body()
)
rp_resp = await self._client.send(rp_req, stream=True)
return StreamingResponse(
rp_resp.aiter_raw(),
status_code=rp_resp.status_code,
headers=rp_resp.headers,
background=BackgroundTask(rp_resp.aclose),
)



12 changes: 11 additions & 1 deletion self_hosting_machinery/webgui/selfhost_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ class StaticRouter(APIRouter):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
super().add_api_route("/", self._index, methods=["GET"])
super().add_api_route("/chat", self._chat, methods=["GET"])
super().add_api_route("/{file_path:path}", self._static_file, methods=["GET"])
super().add_api_route("/ping", self._ping_handler, methods=["GET"])
self.static_folders = [
os.path.join(os.path.dirname(os.path.abspath(__file__)), "static")
os.path.join(os.path.dirname(os.path.abspath(__file__)), "static"),
os.path.join(os.path.dirname(os.path.abspath(__file__)), "static", "assets")
]

async def _index(self):
Expand All @@ -24,9 +26,17 @@ async def _index(self):
return FileResponse(fn, media_type="text/html")
raise HTTPException(404, "No index.html found")

async def _chat(self):
for spath in self.static_folders:
fn = os.path.join(spath, "chat.html")
if os.path.exists(fn):
return FileResponse(fn, media_type="text/html")
raise HTTPException(404, "No chat.html found")

async def _static_file(self, file_path: str):
if ".." in file_path:
raise HTTPException(404, "Path \"%s\" not found" % file_path)

for spath in self.static_folders:
fn = os.path.join(spath, file_path)
if os.path.exists(fn):
Expand Down
120 changes: 120 additions & 0 deletions self_hosting_machinery/webgui/static/assets/chat.umd.cjs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions self_hosting_machinery/webgui/static/assets/style.css

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions self_hosting_machinery/webgui/static/assets/theme-config.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.radix-themes {
/** see https://www.radix-ui.com/themes/docs/theme/token-reference for variables to over-ride */
--default-font-family: 'Space Grotesk',sans-serif;
}
19 changes: 19 additions & 0 deletions self_hosting_machinery/webgui/static/chat.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en" class="light">
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Refact.ai Chat</title>
<!-- TODO: consider using a cdn for hosting these files after integrating with IDEs-->
<link rel="stylesheet" href="assets/style.css" />
<link rel="stylesheet" crossorigin href="/assets/theme-config.css">
<script src="assets/chat.umd.cjs"></script>
<body>
<div id="refact-chat"></div>
</body>
<script>
window.onload = function() {
RefactChat(document.getElementById("refact-chat"), "lsp")
}
</script>
</html>
11 changes: 11 additions & 0 deletions self_hosting_machinery/webgui/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<link rel="shortcut icon" href="#">
<link rel="icon" type="image/png" href="/favicon.png" />
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
<title>Refact Self Hosting</title>
Expand Down Expand Up @@ -65,6 +66,11 @@
</li>
{{/unless}}
{{/each}}
{{#unless hamburger}}
<li class="nav-item" role="presentation">
<button onclick="window.open('/chat', '_blank')" class="nav-link" id="{{id}}" {{#if disabled}}disabled{{/if}}>Chat</button>
</li>
{{/unless}}
<div class="d-flex ms-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button"
Expand All @@ -91,6 +97,11 @@
</li>
{{/if}}
{{/each}}
{{#if hamburger}}
<li class="nav-item" role="presentation">
<button onclick="window.open('/chat', '_blank')" class="nav-link main-tab-button" id="{{id}}-tab">Chat</button>
</li>
{{/if}}
</ul>
</li>
</div>
Expand Down
2 changes: 2 additions & 0 deletions self_hosting_machinery/webgui/webgui.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

from self_hosting_machinery.webgui.selfhost_database import RefactDatabase
from self_hosting_machinery.webgui.selfhost_database import StatisticsService
from self_hosting_machinery.webgui.selfhost_lsp_proxy import LspProxy

from typing import Dict

Expand Down Expand Up @@ -93,6 +94,7 @@ def _routers_list(
model_assigner=model_assigner),
TabHostRouter(model_assigner),
TabSettingsRouter(model_assigner),
LspProxy(),
StaticRouter(),
]

Expand Down
Loading