fix: 恢复 markdown 渲染修复,应用配置系统重构
- 恢复e070461修复:wrap_width=-1 禁用换行,使用 lipgloss.Print - 应用dd3c8a0配置重构:字段名变更(theme/line_width/user_icon) - 添加用户配置文件支持(~/.config/hxclaw/config.yml) - 添加 TTS 配置到用户配置(enabled, auto)
This commit is contained in:
38
agents.md
38
agents.md
@@ -97,18 +97,19 @@ streaming:
|
|||||||
|
|
||||||
# Markdown 渲染配置
|
# Markdown 渲染配置
|
||||||
markdown:
|
markdown:
|
||||||
glamour_style: dark # 渲染主题:dark, light, dracula, tokyo-night 等
|
theme: dark # 渲染主题:dark, light, dracula, tokyo-night 等
|
||||||
|
line_width: -1 # 自动换行宽度(-1=禁用,0=自动,>0=固定宽度)
|
||||||
|
|
||||||
# UI 配置
|
# UI 配置
|
||||||
ui:
|
ui:
|
||||||
logo: "🦐"
|
logo: "🦐"
|
||||||
user_prefix: "👀 "
|
user_icon: "👀 "
|
||||||
|
|
||||||
# TTS 语音配置
|
# TTS 语音配置
|
||||||
tts:
|
tts:
|
||||||
enabled: false # 全局开关(默认关闭)
|
enabled: false # 全局开关(默认关闭)
|
||||||
port: 9876 # mimo-tts daemon 端口
|
port: 9876 # mimo-tts daemon 端口
|
||||||
auto: true # AI 回复后自动朗读
|
auto: true # AI 回复后自动朗读
|
||||||
```
|
```
|
||||||
|
|
||||||
配置加载优先级:
|
配置加载优先级:
|
||||||
@@ -117,6 +118,33 @@ tts:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 用户配置
|
||||||
|
|
||||||
|
用户配置文件位于 `~/.config/hxclaw/config.yml`,启动时自动创建。
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# hxclaw 用户配置文件
|
||||||
|
# 此文件位于 ~/.config/hxclaw/config.yml
|
||||||
|
# 用户配置优先于项目配置
|
||||||
|
|
||||||
|
# Markdown 渲染配置
|
||||||
|
markdown:
|
||||||
|
theme: dark # 渲染主题
|
||||||
|
line_width: 0 # 换行宽度
|
||||||
|
|
||||||
|
# UI 配置
|
||||||
|
ui:
|
||||||
|
logo: "🦐"
|
||||||
|
user_icon: "👀 "
|
||||||
|
|
||||||
|
# TTS 语音配置
|
||||||
|
tts:
|
||||||
|
enabled: false # 全局开关
|
||||||
|
auto: true # AI 回复后自动朗读
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## TTS 使用指南
|
## TTS 使用指南
|
||||||
|
|
||||||
### 命令
|
### 命令
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// Package internal 包含 hxclaw 的内部工具模块
|
||||||
|
// 提供配置管理、Markdown 渲染、输入读取等功能
|
||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -8,47 +10,66 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProjectConfig struct {
|
// Config 是项目配置结构体,包含流式输出、Markdown 渲染和 UI 相关配置
|
||||||
|
type Config struct {
|
||||||
|
// Streaming 流式输出配置
|
||||||
Streaming StreamingConfig `yaml:"streaming"`
|
Streaming StreamingConfig `yaml:"streaming"`
|
||||||
Markdown MarkdownConfig `yaml:"markdown"`
|
// Markdown Markdown 渲染配置
|
||||||
UI UIConfig `yaml:"ui"`
|
Markdown MarkdownConfig `yaml:"markdown"`
|
||||||
TTS TTSConfig `yaml:"tts"`
|
// UI UI 显示配置
|
||||||
|
UI UIConfig `yaml:"ui"`
|
||||||
|
// TTS TTS 语音配置
|
||||||
|
TTS TTSConfig `yaml:"tts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StreamingConfig 流式输出配置,控制模拟打字效果的延迟时间
|
||||||
type StreamingConfig struct {
|
type StreamingConfig struct {
|
||||||
LineDelayMs int `yaml:"line_delay_ms"`
|
// LineDelayMs 每行输出延迟(毫秒)
|
||||||
|
LineDelayMs int `yaml:"line_delay_ms"`
|
||||||
|
// LastLineDelayMs 最后一行输出延迟(毫秒)
|
||||||
LastLineDelayMs int `yaml:"last_line_delay_ms"`
|
LastLineDelayMs int `yaml:"last_line_delay_ms"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarkdownConfig Markdown 渲染配置,控制渲染主题和换行行为
|
||||||
type MarkdownConfig struct {
|
type MarkdownConfig struct {
|
||||||
GlamourStyle string `yaml:"glamour_style"`
|
// Theme 渲染主题,支持 dark、light、dracula、tokyo-night 等
|
||||||
WrapWidth int `yaml:"wrap_width"`
|
Theme string `yaml:"theme"`
|
||||||
|
// LineWidth 自动换行宽度(0=自动,>0=固定宽度,-1=禁用)
|
||||||
|
LineWidth int `yaml:"line_width"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UIConfig UI 显示配置,控制 Logo 和用户提示符
|
||||||
type UIConfig struct {
|
type UIConfig struct {
|
||||||
Logo string `yaml:"logo"`
|
// Logo 应用 Logo 字符
|
||||||
UserPrefix string `yaml:"user_prefix"`
|
Logo string `yaml:"logo"`
|
||||||
|
// UserIcon 用户输入提示符
|
||||||
|
UserIcon string `yaml:"user_icon"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TTSConfig TTS 语音配置
|
||||||
type TTSConfig struct {
|
type TTSConfig struct {
|
||||||
|
// Enabled 全局开关
|
||||||
Enabled bool `yaml:"enabled"`
|
Enabled bool `yaml:"enabled"`
|
||||||
Port int `yaml:"port"`
|
// Port 端口
|
||||||
Auto bool `yaml:"auto"`
|
Port int `yaml:"port"`
|
||||||
|
// Auto AI 回复后自动朗读
|
||||||
|
Auto bool `yaml:"auto"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
defaultCfg = ProjectConfig{
|
// defaultCfg 默认配置值,当配置文件不存在或字段为空时使用
|
||||||
|
defaultCfg = Config{
|
||||||
Streaming: StreamingConfig{
|
Streaming: StreamingConfig{
|
||||||
LineDelayMs: 1000,
|
LineDelayMs: 1000,
|
||||||
LastLineDelayMs: 600,
|
LastLineDelayMs: 600,
|
||||||
},
|
},
|
||||||
Markdown: MarkdownConfig{
|
Markdown: MarkdownConfig{
|
||||||
GlamourStyle: "dark",
|
Theme: "dark",
|
||||||
WrapWidth: 0,
|
LineWidth: -1,
|
||||||
},
|
},
|
||||||
UI: UIConfig{
|
UI: UIConfig{
|
||||||
Logo: "🦐",
|
Logo: "🦐",
|
||||||
UserPrefix: "👀 ",
|
UserIcon: "👀 ",
|
||||||
},
|
},
|
||||||
TTS: TTSConfig{
|
TTS: TTSConfig{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
@@ -56,72 +77,202 @@ var (
|
|||||||
Auto: true,
|
Auto: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
projCfg *ProjectConfig
|
cfg *Config // 已合并的配置(用户配置 + 项目配置)
|
||||||
projCfgLock sync.RWMutex
|
cfgLock sync.RWMutex // 配置读写锁
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadProjectConfig() error {
|
// 用户配置文件路径常量
|
||||||
projCfgLock.Lock()
|
const (
|
||||||
defer projCfgLock.Unlock()
|
userConfigDir = ".config/hxclaw" // 用户配置目录(相对于用户家目录)
|
||||||
|
userConfigFile = "config.yml" // 用户配置文件名
|
||||||
|
)
|
||||||
|
|
||||||
cfgPath := getConfigPath()
|
// LoadProjectConfig 加载并合并项目配置
|
||||||
if cfgPath == "" {
|
// 加载顺序:用户配置(~/.config/hxclaw/config.yml) > 项目配置(project.config.yml)
|
||||||
projCfg = &defaultCfg
|
// 最终配置由两者合并得出,用户配置优先于项目配置
|
||||||
|
func LoadProjectConfig() error {
|
||||||
|
cfgLock.Lock()
|
||||||
|
defer cfgLock.Unlock()
|
||||||
|
|
||||||
|
userCfg := loadUserConfig()
|
||||||
|
projCfg := loadProjectConfig()
|
||||||
|
|
||||||
|
merged := mergeConfig(userCfg, projCfg)
|
||||||
|
cfg = merged
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadUserConfig 加载用户配置文件
|
||||||
|
// 路径:~/.config/hxclaw/config.yml
|
||||||
|
// 如果文件不存在,则自动创建默认配置文件
|
||||||
|
func loadUserConfig() *Config {
|
||||||
|
userPath := getUserConfigPath()
|
||||||
|
if userPath == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(userPath)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
createUserConfig(userPath)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var userCfg Config
|
||||||
|
if err := yaml.Unmarshal(data, &userCfg); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &userCfg
|
||||||
|
}
|
||||||
|
|
||||||
|
// createUserConfig 创建默认的用户配置文件
|
||||||
|
func createUserConfig(userPath string) error {
|
||||||
|
dir := filepath.Dir(userPath)
|
||||||
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultContent := `# hxclaw 用户配置文件
|
||||||
|
# 此文件位于 ~/.config/hxclaw/config.yml
|
||||||
|
# 用户配置优先于项目配置
|
||||||
|
|
||||||
|
# Markdown 渲染配置
|
||||||
|
markdown:
|
||||||
|
theme: dark # 渲染主题:dark, light, dracula, tokyo-night 等
|
||||||
|
line_width: 0 # 自动换行宽度(-1=禁用,0=自动,>0=固定宽度)
|
||||||
|
|
||||||
|
# UI 配置
|
||||||
|
ui:
|
||||||
|
logo: "🦐"
|
||||||
|
user_icon: "👀 "
|
||||||
|
|
||||||
|
# TTS 语音配置
|
||||||
|
tts:
|
||||||
|
enabled: false # 全局开关(默认关闭)
|
||||||
|
auto: true # AI 回复后自动朗读
|
||||||
|
`
|
||||||
|
return os.WriteFile(userPath, []byte(defaultContent), 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadProjectConfig 加载项目级配置文件
|
||||||
|
// 路径优先级:环境变量 HXCLAW_CONFIG 指定路径 > ./project.config.yml
|
||||||
|
func loadProjectConfig() *Config {
|
||||||
|
cfgPath := getProjectConfigPath()
|
||||||
|
if cfgPath == "" {
|
||||||
|
return &defaultCfg
|
||||||
|
}
|
||||||
|
|
||||||
data, err := os.ReadFile(cfgPath)
|
data, err := os.ReadFile(cfgPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
projCfg = &defaultCfg
|
return &defaultCfg
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var cfg ProjectConfig
|
|
||||||
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.Streaming.LineDelayMs <= 0 {
|
|
||||||
cfg.Streaming.LineDelayMs = defaultCfg.Streaming.LineDelayMs
|
|
||||||
}
|
|
||||||
if cfg.Streaming.LastLineDelayMs <= 0 {
|
|
||||||
cfg.Streaming.LastLineDelayMs = defaultCfg.Streaming.LastLineDelayMs
|
|
||||||
}
|
|
||||||
if cfg.Markdown.GlamourStyle == "" {
|
|
||||||
cfg.Markdown.GlamourStyle = defaultCfg.Markdown.GlamourStyle
|
|
||||||
}
|
|
||||||
if cfg.Markdown.WrapWidth < 0 {
|
|
||||||
cfg.Markdown.WrapWidth = 0
|
|
||||||
}
|
|
||||||
if cfg.UI.Logo == "" {
|
|
||||||
cfg.UI.Logo = defaultCfg.UI.Logo
|
|
||||||
}
|
|
||||||
if cfg.UI.UserPrefix == "" {
|
|
||||||
cfg.UI.UserPrefix = defaultCfg.UI.UserPrefix
|
|
||||||
}
|
|
||||||
if cfg.TTS.Port <= 0 {
|
|
||||||
cfg.TTS.Port = defaultCfg.TTS.Port
|
|
||||||
}
|
|
||||||
|
|
||||||
projCfg = &cfg
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetProjectConfig() *ProjectConfig {
|
|
||||||
projCfgLock.RLock()
|
|
||||||
defer projCfgLock.RUnlock()
|
|
||||||
if projCfg == nil {
|
|
||||||
return &defaultCfg
|
return &defaultCfg
|
||||||
}
|
}
|
||||||
return projCfg
|
|
||||||
|
var projCfg Config
|
||||||
|
if err := yaml.Unmarshal(data, &projCfg); err != nil {
|
||||||
|
return &defaultCfg
|
||||||
|
}
|
||||||
|
|
||||||
|
return &projCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConfigPath() string {
|
// mergeConfig 合并用户配置和项目配置
|
||||||
|
// 合并规则:用户配置优先于项目配置,项目配置优先于默认配置
|
||||||
|
func mergeConfig(userCfg, projCfg *Config) *Config {
|
||||||
|
result := defaultCfg
|
||||||
|
|
||||||
|
// 先应用项目配置
|
||||||
|
if projCfg != nil {
|
||||||
|
if projCfg.Streaming.LineDelayMs > 0 {
|
||||||
|
result.Streaming.LineDelayMs = projCfg.Streaming.LineDelayMs
|
||||||
|
}
|
||||||
|
if projCfg.Streaming.LastLineDelayMs > 0 {
|
||||||
|
result.Streaming.LastLineDelayMs = projCfg.Streaming.LastLineDelayMs
|
||||||
|
}
|
||||||
|
if projCfg.Markdown.Theme != "" {
|
||||||
|
result.Markdown.Theme = projCfg.Markdown.Theme
|
||||||
|
}
|
||||||
|
if projCfg.Markdown.LineWidth != 0 {
|
||||||
|
result.Markdown.LineWidth = projCfg.Markdown.LineWidth
|
||||||
|
}
|
||||||
|
if projCfg.UI.Logo != "" {
|
||||||
|
result.UI.Logo = projCfg.UI.Logo
|
||||||
|
}
|
||||||
|
if projCfg.UI.UserIcon != "" {
|
||||||
|
result.UI.UserIcon = projCfg.UI.UserIcon
|
||||||
|
}
|
||||||
|
if projCfg.TTS.Port > 0 {
|
||||||
|
result.TTS.Port = projCfg.TTS.Port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 再应用用户配置(覆盖项目配置)
|
||||||
|
if userCfg != nil {
|
||||||
|
// Markdown
|
||||||
|
if userCfg.Markdown.Theme != "" {
|
||||||
|
result.Markdown.Theme = userCfg.Markdown.Theme
|
||||||
|
}
|
||||||
|
if userCfg.Markdown.LineWidth != 0 {
|
||||||
|
result.Markdown.LineWidth = userCfg.Markdown.LineWidth
|
||||||
|
}
|
||||||
|
// UI
|
||||||
|
if userCfg.UI.Logo != "" {
|
||||||
|
result.UI.Logo = userCfg.UI.Logo
|
||||||
|
}
|
||||||
|
if userCfg.UI.UserIcon != "" {
|
||||||
|
result.UI.UserIcon = userCfg.UI.UserIcon
|
||||||
|
}
|
||||||
|
// TTS(用户配置可以覆盖 enabled 和 auto)
|
||||||
|
if userCfg.TTS.Enabled {
|
||||||
|
result.TTS.Enabled = userCfg.TTS.Enabled
|
||||||
|
}
|
||||||
|
if userCfg.TTS.Port > 0 {
|
||||||
|
result.TTS.Port = userCfg.TTS.Port
|
||||||
|
}
|
||||||
|
if userCfg.TTS.Auto {
|
||||||
|
result.TTS.Auto = userCfg.TTS.Auto
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &result
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProjectConfig 获取当前生效的配置(线程安全)
|
||||||
|
// 如果配置未加载,返回默认配置
|
||||||
|
func GetProjectConfig() *Config {
|
||||||
|
cfgLock.RLock()
|
||||||
|
defer cfgLock.RUnlock()
|
||||||
|
if cfg == nil {
|
||||||
|
return &defaultCfg
|
||||||
|
}
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
// getUserConfigPath 获取用户配置文件路径
|
||||||
|
// 路径格式:~/.config/hxclaw/config.yml
|
||||||
|
// 支持 Windows (USERPROFILE) 和 Unix (HOME) 环境变量
|
||||||
|
func getUserConfigPath() string {
|
||||||
|
homeDir := os.Getenv("USERPROFILE")
|
||||||
|
if homeDir == "" {
|
||||||
|
homeDir = os.Getenv("HOME")
|
||||||
|
}
|
||||||
|
if homeDir == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return filepath.Join(homeDir, userConfigDir, userConfigFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getProjectConfigPath 获取项目配置文件路径
|
||||||
|
// 优先使用环境变量 HXCLAW_CONFIG 指定的路径,否则使用当前目录的 project.config.yml
|
||||||
|
func getProjectConfigPath() string {
|
||||||
if path := os.Getenv("HXCLAW_CONFIG"); path != "" {
|
if path := os.Getenv("HXCLAW_CONFIG"); path != "" {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
return filepath.Join(".", "project.config.yml")
|
return filepath.Join(".", "project.config.yml")
|
||||||
}
|
}
|
||||||
@@ -67,8 +67,8 @@ func RenderParagraph(text string) string {
|
|||||||
|
|
||||||
func getStyle() string {
|
func getStyle() string {
|
||||||
if cfg := GetProjectConfig(); cfg != nil {
|
if cfg := GetProjectConfig(); cfg != nil {
|
||||||
if cfg.Markdown.GlamourStyle != "" {
|
if cfg.Markdown.Theme != "" {
|
||||||
return cfg.Markdown.GlamourStyle
|
return cfg.Markdown.Theme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s := os.Getenv("GLAMOUR_STYLE"); s != "" {
|
if s := os.Getenv("GLAMOUR_STYLE"); s != "" {
|
||||||
@@ -79,8 +79,11 @@ func getStyle() string {
|
|||||||
|
|
||||||
func getWrapWidth() int {
|
func getWrapWidth() int {
|
||||||
if cfg := GetProjectConfig(); cfg != nil {
|
if cfg := GetProjectConfig(); cfg != nil {
|
||||||
if cfg.Markdown.WrapWidth > 0 {
|
if cfg.Markdown.LineWidth > 0 {
|
||||||
return cfg.Markdown.WrapWidth
|
return cfg.Markdown.LineWidth
|
||||||
|
}
|
||||||
|
if cfg.Markdown.LineWidth < 0 {
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,9 +93,15 @@ func getWrapWidth() int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cols := os.Getenv("LINES"); cols != "" {
|
||||||
|
if w, err := strconv.Atoi(cols); err == nil && w > 0 {
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
width, _, err := term.GetSize(0)
|
width, _, err := term.GetSize(0)
|
||||||
if err != nil || width <= 0 {
|
if err != nil || width <= 0 {
|
||||||
return 80
|
return 0
|
||||||
}
|
}
|
||||||
return width
|
return width
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func interactiveMode(agentLoop *agent.AgentLoop, sessionKey string) {
|
func interactiveMode(agentLoop *agent.AgentLoop, sessionKey string) {
|
||||||
basePrompt := internal.GetProjectConfig().UI.UserPrefix
|
basePrompt := internal.GetProjectConfig().UI.UserIcon
|
||||||
prompt := internal.GetTTSPrompt(basePrompt)
|
prompt := internal.GetTTSPrompt(basePrompt)
|
||||||
|
|
||||||
rl, err := internal.NewReadline(prompt)
|
rl, err := internal.NewReadline(prompt)
|
||||||
@@ -134,7 +134,7 @@ func simpleInteractiveMode(agentLoop *agent.AgentLoop, sessionKey string) {
|
|||||||
internal.SetTTSEnabled(true)
|
internal.SetTTSEnabled(true)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
fmt.Print(internal.GetTTSPrompt(internal.GetProjectConfig().UI.UserPrefix))
|
fmt.Print(internal.GetTTSPrompt(internal.GetProjectConfig().UI.UserIcon))
|
||||||
line, err := reader.ReadString()
|
line, err := reader.ReadString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == internal.ErrEOF {
|
if err == internal.ErrEOF {
|
||||||
@@ -225,11 +225,11 @@ func outputLineByLine(text string) {
|
|||||||
|
|
||||||
for i, line := range lines {
|
for i, line := range lines {
|
||||||
if line == "" {
|
if line == "" {
|
||||||
fmt.Println()
|
lipgloss.Print("\n")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(line)
|
lipgloss.Print(line + "\n")
|
||||||
|
|
||||||
if i < totalLines-1 {
|
if i < totalLines-1 {
|
||||||
time.Sleep(lineDelay)
|
time.Sleep(lineDelay)
|
||||||
@@ -238,7 +238,7 @@ func outputLineByLine(text string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
lipgloss.Print("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -2,21 +2,21 @@
|
|||||||
|
|
||||||
# 模拟流式输出配置
|
# 模拟流式输出配置
|
||||||
streaming:
|
streaming:
|
||||||
line_delay_ms: 1000 # 每行输出后的延迟(毫秒)
|
line_delay_ms: 1000 # 每行输出后的延迟(毫秒)
|
||||||
last_line_delay_ms: 600 # 最后一行延迟(毫秒)
|
last_line_delay_ms: 600 # 最后一行延迟(毫秒)
|
||||||
|
|
||||||
# Markdown 渲染配置
|
# Markdown 渲染配置
|
||||||
markdown:
|
markdown:
|
||||||
glamour_style: dark # 渲染主题:dark, light, dracula, tokyo-night 等
|
theme: dark # 渲染主题:dark, light, dracula, tokyo-night 等
|
||||||
wrap_width: 0 # 自动换行宽度(0=自动获取终端宽度)
|
line_width: -1 # 自动换行宽度(-1=禁用,0=自动,>0=固定宽度)
|
||||||
|
|
||||||
# UI 配置
|
# UI 配置
|
||||||
ui:
|
ui:
|
||||||
logo: "🦐"
|
logo: "🦐"
|
||||||
user_prefix: "👀 "
|
user_icon: "👀 "
|
||||||
|
|
||||||
# TTS 语音配置
|
# TTS 语音配置
|
||||||
tts:
|
tts:
|
||||||
enabled: false # 全局开关(默认关闭)
|
enabled: false # 全局开关(默认关闭)
|
||||||
port: 9876 # mimo-tts daemon 端口
|
port: 9876 # mimo-tts daemon 端口
|
||||||
auto: true # AI 回复后自动朗读
|
auto: true # AI 回复后自动朗读
|
||||||
Reference in New Issue
Block a user