| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- package service
- import (
- "context"
- "fmt"
- "io"
- "net/http"
- "time"
- "yunion.io/x/jsonutils"
- api "yunion.io/x/onecloud/pkg/apis/llm"
- "yunion.io/x/onecloud/pkg/appsrv"
- "yunion.io/x/onecloud/pkg/appsrv/dispatcher"
- "yunion.io/x/onecloud/pkg/cloudcommon/db"
- "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
- "yunion.io/x/onecloud/pkg/cloudcommon/policy"
- "yunion.io/x/onecloud/pkg/httperrors"
- "yunion.io/x/onecloud/pkg/llm/models"
- "yunion.io/x/onecloud/pkg/mcclient/auth"
- )
- func handleOllamaRegistryYAML(ctx context.Context, w http.ResponseWriter, r *http.Request) {
- yamlContent := models.GetInstantModelManager().GetOllamaRegistryYAML()
- w.Header().Set("Content-Type", "application/x-yaml; charset=utf-8")
- appsrv.Send(w, yamlContent)
- }
- func AddAvailableNetworkHandler(prefix string, app *appsrv.Application) {
- app.AddHandler2("GET", fmt.Sprintf("%s/available-network", prefix), auth.Authenticate(handleLLMAvailableNetwork), nil, "get_llm_available_network", nil)
- }
- func handleLLMAvailableNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request) {
- userCred := auth.FetchUserCredential(ctx, policy.FilterPolicyCredential)
- if userCred == nil {
- httperrors.UnauthorizedError(ctx, w, "Unauthorized")
- return
- }
- query, err := jsonutils.ParseQueryString(r.URL.RawQuery)
- if err != nil {
- httperrors.InvalidInputError(ctx, w, "Parse query string %q: %v", r.URL.RawQuery, err)
- return
- }
- ret, err := models.GetLLMManager().GetAvailableNetwork(ctx, userCred, query)
- if err != nil {
- httperrors.GeneralServerError(ctx, w, err)
- return
- }
- wrapped := jsonutils.NewDict()
- if ret != nil {
- wrapped.Add(ret, "llm")
- }
- appsrv.SendJSON(w, wrapped)
- }
- func handleLLMProviderModels(ctx context.Context, w http.ResponseWriter, r *http.Request) {
- userCred := auth.FetchUserCredential(ctx, policy.FilterPolicyCredential)
- if userCred == nil {
- httperrors.UnauthorizedError(ctx, w, "Unauthorized")
- return
- }
- query, err := jsonutils.ParseQueryString(r.URL.RawQuery)
- if err != nil {
- httperrors.InvalidInputError(ctx, w, "Parse query string %q: %v", r.URL.RawQuery, err)
- return
- }
- ret, err := models.GetLLMManager().GetProviderModels(ctx, userCred, query)
- if err != nil {
- httperrors.GeneralServerError(ctx, w, err)
- return
- }
- appsrv.SendStruct(w, ret)
- }
- func handleDefaultChatStream(ctx context.Context, w http.ResponseWriter, r *http.Request) {
- userCred := auth.FetchUserCredential(ctx, policy.FilterPolicyCredential)
- if userCred == nil {
- httperrors.UnauthorizedError(ctx, w, "Unauthorized")
- return
- }
- bodyBytes, err := io.ReadAll(r.Body)
- if err != nil {
- httperrors.GeneralServerError(ctx, w, err)
- return
- }
- body, err := jsonutils.Parse(bodyBytes)
- if err != nil {
- httperrors.InvalidInputError(ctx, w, "invalid body: %v", err)
- return
- }
- var input api.LLMMCPAgentRequestInput
- if body.Contains(models.GetMCPAgentManager().Keyword()) {
- agentObj, _ := body.Get(models.GetMCPAgentManager().Keyword())
- if agentObj != nil {
- body = agentObj
- }
- }
- if err := body.Unmarshal(&input); err != nil {
- httperrors.InvalidInputError(ctx, w, "invalid input: %v", err)
- return
- }
- defaultAgent, err := models.GetMCPAgentManager().GetDefaultAgent(ctx, userCred)
- if err != nil {
- httperrors.GeneralServerError(ctx, w, err)
- return
- }
- if defaultAgent == nil {
- httperrors.NotFoundError(ctx, w, "no default MCP agent set (set one agent with default_agent=true)")
- return
- }
- query := jsonutils.NewDict()
- _, err = defaultAgent.PerformChatStream(ctx, userCred, query, input)
- if err != nil {
- httperrors.GeneralServerError(ctx, w, err)
- return
- }
- }
- func handleDefaultMcpTools(ctx context.Context, w http.ResponseWriter, r *http.Request) {
- userCred := auth.FetchUserCredential(ctx, policy.FilterPolicyCredential)
- if userCred == nil {
- httperrors.UnauthorizedError(ctx, w, "Unauthorized")
- return
- }
- result, err := models.GetMCPAgentManager().GetDefaultMcpServerTools(ctx, userCred)
- if err != nil {
- httperrors.GeneralServerError(ctx, w, err)
- return
- }
- appsrv.SendJSON(w, result)
- }
- func InitHandlers(app *appsrv.Application, isSlave bool) {
- db.InitAllManagers()
- db.RegistUserCredCacheUpdater()
- taskman.AddTaskHandler("", app, isSlave)
- app.AddHandler("GET", "/ollama-registry.yaml", handleOllamaRegistryYAML)
- AddAvailableNetworkHandler(models.GetLLMManager().KeywordPlural(), app)
- // 默认 Agent 聊天流:优先于 dispatcher 注册,避免被 performClassAction 的 sendJSON 覆盖。
- // 注册两种路径:default-chat-stream(apigateway 转发用)与 default/chat-stream(climc 直连 region 时用,否则会被当作 resid=default 的 perform 导致 404)
- defaultChatStream := app.AddHandler2("POST", "/mcp_agents/default-chat-stream", auth.Authenticate(handleDefaultChatStream), nil, "default_chat_stream", nil)
- defaultChatStream.SetProcessTimeout(time.Hour * 4).SetWorkerManager(models.GetMCPAgentWorkerManager())
- defaultChatStreamSlash := app.AddHandler2("POST", "/mcp_agents/default/chat-stream", auth.Authenticate(handleDefaultChatStream), nil, "default_chat_stream_slash", nil)
- defaultChatStreamSlash.SetProcessTimeout(time.Hour * 4).SetWorkerManager(models.GetMCPAgentWorkerManager())
- // 默认 MCP 服务器 tools:仅使用 options.MCPServerURL,不依赖 mcp_agent 条目
- app.AddHandler2("GET", "/mcp_agents/default-mcp-tools", auth.Authenticate(handleDefaultMcpTools), nil, "default_mcp_tools", nil)
- for _, manager := range []db.IModelManager{
- taskman.TaskManager,
- taskman.SubTaskManager,
- taskman.TaskObjectManager,
- taskman.ArchivedTaskManager,
- db.SharedResourceManager,
- db.UserCacheManager,
- db.TenantCacheManager,
- } {
- db.RegisterModelManager(manager)
- }
- for _, manager := range []db.IModelManager{
- db.OpsLog,
- db.Metadata,
- models.GetLLMImageManager(),
- models.GetLLMSkuManager(),
- // models.GetDifySkuManager(),
- models.GetVolumeManager(),
- models.GetLLMBackupManager(),
- models.GetAccessInfoManager(),
- models.GetLLMContainerManager(),
- models.GetLLMManager(),
- // models.GetDifyManager(),
- models.GetInstantModelManager(),
- models.GetLLMInstantModelManager(),
- models.GetMCPAgentManager(),
- } {
- db.RegisterModelManager(manager)
- handler := db.NewModelHandler(manager)
- dispatcher.AddModelDispatcher("", app, handler, isSlave)
- }
- }
|