Merge pull request #1998 from abnerhexu/main

feat(config): allow placeholder text to be string or list
This commit is contained in:
Mauro 2026-03-25 22:47:39 +01:00 committed by GitHub
commit 5db1e94693
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 44 additions and 28 deletions

View file

@ -130,6 +130,10 @@
"encrypt_key": "", "encrypt_key": "",
"verification_token": "", "verification_token": "",
"allow_from": [], "allow_from": [],
"placeholder": {
"enabled": true,
"text": ["Thinking...", "Processing...", "Typing..."]
},
"reasoning_channel_id": "", "reasoning_channel_id": "",
"random_reaction_emoji": [], "random_reaction_emoji": [],
"is_lark": false "is_lark": false
@ -161,7 +165,7 @@
}, },
"placeholder": { "placeholder": {
"enabled": true, "enabled": true,
"text": "Thinking... 💭" "text": ["Thinking...", "Processing...", "Typing..."]
}, },
"reasoning_channel_id": "", "reasoning_channel_id": "",
"crypto_database_path": "", "crypto_database_path": "",

View file

@ -22,7 +22,7 @@ Add this to `config.json`:
}, },
"placeholder": { "placeholder": {
"enabled": true, "enabled": true,
"text": "Thinking..." "text": ["Thinking...", "Processing...", "Typing..."]
}, },
"reasoning_channel_id": "", "reasoning_channel_id": "",
"message_format": "richtext", "message_format": "richtext",
@ -45,12 +45,19 @@ Add this to `config.json`:
| join_on_invite | bool | No | Auto-join invited rooms | | join_on_invite | bool | No | Auto-join invited rooms |
| allow_from | []string | No | User whitelist (Matrix user IDs) | | allow_from | []string | No | User whitelist (Matrix user IDs) |
| group_trigger | object | No | Group trigger strategy (`mention_only` / `prefixes`) | | group_trigger | object | No | Group trigger strategy (`mention_only` / `prefixes`) |
| placeholder | object | No | Placeholder message config | | placeholder | object | No | Placeholder message config (see below) |
| reasoning_channel_id | string | No | Target channel for reasoning output | | reasoning_channel_id | string | No | Target channel for reasoning output |
| message_format | string | No | Output format: `"richtext"` (default) renders markdown as HTML; `"plain"` sends plain text only | | message_format | string | No | Output format: `"richtext"` (default) renders markdown as HTML; `"plain"` sends plain text only |
| crypto_database_path | string | No | Path to store the crypto database (uses workspace path `~/.picoclaw/workspace` if empty) | | crypto_database_path | string | No | Path to store the crypto database (uses workspace path `~/.picoclaw/workspace` if empty) |
| crypto_passphrase | string | No | Serialization key for encrypting session keys in the database; must remain unchanged once set | | crypto_passphrase | string | No | Serialization key for encrypting session keys in the database; must remain unchanged once set |
### Placeholder Config
| Field | Type | Required | Description |
|---------|----------------|----------|-------------|
| enabled | bool | No | Enable placeholder messages (default: false) |
| text | string/[]string | No | Placeholder text(s). Can be a single string or array of strings. If multiple texts are provided, one is randomly selected at runtime. Default: "Thinking..." |
## 3. Currently Supported ## 3. Currently Supported
- Text message send/receive with markdown rendering (bold, italic, headers, code blocks, etc.) - Text message send/receive with markdown rendering (bold, italic, headers, code blocks, etc.)

View file

@ -22,7 +22,7 @@
}, },
"placeholder": { "placeholder": {
"enabled": true, "enabled": true,
"text": "Thinking... 💭" "text": ["Thinking...", "Processing...", "Typing..."]
}, },
"reasoning_channel_id": "", "reasoning_channel_id": "",
"message_format": "richtext", "message_format": "richtext",
@ -51,6 +51,13 @@
| crypto_database_path | string | 否 | 加密数据库存储路径(为空时使用工作空间路径 `~/.picoclaw/workspace` | | crypto_database_path | string | 否 | 加密数据库存储路径(为空时使用工作空间路径 `~/.picoclaw/workspace` |
| crypto_passphrase | string | 否 | 加密数据库中 session key 的序列化密钥;设置后不能更改 | | crypto_passphrase | string | 否 | 加密数据库中 session key 的序列化密钥;设置后不能更改 |
### 占位消息配置 (Placeholder)
| 字段 | 类型 | 必填 | 说明 |
|---------|-----------------|------|------|
| enabled | bool | 否 | 是否启用占位消息默认false |
| text | string/[]string | 否 | 占位文本。可以是单个字符串或字符串数组。如果提供多个文本,运行时会随机选择一个。默认:"Thinking..." |
## 3. 当前支持 ## 3. 当前支持
- 文本消息收发 - 文本消息收发

View file

@ -254,10 +254,7 @@ func (c *DiscordChannel) SendPlaceholder(ctx context.Context, chatID string) (st
return "", nil return "", nil
} }
text := c.config.Placeholder.Text text := c.config.Placeholder.GetRandomText()
if text == "" {
text = "Thinking... 💭"
}
msg, err := c.session.ChannelMessageSend(chatID, text) msg, err := c.session.ChannelMessageSend(chatID, text)
if err != nil { if err != nil {

View file

@ -211,10 +211,7 @@ func (c *FeishuChannel) SendPlaceholder(ctx context.Context, chatID string) (str
return "", nil return "", nil
} }
text := c.config.Placeholder.Text text := c.config.Placeholder.GetRandomText()
if text == "" {
text = "Thinking..."
}
cardContent, err := buildMarkdownCard(text) cardContent, err := buildMarkdownCard(text)
if err != nil { if err != nil {

View file

@ -573,10 +573,7 @@ func (c *MatrixChannel) SendPlaceholder(ctx context.Context, chatID string) (str
return "", fmt.Errorf("matrix room ID is empty") return "", fmt.Errorf("matrix room ID is empty")
} }
text := strings.TrimSpace(c.config.Placeholder.Text) text := c.config.Placeholder.GetRandomText()
if text == "" {
text = "Thinking... 💭"
}
resp, err := c.client.SendMessageEvent(ctx, roomID, event.EventMessage, &event.MessageEventContent{ resp, err := c.client.SendMessageEvent(ctx, roomID, event.EventMessage, &event.MessageEventContent{
MsgType: event.MsgNotice, MsgType: event.MsgNotice,

View file

@ -275,10 +275,7 @@ func (c *PicoChannel) SendPlaceholder(ctx context.Context, chatID string) (strin
return "", nil return "", nil
} }
text := c.config.Placeholder.Text text := c.config.Placeholder.GetRandomText()
if text == "" {
text = "Thinking... 💭"
}
msgID := uuid.New().String() msgID := uuid.New().String()
outMsg := newMessage(TypeMessageCreate, map[string]any{ outMsg := newMessage(TypeMessageCreate, map[string]any{

View file

@ -402,10 +402,7 @@ func (c *TelegramChannel) SendPlaceholder(ctx context.Context, chatID string) (s
return "", nil return "", nil
} }
text := phCfg.Text text := phCfg.GetRandomText()
if text == "" {
text = "Thinking... 💭"
}
cid, threadID, err := parseTelegramChatID(chatID) cid, threadID, err := parseTelegramChatID(chatID)
if err != nil { if err != nil {

View file

@ -3,6 +3,7 @@ package config
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -383,7 +384,19 @@ type TypingConfig struct {
// PlaceholderConfig controls placeholder message behavior (Phase 10). // PlaceholderConfig controls placeholder message behavior (Phase 10).
type PlaceholderConfig struct { type PlaceholderConfig struct {
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
Text string `json:"text,omitempty"` Text FlexibleStringSlice `json:"text,omitempty"`
}
// GetRandomText returns a random placeholder text, or default if none set.
func (p *PlaceholderConfig) GetRandomText() string {
if len(p.Text) == 0 {
return "Thinking..."
}
if len(p.Text) == 1 {
return p.Text[0]
}
idx := rand.Intn(len(p.Text))
return p.Text[idx]
} }
type StreamingConfig struct { type StreamingConfig struct {

View file

@ -63,7 +63,7 @@ func DefaultConfig() *Config {
Typing: TypingConfig{Enabled: true}, Typing: TypingConfig{Enabled: true},
Placeholder: PlaceholderConfig{ Placeholder: PlaceholderConfig{
Enabled: true, Enabled: true,
Text: "Thinking... 💭", Text: FlexibleStringSlice{"Thinking... 💭"},
}, },
Streaming: StreamingConfig{Enabled: true, ThrottleSeconds: 3, MinGrowthChars: 200}, Streaming: StreamingConfig{Enabled: true, ThrottleSeconds: 3, MinGrowthChars: 200},
UseMarkdownV2: false, UseMarkdownV2: false,
@ -112,7 +112,7 @@ func DefaultConfig() *Config {
}, },
Placeholder: PlaceholderConfig{ Placeholder: PlaceholderConfig{
Enabled: true, Enabled: true,
Text: "Thinking... 💭", Text: FlexibleStringSlice{"Thinking... 💭"},
}, },
CryptoDatabasePath: "", CryptoDatabasePath: "",
CryptoPassphrase: "", CryptoPassphrase: "",