refactor: switch to /v1/events endpoint (#42)
* refactor: Add EventType enum for validation * refactor: use /v1/events in monaco components * refactor: use /v1/events in vscode client * refactor: remove unused api endpoint * refactor: improve api endpoint type checkadd-more-languages
parent
51e3b54016
commit
6da7c17f67
|
|
@ -110,9 +110,11 @@ export class TabbyClient extends EventEmitter {
|
|||
this.ping();
|
||||
}
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`${this.tabbyServerUrl}/v1/completions/${event.id}/choices/${event.index}/${event.type}`
|
||||
);
|
||||
const response = await axios.post(`${this.tabbyServerUrl}/v1/events`, {
|
||||
type: event.type,
|
||||
completion_id: event.id,
|
||||
choice_index: event.index
|
||||
});
|
||||
assert(response.status == 200);
|
||||
} catch (e) {
|
||||
this.ping();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"files": {
|
||||
"main.js": "./static/js/main.c14dfe27.js",
|
||||
"main.js": "./static/js/main.ab7e9a50.js",
|
||||
"index.html": "./index.html"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/main.c14dfe27.js"
|
||||
"static/js/main.ab7e9a50.js"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
<!doctype html><html lang="en"><head><title>Streamlit Component</title><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Streamlit Component"/><link rel="stylesheet" href="bootstrap.min.css"/><script defer="defer" src="./static/js/main.c14dfe27.js"></script></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><title>Streamlit Component</title><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Streamlit Component"/><link rel="stylesheet" href="bootstrap.min.css"/><script defer="defer" src="./static/js/main.ab7e9a50.js"></script></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,7 +1,7 @@
|
|||
import axios from "axios"
|
||||
import { useRenderData } from "streamlit-component-lib-react-hooks"
|
||||
|
||||
import React, { useRef, useEffect} from "react"
|
||||
import React, { useRef, useEffect } from "react"
|
||||
import Editor, { useMonaco } from "@monaco-editor/react"
|
||||
|
||||
let TabbyServerURL = "http://localhost:5000"
|
||||
|
|
@ -162,6 +162,10 @@ class CompletionProvider {
|
|||
}
|
||||
}
|
||||
|
||||
function logAction(id, index, event) {
|
||||
axios.post(`${TabbyServerURL}/v1/completions/${id}/choices/${index}/${event}`)
|
||||
function logAction(completion_id, choice_index, type) {
|
||||
axios.post(`${TabbyServerURL}/v1/events`, {
|
||||
type,
|
||||
completion_id,
|
||||
choice_index,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,15 @@ from fastapi import FastAPI, Response
|
|||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from . import events
|
||||
from . import events as events_lib
|
||||
from .backend import PythonModelService, TritonService
|
||||
from .models import CompletionRequest, CompletionResponse
|
||||
from .models import (
|
||||
ChoiceEvent,
|
||||
CompletionEvent,
|
||||
CompletionRequest,
|
||||
CompletionResponse,
|
||||
EventTypeMapping,
|
||||
)
|
||||
|
||||
app = FastAPI(
|
||||
title="TabbyServer",
|
||||
|
|
@ -37,23 +43,21 @@ else:
|
|||
|
||||
LOGS_DIR = os.environ.get("LOGS_DIR", None)
|
||||
if LOGS_DIR is not None:
|
||||
events.setup_logging(os.path.join(LOGS_DIR, "tabby-server"))
|
||||
events_lib.setup_logging(os.path.join(LOGS_DIR, "tabby-server"))
|
||||
|
||||
|
||||
@app.post("/v1/completions")
|
||||
async def completions(request: CompletionRequest) -> CompletionResponse:
|
||||
response = model_backend(request)
|
||||
events.log_completions(request, response)
|
||||
events_lib.log_completion(request, response)
|
||||
return response
|
||||
|
||||
|
||||
@app.post("/v1/completions/{id}/choices/{index}/view")
|
||||
async def view(id: str, index: int) -> JSONResponse:
|
||||
events.log_view(id, index)
|
||||
return JSONResponse(content="ok")
|
||||
|
||||
|
||||
@app.post("/v1/completions/{id}/choices/{index}/select")
|
||||
async def select(id: str, index: int) -> JSONResponse:
|
||||
events.log_select(id, index)
|
||||
return JSONResponse(content="ok")
|
||||
@app.post("/v1/events")
|
||||
async def events(e: ChoiceEvent | CompletionEvent) -> JSONResponse:
|
||||
if isinstance(e, EventTypeMapping[e.type]):
|
||||
events_lib.log_event(e)
|
||||
return JSONResponse(content="ok")
|
||||
else:
|
||||
print(type(e))
|
||||
return JSONResponse(content="invalid event", status_code=422)
|
||||
|
|
|
|||
|
|
@ -27,18 +27,12 @@ def setup_logging(logdir):
|
|||
)
|
||||
|
||||
|
||||
def log_completions(
|
||||
def log_completion(
|
||||
request: models.CompletionRequest, response: models.CompletionResponse
|
||||
) -> None:
|
||||
event = models.CompletionEvent.build(request, response)
|
||||
logger.info(event.json())
|
||||
|
||||
|
||||
def log_view(id: str, index: int) -> None:
|
||||
event = models.ChoiceEvent.build_view(id, index)
|
||||
logger.info(event.json())
|
||||
|
||||
|
||||
def log_select(id: str, index: int) -> None:
|
||||
event = models.ChoiceEvent.build_select(id, index)
|
||||
def log_event(event: models.Event):
|
||||
logger.info(event.json())
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from enum import Enum
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
|
@ -21,8 +22,14 @@ class CompletionResponse(BaseModel):
|
|||
choices: List[Choice]
|
||||
|
||||
|
||||
class EventType(str, Enum):
|
||||
COMPLETION = "completion"
|
||||
VIEW = "view"
|
||||
SELECT = "select"
|
||||
|
||||
|
||||
class Event(BaseModel):
|
||||
type: str
|
||||
type: EventType
|
||||
|
||||
|
||||
class CompletionEvent(Event):
|
||||
|
|
@ -34,7 +41,7 @@ class CompletionEvent(Event):
|
|||
@classmethod
|
||||
def build(cls, request: CompletionRequest, response: CompletionResponse):
|
||||
return cls(
|
||||
type="completion",
|
||||
type=EventType.COMPLETION,
|
||||
id=response.id,
|
||||
prompt=request.prompt,
|
||||
created=response.created,
|
||||
|
|
@ -46,10 +53,9 @@ class ChoiceEvent(Event):
|
|||
completion_id: str
|
||||
choice_index: int
|
||||
|
||||
@classmethod
|
||||
def build_view(cls, id, index):
|
||||
return cls(type="view", completion_id=id, choice_index=index)
|
||||
|
||||
@classmethod
|
||||
def build_select(cls, id, index):
|
||||
return cls(type="select", completion_id=id, choice_index=index)
|
||||
EventTypeMapping = {
|
||||
EventType.COMPLETION: CompletionEvent,
|
||||
EventType.VIEW: ChoiceEvent,
|
||||
EventType.SELECT: ChoiceEvent,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue