Files
agent-chain/internal/tui/model.go
T
2026-03-20 14:26:24 +08:00

149 lines
2.9 KiB
Go

package tui
import (
"learning-assistant/internal/ai"
"learning-assistant/internal/ai/generators"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
// State TUI状态
type State string
const (
StateInput State = "input"
StateLoading State = "loading"
StateResult State = "result"
StateError State = "error"
)
// TabType Tab类型
type TabType string
const (
TabGuodegang TabType = "guodegang"
TabQuiz TabType = "quiz"
TabCard TabType = "card"
TabScenario TabType = "scenario"
)
// TabItem Tab项
type TabItem struct {
Type TabType
Label string
Icon string
}
// Model TUI模型
type Model struct {
state State
// AI组件
client *ai.SiliconFlowClient
promptManager *ai.PromptManager
generator *generators.BaseGenerator
// 用户输入
inputText string
// 生成结果
results map[TabType]string
// 加载状态
loadingStatus map[generators.GeneratorType]bool
// Tab管理
tabs []TabItem
activeTab int
// 错误信息
errorMsg string
}
// NewModel 创建模型
func NewModel(client *ai.SiliconFlowClient, promptManager *ai.PromptManager) Model {
return Model{
state: StateResult,
client: client,
promptManager: promptManager,
generator: generators.NewBaseGenerator(client, promptManager),
inputText: "",
results: make(map[TabType]string),
loadingStatus: make(map[generators.GeneratorType]bool),
tabs: []TabItem{
{Type: TabGuodegang, Label: "讲解", Icon: "🎭"},
{Type: TabQuiz, Label: "考核", Icon: "✍️"},
{Type: TabCard, Label: "卡片", Icon: "📝"},
{Type: TabScenario, Label: "场景", Icon: "🏗️"},
},
activeTab: 0,
}
}
// SetInput 设置输入
func (m *Model) SetInput(input string) {
m.inputText = input
m.state = StateLoading
}
// Init 初始化
func (m Model) Init() tea.Cmd {
return nil
}
// Update 更新
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
return m.handleKeyPress(msg)
case contentMsg:
return m.handleContentResult(msg)
case errorMessage:
return m.handleError(msg)
}
return m, nil
}
// View 视图
func (m Model) View() string {
switch m.state {
case StateInput:
return m.inputView()
case StateLoading:
return m.loadingView()
case StateResult:
return m.resultView()
case StateError:
return m.errorView()
default:
return "Unknown state"
}
}
// contentMsg 内容生成完成消息
type contentMsg struct {
Type generators.GeneratorType
Content string
}
// errorMessage 错误消息
type errorMessage struct {
Type generators.GeneratorType
Error error
}
// 样式定义
var (
baseStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#FAFAFA"))
headerStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#7D56F4")).
Bold(true)
errorStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#FF5555"))
)