mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 18:07:36 +08:00
fix
This commit is contained in:
@@ -29,8 +29,8 @@ func getGlobalConfigDir() string {
|
||||
}
|
||||
|
||||
func NewContextBuilder(workspace string, toolsSummaryFunc func() []string) *ContextBuilder {
|
||||
// builtin skills: 当前项目的 skills 目录
|
||||
// 使用当前工作目录下的 skills/ 目录
|
||||
// Built-in skills: use the current project's skills directory.
|
||||
// Resolve from current working directory: skills/
|
||||
wd, _ := os.Getwd()
|
||||
builtinSkillsDir := filepath.Join(wd, "skills")
|
||||
globalSkillsDir := filepath.Join(getGlobalConfigDir(), "skills")
|
||||
|
||||
@@ -79,9 +79,9 @@ func ExtractLanguagePreference(text string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
enHints := []string{"speak english", "reply in english", "use english", "以后用英文", "请用英文", "用英文"}
|
||||
zhHints := []string{"说中文", "用中文", "请用中文", "reply in chinese", "speak chinese"}
|
||||
jaHints := []string{"日本語", "reply in japanese", "speak japanese"}
|
||||
enHints := []string{"speak english", "reply in english", "use english"}
|
||||
zhHints := []string{"reply in chinese", "speak chinese", "use chinese"}
|
||||
jaHints := []string{"reply in japanese", "speak japanese", "use japanese"}
|
||||
koHints := []string{"한국어", "reply in korean", "speak korean"}
|
||||
|
||||
for _, h := range enHints {
|
||||
|
||||
@@ -235,9 +235,9 @@ func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, provider providers
|
||||
sessionRunLocks: map[string]*sync.Mutex{},
|
||||
}
|
||||
|
||||
// 注入递归运行逻辑,使 subagent 具备 full tool-calling 能力
|
||||
// Inject recursive run logic so subagents can use full tool-calling flows.
|
||||
subagentManager.SetRunFunc(func(ctx context.Context, task, channel, chatID string) (string, error) {
|
||||
sessionKey := fmt.Sprintf("subagent:%d", os.Getpid()) // 改用 PID 或随机数,避免 sessionKey 冲突
|
||||
sessionKey := fmt.Sprintf("subagent:%d", os.Getpid()) // Use PID/randomized key to reduce session key collisions.
|
||||
return loop.ProcessDirect(ctx, task, sessionKey)
|
||||
})
|
||||
|
||||
@@ -629,7 +629,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
||||
})
|
||||
}
|
||||
messages = append(messages, assistantMsg)
|
||||
// 持久化包含 ToolCalls 的助手消息
|
||||
// Persist assistant message with tool calls.
|
||||
al.sessions.AddMessageFull(msg.SessionKey, assistantMsg)
|
||||
|
||||
for _, tc := range response.ToolCalls {
|
||||
@@ -652,7 +652,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
||||
ToolCallID: tc.ID,
|
||||
}
|
||||
messages = append(messages, toolResultMsg)
|
||||
// 持久化工具返回结果
|
||||
// Persist tool result message.
|
||||
al.sessions.AddMessageFull(msg.SessionKey, toolResultMsg)
|
||||
}
|
||||
}
|
||||
@@ -673,7 +673,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
||||
if iteration == 1 {
|
||||
fallback := strings.TrimSpace(al.thinkOnlyFallback)
|
||||
if fallback == "" {
|
||||
fallback = "已完成思考流程。"
|
||||
fallback = "Thinking process completed."
|
||||
}
|
||||
userContent = fallback
|
||||
}
|
||||
@@ -686,7 +686,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
||||
}
|
||||
al.sessions.AddMessage(msg.SessionKey, "user", msg.Content)
|
||||
|
||||
// 使用 AddMessageFull 存储包含思考过程或工具调用的完整助手消息
|
||||
// Persist full assistant response (including reasoning/tool flow outcomes when present).
|
||||
al.sessions.AddMessageFull(msg.SessionKey, providers.Message{
|
||||
Role: "assistant",
|
||||
Content: userContent,
|
||||
@@ -716,15 +716,15 @@ func (al *AgentLoop) updateIntentHint(sessionKey, content string) {
|
||||
lower := strings.ToLower(content)
|
||||
|
||||
// Cron natural-language intent: avoid searching project files for user timer ops.
|
||||
if strings.Contains(lower, "定时") || strings.Contains(lower, "定时任务") || strings.Contains(lower, "cron") || strings.Contains(lower, "schedule") {
|
||||
hint := "优先使用 cron 工具处理定时任务:查看=action=list;删除=action=delete(id);启停=action=enable/disable。不要改为在项目目录中搜索 cron 文本。"
|
||||
if strings.Contains(lower, "cron") || strings.Contains(lower, "schedule") || strings.Contains(lower, "timer") || strings.Contains(lower, "reminder") {
|
||||
hint := "Prioritize the cron tool for timer operations: list=action=list; delete=action=delete(id); enable/disable=action=enable/disable. Do not switch to grepping project files for cron text."
|
||||
al.intentMu.Lock()
|
||||
al.intentHints[sessionKey] = hint + " 用户补充=" + content
|
||||
al.intentHints[sessionKey] = hint + " User details=" + content
|
||||
al.intentMu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.Contains(lower, "提交") && !strings.Contains(lower, "推送") && !strings.Contains(lower, "commit") && !strings.Contains(lower, "push") {
|
||||
if !strings.Contains(lower, "commit") && !strings.Contains(lower, "push") {
|
||||
if strings.HasPrefix(content, "1.") || strings.HasPrefix(content, "2.") {
|
||||
al.intentMu.Lock()
|
||||
if prev := strings.TrimSpace(al.intentHints[sessionKey]); prev != "" {
|
||||
@@ -734,12 +734,12 @@ func (al *AgentLoop) updateIntentHint(sessionKey, content string) {
|
||||
}
|
||||
return
|
||||
}
|
||||
hint := "执行事务: commit+push 一次闭环,包含分支/范围确认。"
|
||||
if strings.Contains(lower, "所有分支") || strings.Contains(lower, "all branches") {
|
||||
hint += " 范围=所有分支。"
|
||||
hint := "Execute as one transaction: complete commit+push in one pass with branch/scope confirmation."
|
||||
if strings.Contains(lower, "all branches") {
|
||||
hint += " Scope=all branches."
|
||||
}
|
||||
al.intentMu.Lock()
|
||||
al.intentHints[sessionKey] = hint + " 用户补充=" + content
|
||||
al.intentHints[sessionKey] = hint + " User details=" + content
|
||||
al.intentMu.Unlock()
|
||||
}
|
||||
|
||||
@@ -751,7 +751,7 @@ func (al *AgentLoop) applyIntentHint(sessionKey, content string) string {
|
||||
return content
|
||||
}
|
||||
lower := strings.ToLower(strings.TrimSpace(content))
|
||||
if strings.Contains(lower, "提交") || strings.Contains(lower, "推送") || strings.HasPrefix(content, "1.") || strings.HasPrefix(content, "2.") || strings.Contains(lower, "定时") || strings.Contains(lower, "cron") || strings.Contains(lower, "schedule") {
|
||||
if strings.Contains(lower, "commit") || strings.Contains(lower, "push") || strings.HasPrefix(content, "1.") || strings.HasPrefix(content, "2.") || strings.Contains(lower, "cron") || strings.Contains(lower, "schedule") || strings.Contains(lower, "timer") || strings.Contains(lower, "reminder") {
|
||||
return "[Intent Slot]\n" + hint + "\n\n[User Message]\n" + content
|
||||
}
|
||||
return content
|
||||
@@ -887,7 +887,7 @@ func (al *AgentLoop) processSystemMessage(ctx context.Context, msg bus.InboundMe
|
||||
})
|
||||
}
|
||||
messages = append(messages, assistantMsg)
|
||||
// 持久化包含 ToolCalls 的助手消息
|
||||
// Persist assistant message with tool calls.
|
||||
al.sessions.AddMessageFull(sessionKey, assistantMsg)
|
||||
|
||||
for _, tc := range response.ToolCalls {
|
||||
@@ -902,7 +902,7 @@ func (al *AgentLoop) processSystemMessage(ctx context.Context, msg bus.InboundMe
|
||||
ToolCallID: tc.ID,
|
||||
}
|
||||
messages = append(messages, toolResultMsg)
|
||||
// 持久化工具返回结果
|
||||
// Persist tool result message.
|
||||
al.sessions.AddMessageFull(sessionKey, toolResultMsg)
|
||||
}
|
||||
}
|
||||
@@ -914,9 +914,8 @@ func (al *AgentLoop) processSystemMessage(ctx context.Context, msg bus.InboundMe
|
||||
// Save to session with system message marker
|
||||
al.sessions.AddMessage(sessionKey, "user", fmt.Sprintf("[System: %s] %s", msg.SenderID, msg.Content))
|
||||
|
||||
// 如果 finalContent 中没有包含 tool calls (即最后一次 LLM 返回的结果)
|
||||
// 我们已经通过循环内部的 AddMessageFull 存储了前面的步骤
|
||||
// 这里的 AddMessageFull 会存储最终回复
|
||||
// If finalContent has no tool calls (last LLM turn is direct text),
|
||||
// earlier steps were already persisted in-loop; this stores the final reply.
|
||||
al.sessions.AddMessageFull(sessionKey, providers.Message{
|
||||
Role: "assistant",
|
||||
Content: finalContent,
|
||||
@@ -1110,7 +1109,7 @@ func shouldRecallMemory(text string, keywords []string) bool {
|
||||
return false
|
||||
}
|
||||
if len(keywords) == 0 {
|
||||
keywords = []string{"remember", "记得", "上次", "之前", "偏好", "preference", "todo", "待办", "决定", "decision", "日期", "when did", "what did we"}
|
||||
keywords = []string{"remember", "preference", "todo", "decision", "date", "when did", "what did we"}
|
||||
}
|
||||
for _, k := range keywords {
|
||||
kk := strings.ToLower(strings.TrimSpace(k))
|
||||
|
||||
@@ -20,23 +20,23 @@ import (
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
Enabled bool
|
||||
TickIntervalSec int
|
||||
MinRunIntervalSec int
|
||||
MaxPendingDurationSec int
|
||||
MaxConsecutiveStalls int
|
||||
MaxDispatchPerTick int
|
||||
Workspace string
|
||||
DefaultNotifyChannel string
|
||||
DefaultNotifyChatID string
|
||||
NotifyCooldownSec int
|
||||
Enabled bool
|
||||
TickIntervalSec int
|
||||
MinRunIntervalSec int
|
||||
MaxPendingDurationSec int
|
||||
MaxConsecutiveStalls int
|
||||
MaxDispatchPerTick int
|
||||
Workspace string
|
||||
DefaultNotifyChannel string
|
||||
DefaultNotifyChatID string
|
||||
NotifyCooldownSec int
|
||||
NotifySameReasonCooldownSec int
|
||||
QuietHours string
|
||||
UserIdleResumeSec int
|
||||
WaitingResumeDebounceSec int
|
||||
ImportantKeywords []string
|
||||
CompletionTemplate string
|
||||
BlockedTemplate string
|
||||
QuietHours string
|
||||
UserIdleResumeSec int
|
||||
WaitingResumeDebounceSec int
|
||||
ImportantKeywords []string
|
||||
CompletionTemplate string
|
||||
BlockedTemplate string
|
||||
}
|
||||
|
||||
type taskState struct {
|
||||
@@ -436,10 +436,10 @@ func normalizeResourceKeys(keys []string) []string {
|
||||
}
|
||||
|
||||
type todoItem struct {
|
||||
ID string
|
||||
Content string
|
||||
Priority string
|
||||
DueAt string
|
||||
ID string
|
||||
Content string
|
||||
Priority string
|
||||
DueAt string
|
||||
DedupeHits int
|
||||
}
|
||||
|
||||
@@ -549,7 +549,7 @@ func (e *Engine) sendCompletionNotification(st *taskState) {
|
||||
}
|
||||
tpl := strings.TrimSpace(e.opts.CompletionTemplate)
|
||||
if tpl == "" {
|
||||
tpl = "✅ 已完成:%s\n下一步:如需我继续处理后续,直接回复“继续 %s”"
|
||||
tpl = "✅ Completed: %s\nNext step: reply \"continue %s\" if you want me to proceed."
|
||||
}
|
||||
e.bus.PublishOutbound(bus.OutboundMessage{
|
||||
Channel: e.opts.DefaultNotifyChannel,
|
||||
@@ -566,7 +566,7 @@ func (e *Engine) sendFailureNotification(st *taskState, reason string) {
|
||||
}
|
||||
tpl := strings.TrimSpace(e.opts.BlockedTemplate)
|
||||
if tpl == "" {
|
||||
tpl = "⚠️ 任务受阻:%s\n原因:%s\n建议:回复“继续 %s”我会按当前状态重试。"
|
||||
tpl = "⚠️ Task blocked: %s\nReason: %s\nSuggestion: reply \"continue %s\" and I will retry from current state."
|
||||
}
|
||||
e.bus.PublishOutbound(bus.OutboundMessage{
|
||||
Channel: e.opts.DefaultNotifyChannel,
|
||||
@@ -942,7 +942,7 @@ func (e *Engine) isHighValueCompletion(st *taskState) bool {
|
||||
s := strings.ToLower(strings.TrimSpace(st.Content))
|
||||
keywords := e.opts.ImportantKeywords
|
||||
if len(keywords) == 0 {
|
||||
keywords = []string{"urgent", "重要", "付款", "payment", "上线", "release", "deadline", "截止"}
|
||||
keywords = []string{"urgent", "payment", "release", "deadline", "p0", "asap"}
|
||||
}
|
||||
for _, k := range keywords {
|
||||
kk := strings.ToLower(strings.TrimSpace(k))
|
||||
|
||||
@@ -45,19 +45,19 @@ type AgentDefaults struct {
|
||||
}
|
||||
|
||||
type AutonomyConfig struct {
|
||||
Enabled bool `json:"enabled" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_ENABLED"`
|
||||
TickIntervalSec int `json:"tick_interval_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_TICK_INTERVAL_SEC"`
|
||||
MinRunIntervalSec int `json:"min_run_interval_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MIN_RUN_INTERVAL_SEC"`
|
||||
MaxPendingDurationSec int `json:"max_pending_duration_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_PENDING_DURATION_SEC"`
|
||||
MaxConsecutiveStalls int `json:"max_consecutive_stalls" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_CONSECUTIVE_STALLS"`
|
||||
MaxDispatchPerTick int `json:"max_dispatch_per_tick" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_DISPATCH_PER_TICK"`
|
||||
NotifyCooldownSec int `json:"notify_cooldown_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_COOLDOWN_SEC"`
|
||||
NotifySameReasonCooldownSec int `json:"notify_same_reason_cooldown_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_SAME_REASON_COOLDOWN_SEC"`
|
||||
QuietHours string `json:"quiet_hours" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_QUIET_HOURS"`
|
||||
UserIdleResumeSec int `json:"user_idle_resume_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_USER_IDLE_RESUME_SEC"`
|
||||
WaitingResumeDebounceSec int `json:"waiting_resume_debounce_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_WAITING_RESUME_DEBOUNCE_SEC"`
|
||||
NotifyChannel string `json:"notify_channel" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_CHANNEL"`
|
||||
NotifyChatID string `json:"notify_chat_id" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_CHAT_ID"`
|
||||
Enabled bool `json:"enabled" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_ENABLED"`
|
||||
TickIntervalSec int `json:"tick_interval_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_TICK_INTERVAL_SEC"`
|
||||
MinRunIntervalSec int `json:"min_run_interval_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MIN_RUN_INTERVAL_SEC"`
|
||||
MaxPendingDurationSec int `json:"max_pending_duration_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_PENDING_DURATION_SEC"`
|
||||
MaxConsecutiveStalls int `json:"max_consecutive_stalls" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_CONSECUTIVE_STALLS"`
|
||||
MaxDispatchPerTick int `json:"max_dispatch_per_tick" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_MAX_DISPATCH_PER_TICK"`
|
||||
NotifyCooldownSec int `json:"notify_cooldown_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_COOLDOWN_SEC"`
|
||||
NotifySameReasonCooldownSec int `json:"notify_same_reason_cooldown_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_SAME_REASON_COOLDOWN_SEC"`
|
||||
QuietHours string `json:"quiet_hours" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_QUIET_HOURS"`
|
||||
UserIdleResumeSec int `json:"user_idle_resume_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_USER_IDLE_RESUME_SEC"`
|
||||
WaitingResumeDebounceSec int `json:"waiting_resume_debounce_sec" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_WAITING_RESUME_DEBOUNCE_SEC"`
|
||||
NotifyChannel string `json:"notify_channel" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_CHANNEL"`
|
||||
NotifyChatID string `json:"notify_chat_id" env:"CLAWGO_AGENTS_DEFAULTS_AUTONOMY_NOTIFY_CHAT_ID"`
|
||||
}
|
||||
|
||||
type AgentTextConfig struct {
|
||||
@@ -304,42 +304,42 @@ func DefaultConfig() *Config {
|
||||
Temperature: 0.7,
|
||||
MaxToolIterations: 20,
|
||||
Heartbeat: HeartbeatConfig{
|
||||
Enabled: true,
|
||||
EverySec: 30 * 60,
|
||||
AckMaxChars: 64,
|
||||
Enabled: true,
|
||||
EverySec: 30 * 60,
|
||||
AckMaxChars: 64,
|
||||
PromptTemplate: "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.",
|
||||
},
|
||||
Autonomy: AutonomyConfig{
|
||||
Enabled: false,
|
||||
TickIntervalSec: 30,
|
||||
MinRunIntervalSec: 20,
|
||||
MaxPendingDurationSec: 180,
|
||||
MaxConsecutiveStalls: 3,
|
||||
MaxDispatchPerTick: 2,
|
||||
NotifyCooldownSec: 300,
|
||||
Enabled: false,
|
||||
TickIntervalSec: 30,
|
||||
MinRunIntervalSec: 20,
|
||||
MaxPendingDurationSec: 180,
|
||||
MaxConsecutiveStalls: 3,
|
||||
MaxDispatchPerTick: 2,
|
||||
NotifyCooldownSec: 300,
|
||||
NotifySameReasonCooldownSec: 900,
|
||||
QuietHours: "23:00-08:00",
|
||||
UserIdleResumeSec: 20,
|
||||
WaitingResumeDebounceSec: 5,
|
||||
NotifyChannel: "",
|
||||
NotifyChatID: "",
|
||||
QuietHours: "23:00-08:00",
|
||||
UserIdleResumeSec: 20,
|
||||
WaitingResumeDebounceSec: 5,
|
||||
NotifyChannel: "",
|
||||
NotifyChatID: "",
|
||||
},
|
||||
Texts: AgentTextConfig{
|
||||
NoResponseFallback: "I've completed processing but have no response to give.",
|
||||
ThinkOnlyFallback: "Thinking process completed.",
|
||||
MemoryRecallKeywords: []string{"remember", "记得", "上次", "之前", "偏好", "preference", "todo", "待办", "决定", "decision", "日期", "when did", "what did we"},
|
||||
LangUsage: "Usage: /lang <code>",
|
||||
LangInvalid: "Invalid language code.",
|
||||
LangUpdatedTemplate: "Language preference updated to %s",
|
||||
SubagentsNone: "No subagents.",
|
||||
SessionsNone: "No sessions.",
|
||||
UnsupportedAction: "unsupported action",
|
||||
NoResponseFallback: "I've completed processing but have no response to give.",
|
||||
ThinkOnlyFallback: "Thinking process completed.",
|
||||
MemoryRecallKeywords: []string{"remember", "previous", "preference", "todo", "decision", "date", "when did", "what did we"},
|
||||
LangUsage: "Usage: /lang <code>",
|
||||
LangInvalid: "Invalid language code.",
|
||||
LangUpdatedTemplate: "Language preference updated to %s",
|
||||
SubagentsNone: "No subagents.",
|
||||
SessionsNone: "No sessions.",
|
||||
UnsupportedAction: "unsupported action",
|
||||
SystemRewriteTemplate: "Rewrite the following internal system update in concise user-facing language:\n\n%s",
|
||||
RuntimeCompactionNote: "[runtime-compaction] removed %d old messages, kept %d recent messages",
|
||||
StartupCompactionNote: "[startup-compaction] removed %d old messages, kept %d recent messages",
|
||||
AutonomyImportantKeywords: []string{"urgent", "重要", "付款", "payment", "上线", "release", "deadline", "截止"},
|
||||
AutonomyCompletionTemplate: "✅ 已完成:%s\n回复“继续 %s”可继续下一步。",
|
||||
AutonomyBlockedTemplate: "⚠️ 任务受阻:%s(%s)\n回复“继续 %s”我会重试。",
|
||||
AutonomyImportantKeywords: []string{"urgent", "payment", "release", "deadline", "p0", "asap"},
|
||||
AutonomyCompletionTemplate: "✅ Completed: %s\nReply \"continue %s\" to proceed to the next step.",
|
||||
AutonomyBlockedTemplate: "⚠️ Task blocked: %s (%s)\nReply \"continue %s\" and I will retry.",
|
||||
},
|
||||
ContextCompaction: ContextCompactionConfig{
|
||||
Enabled: true,
|
||||
|
||||
@@ -1418,16 +1418,16 @@ func (s *RegistryServer) checkAuth(r *http.Request) bool {
|
||||
|
||||
func hotReloadFieldInfo() []map[string]interface{} {
|
||||
return []map[string]interface{}{
|
||||
{"path": "logging.*", "name": "日志配置", "description": "日志等级、落盘等"},
|
||||
{"path": "sentinel.*", "name": "哨兵配置", "description": "健康检查与自动修复"},
|
||||
{"path": "agents.*", "name": "Agent 配置", "description": "模型、策略、默认行为"},
|
||||
{"path": "providers.*", "name": "Provider 配置", "description": "LLM 提供商与代理"},
|
||||
{"path": "tools.*", "name": "工具配置", "description": "工具开关、执行参数"},
|
||||
{"path": "channels.*", "name": "渠道配置", "description": "Telegram/其它渠道参数"},
|
||||
{"path": "cron.*", "name": "定时任务配置", "description": "cron 全局运行参数"},
|
||||
{"path": "agents.defaults.heartbeat.*", "name": "心跳策略", "description": "心跳频率、提示词"},
|
||||
{"path": "agents.defaults.autonomy.*", "name": "自治策略", "description": "自治任务开关与限流"},
|
||||
{"path": "gateway.*", "name": "网关配置", "description": "多数可热更,监听地址/端口可能需重启"},
|
||||
{"path": "logging.*", "name": "Logging", "description": "Log level, persistence, and related settings"},
|
||||
{"path": "sentinel.*", "name": "Sentinel", "description": "Health checks and auto-heal behavior"},
|
||||
{"path": "agents.*", "name": "Agent", "description": "Models, policies, and default behavior"},
|
||||
{"path": "providers.*", "name": "Providers", "description": "LLM providers and proxy settings"},
|
||||
{"path": "tools.*", "name": "Tools", "description": "Tool toggles and runtime options"},
|
||||
{"path": "channels.*", "name": "Channels", "description": "Telegram and other channel settings"},
|
||||
{"path": "cron.*", "name": "Cron", "description": "Global cron runtime settings"},
|
||||
{"path": "agents.defaults.heartbeat.*", "name": "Heartbeat", "description": "Heartbeat interval and prompt template"},
|
||||
{"path": "agents.defaults.autonomy.*", "name": "Autonomy", "description": "Autonomy toggles and throttling"},
|
||||
{"path": "gateway.*", "name": "Gateway", "description": "Mostly hot-reloadable; host/port may require restart"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ func (sm *SessionManager) AddMessageFull(sessionKey string, msg providers.Messag
|
||||
session.Updated = time.Now()
|
||||
session.mu.Unlock()
|
||||
|
||||
// 立即持久化 (Append-only)
|
||||
// Persist immediately (append-only).
|
||||
sm.appendMessage(sessionKey, msg)
|
||||
}
|
||||
|
||||
@@ -323,8 +323,8 @@ func toOpenClawMessageEvent(msg providers.Message) openClawEvent {
|
||||
Type: "message",
|
||||
Timestamp: time.Now().UTC().Format(time.RFC3339Nano),
|
||||
Message: &struct {
|
||||
Role string `json:"role"`
|
||||
Content []struct {
|
||||
Role string `json:"role"`
|
||||
Content []struct {
|
||||
Type string `json:"type"`
|
||||
Text string `json:"text,omitempty"`
|
||||
} `json:"content,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user