package migu import ( "yunyan/comm" "yunyan/modules" "fmt" "net/http" "time" "yunyan/lego/base" "yunyan/lego/core" "yunyan/lego/sys/log" httpSwagger "github.com/swaggo/http-swagger" _ "yunyan/swagger/migu" // migu 专属 swagger 文档(instanceName=migu) ) /* 模块名:移动灵犀聊天服务(migu) 说明:独立部署,对外暴露普通聊天接口 POST /chat(支持流式 SSE 与非流式 JSON), 内部按咪咕「智能体能力统一对外输出API」格式调用咪咕灵犀(sys/migu), 并把咪咕响应(文本/思考/音乐等结构化卡片/追问词)整理后返回。不使用 gateway 的路由转发机制。 */ func NewModule() core.IModule { return new(Migu) } type Migu struct { modules.ModuleBase service base.ISingleService options *Options } func (this *Migu) GetType() core.M_Modules { return comm.ModuleMigu } func (this *Migu) NewOptions() (options core.IModuleOptions) { return new(Options) } func (this *Migu) Init(service core.IService, module core.IModule, options core.IModuleOptions) (err error) { this.service = service.(base.ISingleService) this.options = options.(*Options) if err = this.ModuleBase.Init(service, module, options); err != nil { return } return } func (this *Migu) Start() (err error) { if err = this.ModuleBase.Start(); err != nil { return } go this.run() return } func (this *Migu) OnInstallComp() { this.ModuleBase.OnInstallComp() } // run 启动独立的 HTTP 服务入口;启动失败直接 panic 退出进程 func (this *Migu) run() { mux := http.NewServeMux() mux.HandleFunc("/chat", this.handleChat) // migu 专属 swagger UI:访问 /swagger/index.html(instanceName=migu) mux.HandleFunc("/swagger/", httpSwagger.Handler(httpSwagger.InstanceName("migu"))) mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"status":"ok"}`)) }) handler := withCORS(withRecover(mux)) httpServer := &http.Server{ Addr: fmt.Sprintf(":%d", this.options.Port), Handler: handler, ReadTimeout: 5 * time.Minute, WriteTimeout: 30 * time.Minute, // 流式回复可能较长 IdleTimeout: 5 * time.Minute, } // TLS 由外层 nginx 处理,本服务只监听明文 HTTP log.Infof("migu openai-compatible server listening on :%d", this.options.Port) if err := httpServer.ListenAndServe(); err != nil { log.Panicf("migu server error: %v", err) } }