fix/hard-code #62
@@ -22,6 +22,10 @@ import (
|
|||||||
"github.com/hhs/camtalk/internal/ws"
|
"github.com/hhs/camtalk/internal/ws"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Version 通过构建时 -ldflags 注入,如:
|
||||||
|
// go build -ldflags "-X main.Version=v1.0.0" ./cmd/server
|
||||||
|
var Version string
|
||||||
|
|
||||||
var startTime = time.Now()
|
var startTime = time.Now()
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -43,7 +47,10 @@ func main() {
|
|||||||
// 初始化 Session Manager(MVP 默认内存实现)
|
// 初始化 Session Manager(MVP 默认内存实现)
|
||||||
var sessionMgr session.Manager
|
var sessionMgr session.Manager
|
||||||
// TODO: 当 Redis 配置非空时切换为 RedisManager
|
// TODO: 当 Redis 配置非空时切换为 RedisManager
|
||||||
sessionMgr = session.NewMemoryManager(30*time.Minute, 20)
|
sessionMgr = session.NewMemoryManager(
|
||||||
|
time.Duration(cfg.Session.TTL)*time.Minute,
|
||||||
|
cfg.Session.MaxHistory,
|
||||||
|
)
|
||||||
defer sessionMgr.(*session.MemoryManager).Stop()
|
defer sessionMgr.(*session.MemoryManager).Stop()
|
||||||
|
|
||||||
// 初始化 AI 服务
|
// 初始化 AI 服务
|
||||||
@@ -60,27 +67,27 @@ func main() {
|
|||||||
var sttService stt.Service
|
var sttService stt.Service
|
||||||
switch strings.ToLower(cfg.AI.STT.Provider) {
|
switch strings.ToLower(cfg.AI.STT.Provider) {
|
||||||
case "mimo", "xiaomi":
|
case "mimo", "xiaomi":
|
||||||
sttService = stt.NewMiMoService(cfg.AI.STT.APIKey, cfg.AI.STT.Model, cfg.AI.STT.Endpoint, logger.Log)
|
sttService = stt.NewMiMoService(cfg.AI.STT.APIKey, cfg.AI.STT.Model, cfg.AI.STT.Endpoint, cfg.AI.STT.Timeout, logger.Log)
|
||||||
logger.Log.Infow("STT service initialized", "provider", "mimo", "model", cfg.AI.STT.Model, "endpoint", cfg.AI.STT.Endpoint)
|
logger.Log.Infow("STT service initialized", "provider", "mimo", "model", cfg.AI.STT.Model, "endpoint", cfg.AI.STT.Endpoint)
|
||||||
default:
|
default:
|
||||||
sttService = stt.NewDeepgramService(cfg.AI.STT.APIKey, cfg.AI.STT.Model, cfg.AI.STT.Endpoint, logger.Log)
|
sttService = stt.NewDeepgramService(cfg.AI.STT.APIKey, cfg.AI.STT.Model, cfg.AI.STT.Endpoint, cfg.AI.STT.Timeout, logger.Log)
|
||||||
logger.Log.Infow("STT service initialized", "provider", "deepgram", "model", cfg.AI.STT.Model)
|
logger.Log.Infow("STT service initialized", "provider", "deepgram", "model", cfg.AI.STT.Model)
|
||||||
}
|
}
|
||||||
llmService := llm.NewOpenAIService(cfg.AI.LLM.APIKey, cfg.AI.LLM.Model, cfg.AI.LLM.Endpoint, cfg.AI.LLM.Timeout, logger.Log)
|
llmService := llm.NewOpenAIService(cfg.AI.LLM.APIKey, cfg.AI.LLM.Model, cfg.AI.LLM.Endpoint, cfg.AI.LLM.Timeout, cfg.AI.LLM.HTTPClientTimeout, logger.Log)
|
||||||
logger.Log.Infow("LLM service initialized", "provider", cfg.AI.LLM.Provider, "model", cfg.AI.LLM.Model, "endpoint", cfg.AI.LLM.Endpoint, "timeout", cfg.AI.LLM.Timeout)
|
logger.Log.Infow("LLM service initialized", "provider", cfg.AI.LLM.Provider, "model", cfg.AI.LLM.Model, "endpoint", cfg.AI.LLM.Endpoint, "timeout", cfg.AI.LLM.Timeout)
|
||||||
|
|
||||||
var ttsService tts.Service
|
var ttsService tts.Service
|
||||||
switch strings.ToLower(cfg.AI.TTS.Provider) {
|
switch strings.ToLower(cfg.AI.TTS.Provider) {
|
||||||
case "mimo", "xiaomi":
|
case "mimo", "xiaomi":
|
||||||
ttsService = tts.NewMiMoService(cfg.AI.TTS.APIKey, cfg.AI.TTS.Model, cfg.AI.TTS.Voice, cfg.AI.TTS.Endpoint, cfg.AI.TTS.Timeout, logger.Log)
|
ttsService = tts.NewMiMoService(cfg.AI.TTS.APIKey, cfg.AI.TTS.Model, cfg.AI.TTS.Voice, cfg.AI.TTS.Endpoint, cfg.AI.TTS.Timeout, cfg.AI.TTS.HTTPClientTimeout, logger.Log)
|
||||||
logger.Log.Infow("TTS service initialized", "provider", "mimo", "model", cfg.AI.TTS.Model, "voice", cfg.AI.TTS.Voice, "endpoint", cfg.AI.TTS.Endpoint)
|
logger.Log.Infow("TTS service initialized", "provider", "mimo", "model", cfg.AI.TTS.Model, "voice", cfg.AI.TTS.Voice, "endpoint", cfg.AI.TTS.Endpoint)
|
||||||
default:
|
default:
|
||||||
ttsService = tts.NewOpenAIService(cfg.AI.TTS.APIKey, cfg.AI.TTS.Model, cfg.AI.TTS.Voice, cfg.AI.TTS.Endpoint, cfg.AI.TTS.Speed, cfg.AI.TTS.Timeout, logger.Log)
|
ttsService = tts.NewOpenAIService(cfg.AI.TTS.APIKey, cfg.AI.TTS.Model, cfg.AI.TTS.Voice, cfg.AI.TTS.Endpoint, cfg.AI.TTS.Speed, cfg.AI.TTS.Timeout, cfg.AI.TTS.HTTPClientTimeout, logger.Log)
|
||||||
logger.Log.Infow("TTS service initialized", "provider", "openai", "model", cfg.AI.TTS.Model, "voice", cfg.AI.TTS.Voice, "speed", cfg.AI.TTS.Speed)
|
logger.Log.Infow("TTS service initialized", "provider", "openai", "model", cfg.AI.TTS.Model, "voice", cfg.AI.TTS.Voice, "speed", cfg.AI.TTS.Speed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化 Orchestrator
|
// 初始化 Orchestrator
|
||||||
orch := orchestrator.New(sttService, llmService, ttsService, sessionMgr, cfg.AI.LLM.Model, cfg.AI.TTS.Voice, cfg.AI.TTS.Speed)
|
orch := orchestrator.New(sttService, llmService, ttsService, sessionMgr, cfg)
|
||||||
|
|
||||||
// Gin 模式
|
// Gin 模式
|
||||||
if cfg.App.Env == "prod" {
|
if cfg.App.Env == "prod" {
|
||||||
@@ -93,7 +100,7 @@ func main() {
|
|||||||
// REST API
|
// REST API
|
||||||
apiGroup := r.Group("/api")
|
apiGroup := r.Group("/api")
|
||||||
{
|
{
|
||||||
apiGroup.GET("/health", healthHandler(sessionMgr))
|
apiGroup.GET("/health", healthHandler(sessionMgr, cfg))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Session REST 端点
|
// Session REST 端点
|
||||||
@@ -101,7 +108,7 @@ func main() {
|
|||||||
sessionHandler.RegisterRoutes(apiGroup)
|
sessionHandler.RegisterRoutes(apiGroup)
|
||||||
|
|
||||||
// WebSocket
|
// WebSocket
|
||||||
r.GET("/ws", ws.ServeWS(sessionMgr, orch))
|
r.GET("/ws", ws.ServeWS(sessionMgr, orch, cfg))
|
||||||
|
|
||||||
// HTTP Server
|
// HTTP Server
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
@@ -125,7 +132,7 @@ func main() {
|
|||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
logger.Log.Info("shutting down...")
|
logger.Log.Info("shutting down...")
|
||||||
|
|
||||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
shutdownCtx, cancel := context.WithTimeout(context.Background(), time.Duration(cfg.Server.ShutdownTimeout)*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
if err := srv.Shutdown(shutdownCtx); err != nil {
|
if err := srv.Shutdown(shutdownCtx); err != nil {
|
||||||
@@ -135,11 +142,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// healthHandler 健康检查。
|
// healthHandler 健康检查。
|
||||||
func healthHandler(sessionMgr session.Manager) gin.HandlerFunc {
|
func healthHandler(sessionMgr session.Manager, cfg *config.Config) gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
version := Version
|
||||||
|
if version == "" {
|
||||||
|
version = cfg.App.Version
|
||||||
|
}
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"version": "0.1.0",
|
"version": version,
|
||||||
"uptime_seconds": int(time.Since(startTime).Seconds()),
|
"uptime_seconds": int(time.Since(startTime).Seconds()),
|
||||||
"active_sessions": sessionMgr.ActiveCount(),
|
"active_sessions": sessionMgr.ActiveCount(),
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user