ai_scheduler/internal/services/capability.go

131 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package services
import (
"ai_scheduler/internal/config"
"ai_scheduler/internal/data/constants"
errorcode "ai_scheduler/internal/data/error"
"ai_scheduler/internal/domain/workflow/runtime"
"ai_scheduler/internal/entitys"
"ai_scheduler/internal/pkg/util"
"ai_scheduler/internal/pkg/utils_ollama"
"context"
"fmt"
"strings"
"time"
"github.com/gofiber/fiber/v2"
"github.com/ollama/ollama/api"
)
// CapabilityService 统一回调入口
type CapabilityService struct {
cfg *config.Config
workflowManager *runtime.Registry
}
func NewCapabilityService(cfg *config.Config, workflowManager *runtime.Registry) *CapabilityService {
return &CapabilityService{
cfg: cfg,
workflowManager: workflowManager,
}
}
// 产品数据提取入参
type ProductIngestReq struct {
Url string `json:"url"` // 商品详情页URL
Title string `json:"title"` // 商品标题
Text string `json:"text"` // 商品描述
Images []string `json:"images"` // 商品图片URL列表
Timestamp int64 `json:"timestamp"` // 商品发布时间戳
}
// ProductIngest 产品数据提取
func (s *CapabilityService) ProductIngest(c *fiber.Ctx) error {
// 请求头校验
if err := s.checkRequestHeader(c); err != nil {
return err
}
// 解析请求参数
req := ProductIngestReq{}
if err := c.BodyParser(&req); err != nil {
return errorcode.ParamErr("invalid request body: %v", err)
}
// 必要参数校验
if req.Text == "" {
return errorcode.ParamErr("missing required fields")
}
// 模型调用
client, cleanup, err := utils_ollama.NewClient(s.cfg)
if err != nil {
return err
}
defer cleanup()
res, err := client.Chat(context.Background(), []api.Message{
{
Role: "system",
Content: fmt.Sprintf(constants.SystemPrompt, constants.HYTProductPropertyTemplateZH),
},
{
Role: "user",
Content: req.Text,
},
{
Role: "user",
Content: "商品图片URL列表" + strings.Join(req.Images, ","),
},
})
if err != nil {
return err
}
// res.Message.Content Go中map会无序交给前端解析
// 解析模型输出
c.JSON(res.Message.Content)
return nil
}
// checkRequestHeader 校验请求头
func (s *CapabilityService) checkRequestHeader(c *fiber.Ctx) error {
// 读取头
token := strings.TrimSpace(c.Get("X-Source-Key"))
ts := strings.TrimSpace(c.Get("X-Timestamp"))
// 时间窗口校验
if ts != "" && !util.IsInTimeWindow(ts, 5*time.Minute) {
return errorcode.AuthNotFound
}
// token校验
if token == "" || token != "A7f9KQ3mP2X8LZC4R5e" {
return errorcode.KeyErr()
}
return nil
}
// ProductUploadHyt 商品上传至货易通
func (s *CapabilityService) ProductUploadHyt(c *fiber.Ctx) error {
// 请求头校验
if err := s.checkRequestHeader(c); err != nil {
return err
}
// 获取 body json 串
raw := append([]byte(nil), c.BodyRaw()...)
bodyStr := string(raw)
// 调用eino工作流实现商品上传到货易通
workflowId := "hyt.productUpload"
rec := &entitys.Recognize{UserContent: &entitys.RecognizeUserContent{Text: bodyStr}}
res, err := s.workflowManager.Invoke(context.Background(), workflowId, rec)
if err != nil {
return err
}
return c.JSON(res)
}