mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-04 00:03:59 +00:00
Phase 0.1/1/3/6: 核心生产问题修复
Healthcheck 隔离 (Phase 0.1): - 新增 internal/sdk/selftest.go: VirtualInstance 完全隔离自检空间 - PluginSDK.Selftest()/SelftestReset() 暴露隔离实例 (含 mutex) - LLM 自检只读白名单 isSafeReadonlyTool 防写类工具污染生产 - 单测验证: healthcheck 后生产实例内容不变 + 无残留 - 存量清理: 删除 gotest/luatest 残留目录 GraphDB 去重 (Phase 1): - migrateRelationUnique: 启动自动重建 relations 表加 UNIQUE 约束并去重 - Commit 改为存在性检查, 重复三元组仅刷新 confidence 不重复插入 - 3 个 dedup 单测全绿 配置时长解析 (Phase 3): - parseDurationExtended 支持 2d/1w/3h 等人类可读单位 - GetDuration 全局生效, 防 2d 静默回退 30m Agentcli 通知风暴治理 (Phase 6): - 语义通知: 累积 notify_bytes(2KB) 或间隔 notify_interval(2s) 触发 - 生命周期即时通知: 启动/进程退出/EOF 立即通知 - 可配置 settings, 保留通知机制保证 agent 感知终端存在 - 运维止血: 已杀掉幽灵 PID 3716282 (bash git sparse clone 运行 16h) Plan.md: 新增设计意图备忘(插件即App/分层记忆), 更新各 Phase 进度
This commit is contained in:
@ -7,6 +7,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -695,13 +696,44 @@ func (r *ConfigRegistry) GetDuration(key string, defaultVal time.Duration) time.
|
||||
if err != nil {
|
||||
return defaultVal
|
||||
}
|
||||
d, err := time.ParseDuration(v)
|
||||
d, err := parseDurationExtended(v)
|
||||
if err != nil {
|
||||
return defaultVal
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// durationUnitRe 匹配 `\d+[dhw]`(天/小时/周)这类 Go time.ParseDuration 不支持的天气单位。
|
||||
var durationUnitRe = regexp.MustCompile(`(\d+)\s*([dhw])`)
|
||||
|
||||
// parseDurationExtended 解析人类可读时长,支持 Go 原生单位(ns/us/ms/s/m/h,
|
||||
// 及复合如 "1h30m")加上 d(天)与 w(周)。返回实例化 duration,失败返回 error。
|
||||
func parseDurationExtended(s string) (time.Duration, error) {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return 0, fmt.Errorf("empty duration")
|
||||
}
|
||||
// 先展开 d/w,再交给 time.ParseDuration 处理剩余(含 m/h/s 组合)。
|
||||
expanded := durationUnitRe.ReplaceAllStringFunc(s, func(m string) string {
|
||||
parts := durationUnitRe.FindStringSubmatch(m)
|
||||
n, _ := strconv.Atoi(parts[1])
|
||||
switch parts[2] {
|
||||
case "d":
|
||||
return fmt.Sprintf("%dh", n*24)
|
||||
case "w":
|
||||
return fmt.Sprintf("%dh", n*24*7)
|
||||
case "h":
|
||||
return m
|
||||
}
|
||||
return m
|
||||
})
|
||||
d, err := time.ParseDuration(expanded)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
func (r *ConfigRegistry) GetBool(key string, defaultVal bool) bool {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
|
||||
Reference in New Issue
Block a user