Files
YouduWiki/backend/handler/v1/creation.go
2026-05-21 19:52:45 +08:00

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,
})
}