mcp_agent.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package llm
  2. import (
  3. "fmt"
  4. "strings"
  5. "yunion.io/x/jsonutils"
  6. "yunion.io/x/onecloud/pkg/apis"
  7. api "yunion.io/x/onecloud/pkg/apis/llm"
  8. "yunion.io/x/onecloud/pkg/mcclient/options"
  9. )
  10. type MCPAgentListOptions struct {
  11. options.BaseListOptions
  12. LLMDriver string `json:"llm_driver" help:"filter by llm driver (ollama or openai)"`
  13. DefaultAgent *bool `json:"default_agent,omitempty" help:"filter by default agent (true to list the default one)"`
  14. }
  15. func (o *MCPAgentListOptions) Params() (jsonutils.JSONObject, error) {
  16. return options.ListStructToParams(o)
  17. }
  18. type MCPAgentShowOptions struct {
  19. options.BaseShowOptions
  20. }
  21. func (o *MCPAgentShowOptions) Params() (jsonutils.JSONObject, error) {
  22. return options.StructToParams(o)
  23. }
  24. type MCPAgentCreateOptions struct {
  25. apis.SharableVirtualResourceCreateInput
  26. LlmId string `help:"LLM 实例 ID,如果提供则自动获取 llm_url" json:"llm_id"`
  27. LLM_URL string `help:"后端大模型的 base 请求地址" json:"llm_url"`
  28. LLM_DRIVER string `help:"使用的大模型驱动,可以是 ollama 或 openai" json:"llm_driver" choices:"ollama|openai"`
  29. MODEL string `help:"使用的模型名称" json:"model"`
  30. API_KEY string `help:"访问大模型的密钥" json:"api_key"`
  31. McpServer string `help:"mcp 服务器的后端地址" json:"mcp_server"`
  32. DefaultAgent bool `help:"set as default MCP agent (only one can be true globally)" json:"default_agent"`
  33. }
  34. func (o *MCPAgentCreateOptions) Params() (jsonutils.JSONObject, error) {
  35. return jsonutils.Marshal(o), nil
  36. }
  37. type MCPAgentUpdateOptions struct {
  38. apis.SharableVirtualResourceBaseUpdateInput
  39. ID string
  40. LlmId *string `help:"LLM 实例 ID,如果提供则自动获取 llm_url" json:"llm_id,omitempty"`
  41. LlmUrl *string `help:"后端大模型的 base 请求地址" json:"llm_url,omitempty"`
  42. LlmDriver *string `help:"使用的大模型驱动,可以是 ollama 或 openai" json:"llm_driver,omitempty" choices:"ollama|openai"`
  43. Model *string `help:"使用的模型名称" json:"model,omitempty"`
  44. ApiKey *string `help:"访问大模型的密钥" json:"api_key,omitempty"`
  45. McpServer *string `help:"mcp 服务器的后端地址" json:"mcp_server,omitempty"`
  46. DefaultAgent *bool `help:"set as default MCP agent (only one can be true globally)" json:"default_agent,omitempty"`
  47. }
  48. func (o *MCPAgentUpdateOptions) GetId() string {
  49. return o.ID
  50. }
  51. func (o *MCPAgentUpdateOptions) Params() (jsonutils.JSONObject, error) {
  52. // 只包含非空字段
  53. params := jsonutils.NewDict()
  54. if o.LlmId != nil && len(*o.LlmId) > 0 {
  55. params.Set("llm_id", jsonutils.NewString(*o.LlmId))
  56. }
  57. if o.LlmUrl != nil && len(*o.LlmUrl) > 0 {
  58. params.Set("llm_url", jsonutils.NewString(*o.LlmUrl))
  59. }
  60. if o.LlmDriver != nil && len(*o.LlmDriver) > 0 {
  61. params.Set("llm_driver", jsonutils.NewString(*o.LlmDriver))
  62. }
  63. if o.Model != nil && len(*o.Model) > 0 {
  64. params.Set("model", jsonutils.NewString(*o.Model))
  65. }
  66. if o.ApiKey != nil && len(*o.ApiKey) > 0 {
  67. params.Set("api_key", jsonutils.NewString(*o.ApiKey))
  68. }
  69. if o.McpServer != nil && len(*o.McpServer) > 0 {
  70. params.Set("mcp_server", jsonutils.NewString(*o.McpServer))
  71. }
  72. if o.DefaultAgent != nil {
  73. params.Set("default_agent", jsonutils.NewBool(*o.DefaultAgent))
  74. }
  75. // 添加基础字段
  76. baseParams, err := options.StructToParams(&o.SharableVirtualResourceBaseUpdateInput)
  77. if err != nil {
  78. return nil, err
  79. }
  80. if baseParams != nil {
  81. params.Update(baseParams)
  82. }
  83. return params, nil
  84. }
  85. type MCPAgentDeleteOptions struct {
  86. options.BaseIdOptions
  87. }
  88. func (o *MCPAgentDeleteOptions) GetId() string {
  89. return o.ID
  90. }
  91. func (o *MCPAgentDeleteOptions) Params() (jsonutils.JSONObject, error) {
  92. return options.StructToParams(o)
  93. }
  94. type MCPAgentIdOptions struct {
  95. ID string `help:"mcp agent id" json:"-"`
  96. }
  97. func (opts *MCPAgentIdOptions) GetId() string {
  98. return opts.ID
  99. }
  100. func (opts *MCPAgentIdOptions) Params() (jsonutils.JSONObject, error) {
  101. return jsonutils.Marshal(opts), nil
  102. }
  103. type MCPAgentToolRequestOptions struct {
  104. MCPAgentIdOptions
  105. TOOL_NAME string `help:"tool name" json:"tool_name"`
  106. Argument []string `help:"tool arguments, e.g. key=value" json:"argument"`
  107. }
  108. func (opts *MCPAgentToolRequestOptions) Params() (jsonutils.JSONObject, error) {
  109. input := api.LLMToolRequestInput{
  110. ToolName: opts.TOOL_NAME,
  111. Arguments: make(map[string]interface{}),
  112. }
  113. for _, arg := range opts.Argument {
  114. idx := strings.Index(arg, "=")
  115. if idx > 0 {
  116. key := arg[:idx]
  117. val := arg[idx+1:]
  118. input.Arguments[key] = val
  119. }
  120. }
  121. return jsonutils.Marshal(input), nil
  122. }
  123. type MCPAgentMCPAgentRequestOptions struct {
  124. MCPAgentIdOptions
  125. MESSAGE string `help:"message to send to MCP agent" json:"message"`
  126. History string `help:"chat history as JSON string, e.g. '[{\"role\":\"user\",\"content\":\"hello\"}]'" json:"history,omitempty"`
  127. }
  128. func (opts *MCPAgentMCPAgentRequestOptions) Params() (jsonutils.JSONObject, error) {
  129. input := api.LLMMCPAgentRequestInput{
  130. Message: opts.MESSAGE,
  131. History: []api.MCPAgentChatMessage{},
  132. }
  133. if len(opts.History) > 0 {
  134. historyJSON, err := jsonutils.ParseString(opts.History)
  135. if err != nil {
  136. return nil, fmt.Errorf("failed to parse history JSON: %v", err)
  137. }
  138. if historyJSON != nil {
  139. err = historyJSON.Unmarshal(&input.History)
  140. if err != nil {
  141. return nil, fmt.Errorf("failed to unmarshal history: %v", err)
  142. }
  143. }
  144. }
  145. return jsonutils.Marshal(input), nil
  146. }
  147. // MCPAgentDefaultChatOptions 用于默认 Agent 聊天(不传 ID,使用 default_agent=true 的条目)
  148. type MCPAgentDefaultChatOptions struct {
  149. MESSAGE string `help:"message to send to MCP agent" json:"message"`
  150. History string `help:"chat history as JSON string, e.g. '[{\"role\":\"user\",\"content\":\"hello\"}]'" json:"history,omitempty"`
  151. }
  152. func (opts *MCPAgentDefaultChatOptions) Params() (jsonutils.JSONObject, error) {
  153. input := api.LLMMCPAgentRequestInput{
  154. Message: opts.MESSAGE,
  155. History: []api.MCPAgentChatMessage{},
  156. }
  157. if len(opts.History) > 0 {
  158. historyJSON, err := jsonutils.ParseString(opts.History)
  159. if err != nil {
  160. return nil, fmt.Errorf("failed to parse history JSON: %v", err)
  161. }
  162. if historyJSON != nil {
  163. err = historyJSON.Unmarshal(&input.History)
  164. if err != nil {
  165. return nil, fmt.Errorf("failed to unmarshal history: %v", err)
  166. }
  167. }
  168. }
  169. return jsonutils.Marshal(input), nil
  170. }