重构:把剩余 12 个顶层包全部迁到 internal/

继续之前的重构:把根目录残留的非数据/资源类子目录(agents、agenttool、ai、
autoreply、completion、conversation、llm、message、mqtpp、stream、
toolmanager、toolrouter)一并搬到 internal/ 下,并把全工程引用它们的
import 路径从 "meshtastic_mqtt_server/<x>" 重写为
"meshtastic_mqtt_server/internal/<x>"。

变更
- git mv 12 个顶层目录进 internal/,无函数体改动。
- 全工程 sed 把 import path 加上 internal/ 前缀,包括 main.go、
  internal/bot/bot_service.go、internal/store/bot_store.go 中对 mqtpp
  的引用,以及 ai 子系统内部 agents/agenttool/autoreply/conversation/
  llm/toolmanager/toolrouter 之间的相互引用。

验证
- go build ./... 通过;go test ./... 全部包通过。
- AI 自动回复链路(main → ai.NewService → autoreply.Service → botSender)
  保持不变,仅 import 路径调整。
- 根目录最终只剩 main.go / main_test.go / internal/ 加 go.mod / go.sum
  与数据资源目录(dist、doc、firmware、py、win、meshmap_frontend)。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-06-18 18:43:42 +08:00
co-authored by Claude
parent 02b445884d
commit d57dff58f3
25 changed files with 36 additions and 36 deletions
+135
View File
@@ -0,0 +1,135 @@
package ai
import (
"context"
"fmt"
"os"
"path/filepath"
"meshtastic_mqtt_server/internal/agenttool"
_ "meshtastic_mqtt_server/internal/agents/calculator"
_ "meshtastic_mqtt_server/internal/agents/time"
"meshtastic_mqtt_server/internal/autoreply"
"meshtastic_mqtt_server/internal/conversation"
"meshtastic_mqtt_server/internal/llm"
"meshtastic_mqtt_server/internal/toolmanager"
"meshtastic_mqtt_server/internal/toolrouter"
"gorm.io/gorm"
)
// ToolConfigStore is the interface for getting tool configuration
type ToolConfigStore interface {
GetLLMPrimaryConfigSystemPrompt() (string, error)
GetLLMPrimaryConfigEnableTool() (bool, error)
}
// Config holds the AI service configuration
type Config struct {
LLMProviders []llm.ProviderConfig
DataDir string
Enabled bool
ToolConfigStore ToolConfigStore
}
// Service manages all AI-related components
type Service struct {
LLMState *llm.State
ToolRouter *toolrouter.State
ToolMgr *toolmanager.Manager
ConvStore *conversation.Store
AutoReply *autoreply.Service
MsgQueue *autoreply.DBMessageQueue
enabled bool
}
// NewService creates a new AI service
func NewService(cfg Config, db *gorm.DB, botSender autoreply.BotSender) (*Service, error) {
if !cfg.Enabled {
return &Service{enabled: false}, nil
}
// Create data directories
agentsDir := filepath.Join(cfg.DataDir, "agents")
convDir := filepath.Join(cfg.DataDir, "conversations")
if err := os.MkdirAll(agentsDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create agents directory: %w", err)
}
if err := os.MkdirAll(convDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create conversations directory: %w", err)
}
// Initialize LLM state
llmState, err := llm.NewState(cfg.LLMProviders)
if err != nil {
return nil, fmt.Errorf("failed to initialize LLM state: %w", err)
}
// Initialize tool router
toolRouterCfg := &toolrouter.Config{
Enabled: true,
Timeout: 30,
MaxTokens: 512,
SystemPrompt: "你是一个智能助手,可以调用工具来回答用户问题。\n用户正在通过 Mesh 网络与你对话,请保持回答简洁明了。\n工具结果优先于模型内置知识。",
}
toolRouter, err := toolrouter.NewState(toolRouterCfg, llmState)
if err != nil {
return nil, fmt.Errorf("failed to initialize tool router: %w", err)
}
// Load tools
toolMgr, err := toolmanager.Load(agentsDir, agenttool.LoadOptions{})
if err != nil {
return nil, fmt.Errorf("failed to load tools: %w", err)
}
// Initialize conversation store
convStore := conversation.NewStore(convDir)
// Initialize message queue
msgQueue := autoreply.NewDBMessageQueue(db)
// Initialize auto-reply service
autoReply := autoreply.NewService(
llmState,
toolRouter,
toolMgr,
convStore,
msgQueue,
botSender,
cfg.ToolConfigStore,
)
return &Service{
LLMState: llmState,
ToolRouter: toolRouter,
ToolMgr: toolMgr,
ConvStore: convStore,
AutoReply: autoReply,
MsgQueue: msgQueue,
enabled: true,
}, nil
}
// Start starts the AI service
func (s *Service) Start(ctx context.Context) error {
if !s.enabled {
return nil
}
return s.AutoReply.Start(ctx)
}
// Stop stops the AI service
func (s *Service) Stop() {
if !s.enabled {
return
}
s.AutoReply.Stop()
s.ToolMgr.Close()
}
// Enabled returns whether the AI service is enabled
func (s *Service) Enabled() bool {
return s.enabled
}