You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

116 lines
2.8 KiB

package mcp
import (
"context"
"encoding/json"
"fmt"
"yunyan/lego/core"
"yunyan/lego/core/cbase"
"yunyan/lego/sys/log"
lgmigu "yunyan/sys/migu"
"github.com/google/uuid"
"github.com/mark3labs/mcp-go/mcp"
)
type tool_migu_music struct {
cbase.ModuleCompBase
module *Mcp
}
func (this *tool_migu_music) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) {
this.ModuleCompBase.Init(service, module, comp, opt)
this.module = module.(*Mcp)
return
}
func (this *tool_migu_music) Start() (err error) {
err = this.ModuleCompBase.Start()
if this.module.AddTool(ToolGroup_CHINA, this.Tool(), this.Handl) {
if initErr := lgmigu.OnInit(this.module.service.GetSettings().Sys["migu"]); initErr != nil {
panic(fmt.Sprintf("init sys.migu err: %s", initErr.Error()))
} else {
log.Infof("init sys.migu success!")
}
}
return
}
func (this *tool_migu_music) Tool() mcp.Tool {
return mcp.NewTool("migu_music_search",
mcp.WithDescription("通过咪咕灵犀搜索音乐,返回带播放信息的音乐列表卡片"),
mcp.WithString("query",
mcp.Description("搜索的音乐关键字,例如:小苹果、周杰伦、流行音乐等"),
mcp.Required(),
),
)
}
// MiguMusicCard 单条咪咕音乐卡片(H5/模板卡片的原始结构)
type MiguMusicCard struct {
Type string `json:"type"` // "2"=H5, "3"=模板
Data json.RawMessage `json:"data"` // 咪咕返回的原始卡片数据
}
func (this *tool_migu_music) Handl(ctx context.Context, request mcp.CallToolRequest) (result *mcp.CallToolResult, err error) {
query, err := request.RequireString("query")
if err != nil {
err = fmt.Errorf("query is required")
return
}
reqId := uuid.NewString()
miguReq := &lgmigu.Request{
ReqId: reqId,
Messages: []lgmigu.Message{{Role: "user", Content: fmt.Sprintf("帮我搜索并播放:%s", query)}},
Stream: true,
Session: &lgmigu.Session{SessionId: reqId},
}
ch := make(chan *lgmigu.StreamResp, 8)
go func() {
if e := lgmigu.Chat(ctx, miguReq, ch); e != nil {
log.Errorf("migu music search err: %v", e)
}
}()
var cards []*MiguMusicCard
for sr := range ch {
if sr == nil || len(sr.Choices) == 0 {
continue
}
c := sr.Choices[0]
if c.Delta.Content == nil {
continue
}
switch c.Delta.Content.Type {
case lgmigu.ContentTypeH5, lgmigu.ContentTypeTemplate:
cards = append(cards, &MiguMusicCard{
Type: c.Delta.Content.Type,
Data: c.Delta.Content.Data,
})
}
}
var text string
if len(cards) == 0 {
text = fmt.Sprintf(`{"result":"no_music","message":"未找到相关音乐:%s"}`, query)
} else {
b, _ := json.Marshal(map[string]interface{}{
"result": "success",
"data": cards,
})
text = string(b)
}
result = &mcp.CallToolResult{
Content: []mcp.Content{
mcp.TextContent{
Type: "text",
Text: text,
},
},
}
return
}