fix: SuggestPaths 从镜像取路径 — 清库后路径补全不再为空
SuggestPaths 原来只查 mails.to_workspace(清库后为空)和 agents.workspaces(标准插件永远为空) → 清库后路径补全对所有 Agent 都空,界面提示「没有可用路径」。 加第三个来源:agent_platform_sessions.workspace(镜像,心跳上报)。 清库后镜像仍在(心跳重新上报),补全立即恢复。 按使用频率降序排列,常用路径(/root, /home/program/llmsproxy) 排在前,测试路径(/tmp/pi-bridge-e2e/ws)排在后。 顺带修了 SQL:SELECT DISTINCT + ORDER BY MAX() 不加 GROUP BY 在 SQLite 上语法错误(静默返回空集而非报错)。
This commit is contained in:
@ -985,16 +985,19 @@ func FindSessionByAddress(ctx context.Context, name, path, alias string) (uuid.U
|
|||||||
|
|
||||||
// SuggestPaths 给出某个收件方可用的工作目录候选(三段式补全的 path 位)。
|
// SuggestPaths 给出某个收件方可用的工作目录候选(三段式补全的 path 位)。
|
||||||
//
|
//
|
||||||
// 两个来源并集,**历史优先**:
|
// 三个来源并集,**历史优先**:
|
||||||
//
|
//
|
||||||
// 1. mails.to_workspace 里真实投递过的目录(按最近使用倒序)
|
// 1. mails.to_workspace 里真实投递过的目录(按最近使用倒序)
|
||||||
// 2. agents.workspaces 里注册时自报的目录
|
// 2. agent_platform_sessions.workspace 里心跳上报的目录(镜像)
|
||||||
|
// 3. agents.workspaces 里注册时自报的目录
|
||||||
//
|
//
|
||||||
// 早先只看第 2 项,而它对两个官方插件**永远是空的** —— 契约(W-2)
|
// 早先只看第 1、3 项,而第 1 项在清库后为空,第 3 项对两个官方插件
|
||||||
// 明确要求 `workspaces: []`,因为工作目录由每封邮件的 to_workspace 决定而不是
|
// **永远是空的** —— 契约(W-2)明确要求 `workspaces: []`,
|
||||||
// 注册时固定。于是补全的第二段对 dsh / opencode 一直给空列表,
|
// 因为工作目录由每封邮件的 to_workspace 决定而不是注册时固定。
|
||||||
// 人得手敲路径,Agent 更只能猜 —— 生产上 dsh 猜了 `opencode@/home`,
|
// 于是补全的第二段在清库后对所有 Agent 都给空列表。
|
||||||
// 解析通过、投递成功,但那不是 opencode 的工作目录。
|
//
|
||||||
|
// 加入第 2 项:镜像是心跳上报的平台会话快照,其中 workspace 字段
|
||||||
|
// 就是各平台的真实工作目录。它在清库后仍然存在(心跳重新上报)。
|
||||||
//
|
//
|
||||||
// 按最近使用倒序而非字典序:同一个 Agent 常在几个项目间切,刚用过的那个
|
// 按最近使用倒序而非字典序:同一个 Agent 常在几个项目间切,刚用过的那个
|
||||||
// 几乎总是下一封想用的那个。
|
// 几乎总是下一封想用的那个。
|
||||||
@ -1028,7 +1031,32 @@ func SuggestPaths(ctx context.Context, agentName string) ([]string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 来源 2:注册时自报。报了但还没收过信的目录靠这一步进入候选,
|
// 来源 2:平台会话镜像。心跳上报的平台会话快照,workspace 就是
|
||||||
|
// 各平台的真实工作目录。清库后仍然存在(心跳重新上报)。
|
||||||
|
// 没有这一步,清库后路径补全对所有 Agent 都空。
|
||||||
|
mrows, err := db.DB.QueryContext(ctx, `
|
||||||
|
SELECT workspace, COUNT(*) AS n
|
||||||
|
FROM agent_platform_sessions
|
||||||
|
WHERE agent_name = $1 AND COALESCE(workspace, '') <> ''
|
||||||
|
GROUP BY workspace
|
||||||
|
ORDER BY n DESC
|
||||||
|
`, agentName)
|
||||||
|
if err == nil {
|
||||||
|
defer mrows.Close()
|
||||||
|
for mrows.Next() {
|
||||||
|
var p string
|
||||||
|
var n int
|
||||||
|
if mrows.Scan(&p, &n) != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !seen[p] {
|
||||||
|
seen[p] = true
|
||||||
|
out = append(out, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 来源 3:注册时自报。报了但还没收过信的目录靠这一步进入候选,
|
||||||
// 否则新接入的 Agent 在第一封邮件之前仍然无路径可选。
|
// 否则新接入的 Agent 在第一封邮件之前仍然无路径可选。
|
||||||
var wsJSON []byte
|
var wsJSON []byte
|
||||||
if err := db.DB.QueryRowContext(ctx,
|
if err := db.DB.QueryRowContext(ctx,
|
||||||
|
|||||||
Reference in New Issue
Block a user