首次提交:初始化项目代码
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"resume-platform/internal/service/chat"
|
||||
"resume-platform/pkg/logger"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
ReadBufferSize: 4096,
|
||||
WriteBufferSize: 4096,
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
}
|
||||
|
||||
type IMHandler struct {
|
||||
imService *chat.IMService
|
||||
}
|
||||
|
||||
func NewIMHandler(imService *chat.IMService) *IMHandler {
|
||||
return &IMHandler{imService: imService}
|
||||
}
|
||||
|
||||
func (h *IMHandler) WebSocket(c *gin.Context) {
|
||||
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to upgrade connection: %v", err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
ctx := c.Request.Context()
|
||||
logger.CtxInfof(ctx, "WebSocket connection opened")
|
||||
|
||||
for {
|
||||
_, msg, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {
|
||||
logger.CtxInfof(ctx, "WebSocket connection closed normally")
|
||||
} else {
|
||||
logger.CtxErrorf(ctx, "WebSocket read error: %v", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
var request struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
if err := json.Unmarshal(msg, &request); err != nil {
|
||||
logger.CtxErrorf(ctx, "Failed to parse message: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if request.Message == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
go h.handleMessage(ctx, conn, request.Message)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *IMHandler) handleMessage(ctx context.Context, conn *websocket.Conn, message string) {
|
||||
logger.CtxInfof(ctx, "Received message: %s", message)
|
||||
|
||||
agent := h.imService.GetResumeAgent()
|
||||
var result string
|
||||
var err error
|
||||
if agent != nil {
|
||||
logger.CtxInfof(ctx, "Using Eino Resume Agent for request")
|
||||
result, err = h.imService.GenerateWithAgent(ctx, message)
|
||||
} else {
|
||||
logger.CtxInfof(ctx, "Using AI Provider for request")
|
||||
result, err = h.imService.GetAIProvider().Generate(ctx, message)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.CtxErrorf(ctx, "AI generate failed: %v", err)
|
||||
response := map[string]interface{}{
|
||||
"type": "error",
|
||||
"message": err.Error(),
|
||||
}
|
||||
if err := conn.WriteJSON(response); err != nil {
|
||||
logger.CtxErrorf(ctx, "Failed to send error response: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
response := map[string]interface{}{
|
||||
"type": "message",
|
||||
"content": result,
|
||||
}
|
||||
|
||||
if err := conn.WriteJSON(response); err != nil {
|
||||
logger.CtxErrorf(ctx, "Failed to send response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *IMHandler) Chat(c *gin.Context) {
|
||||
var request struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
|
||||
return
|
||||
}
|
||||
|
||||
if request.Message == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "message is required"})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := c.Request.Context()
|
||||
logger.CtxInfof(ctx, "Chat request: %s", request.Message)
|
||||
|
||||
result, err := h.imService.GetAIProvider().Generate(ctx, request.Message)
|
||||
if err != nil {
|
||||
logger.CtxErrorf(ctx, "AI generate failed: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"response": result})
|
||||
}
|
||||
|
||||
func (h *IMHandler) ChatStream(c *gin.Context) {
|
||||
var request struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
|
||||
return
|
||||
}
|
||||
|
||||
if request.Message == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "message is required"})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := c.Request.Context()
|
||||
logger.CtxInfof(ctx, "Chat stream request: %s", request.Message)
|
||||
|
||||
c.Stream(func(w io.Writer) bool {
|
||||
result, err := h.imService.GetAIProvider().Generate(ctx, request.Message)
|
||||
if err != nil {
|
||||
logger.CtxErrorf(ctx, "AI generate failed: %v", err)
|
||||
c.SSEvent("error", gin.H{"message": err.Error()})
|
||||
return false
|
||||
}
|
||||
|
||||
for _, char := range result {
|
||||
c.SSEvent("message", string(char))
|
||||
}
|
||||
c.SSEvent("done", gin.H{})
|
||||
return false
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user