104 lines
3.1 KiB
Go
104 lines
3.1 KiB
Go
package v1
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
|
|
"github.com/chaitin/panda-wiki/domain"
|
|
"github.com/chaitin/panda-wiki/handler"
|
|
"github.com/chaitin/panda-wiki/log"
|
|
"github.com/chaitin/panda-wiki/usecase"
|
|
)
|
|
|
|
type CreationHandler struct {
|
|
*handler.BaseHandler
|
|
logger *log.Logger
|
|
usecase *usecase.CreationUsecase
|
|
}
|
|
|
|
func NewCreationHandler(echo *echo.Echo, baseHandler *handler.BaseHandler, logger *log.Logger, usecase *usecase.CreationUsecase) *CreationHandler {
|
|
h := &CreationHandler{
|
|
BaseHandler: baseHandler,
|
|
logger: logger.WithModule("handler.v1.creation"),
|
|
usecase: usecase,
|
|
}
|
|
|
|
api := echo.Group("/api/v1/creation", h.V1Auth.Authorize)
|
|
api.POST("/text", h.Text)
|
|
api.POST("/tab-complete", h.TabComplete)
|
|
|
|
return h
|
|
}
|
|
|
|
// Text text creation
|
|
//
|
|
// @Summary Text creation
|
|
// @Description Text creation
|
|
// @Tags creation
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param body body domain.TextReq true "text creation request"
|
|
// @Success 200 {string} string "success"
|
|
// @Router /api/v1/creation/text [post]
|
|
func (h *CreationHandler) Text(c echo.Context) error {
|
|
var req domain.TextReq
|
|
if err := c.Bind(&req); err != nil {
|
|
return h.NewResponseWithError(c, "request body is invalid", err)
|
|
}
|
|
if err := c.Validate(req); err != nil {
|
|
return h.NewResponseWithError(c, "validate request body failed", err)
|
|
}
|
|
|
|
c.Response().Header().Set("Content-Type", "text/event-stream")
|
|
c.Response().Header().Set("Cache-Control", "no-cache")
|
|
c.Response().Header().Set("Connection", "keep-alive")
|
|
c.Response().Header().Set("Transfer-Encoding", "chunked")
|
|
|
|
onChunk := func(ctx context.Context, dataType, chunk string) error {
|
|
if _, err := c.Response().Write([]byte(chunk)); err != nil {
|
|
return err
|
|
}
|
|
c.Response().Flush()
|
|
return nil
|
|
}
|
|
err := h.usecase.TextCreation(c.Request().Context(), &req, onChunk)
|
|
if err != nil {
|
|
h.logger.Error("text creation failed", log.Error(err))
|
|
return h.NewResponseWithError(c, "text creation failed", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// TabComplete handles tab-based document completion similar to AI coding's FIM (Fill in Middle)
|
|
//
|
|
// @Summary Tab-based document completion
|
|
// @Description Tab-based document completion similar to AI coding's FIM (Fill in Middle)
|
|
// @Tags creation
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param body body domain.CompleteReq true "tab completion request"
|
|
// @Success 200 {string} string "success"
|
|
// @Router /api/v1/creation/tab-complete [post]
|
|
func (h *CreationHandler) TabComplete(c echo.Context) error {
|
|
var req domain.CompleteReq
|
|
if err := c.Bind(&req); err != nil {
|
|
return h.NewResponseWithError(c, "request body is invalid", err)
|
|
}
|
|
if err := c.Validate(req); err != nil {
|
|
return h.NewResponseWithError(c, "validate request body failed", err)
|
|
}
|
|
|
|
// For FIM-style completion, we don't need streaming
|
|
result, err := h.usecase.TabComplete(c.Request().Context(), &req)
|
|
if err != nil {
|
|
h.logger.Error("tab completion failed", log.Error(err))
|
|
return h.NewResponseWithError(c, "tab completion failed", err)
|
|
}
|
|
|
|
return c.JSON(200, map[string]interface{}{
|
|
"success": true,
|
|
"data": result,
|
|
})
|
|
}
|