add advanced session/subagent filters and trigger error summaries

This commit is contained in:
DBT
2026-02-23 14:26:13 +00:00
parent 6f26464766
commit 51172469f1
3 changed files with 77 additions and 36 deletions

View File

@@ -164,10 +164,18 @@ func (t *SessionsTool) Execute(ctx context.Context, args map[string]interface{})
if key == "" {
return "key is required for history", nil
}
h := t.historyFn(key, 0)
if len(h) == 0 {
raw := t.historyFn(key, 0)
if len(raw) == 0 {
return "No history.", nil
}
type indexedMsg struct {
idx int
msg providers.Message
}
window := make([]indexedMsg, 0, len(raw))
for i, m := range raw {
window = append(window, indexedMsg{idx: i + 1, msg: m})
}
// Window selectors are 1-indexed (human-friendly)
if around > 0 {
@@ -175,8 +183,8 @@ func (t *SessionsTool) Execute(ctx context.Context, args map[string]interface{})
if center < 0 {
center = 0
}
if center >= len(h) {
center = len(h) - 1
if center >= len(window) {
center = len(window) - 1
}
half := limit / 2
if half < 1 {
@@ -187,17 +195,17 @@ func (t *SessionsTool) Execute(ctx context.Context, args map[string]interface{})
start = 0
}
end := center + half + 1
if end > len(h) {
end = len(h)
if end > len(window) {
end = len(window)
}
h = h[start:end]
window = window[start:end]
} else {
start := 0
end := len(h)
end := len(window)
if after > 0 {
start = after
if start > len(h) {
start = len(h)
if start > len(window) {
start = len(window)
}
}
if before > 0 {
@@ -205,72 +213,72 @@ func (t *SessionsTool) Execute(ctx context.Context, args map[string]interface{})
if end < 0 {
end = 0
}
if end > len(h) {
end = len(h)
if end > len(window) {
end = len(window)
}
}
if start > end {
start = end
}
h = h[start:end]
window = window[start:end]
}
if !includeTools {
filtered := make([]providers.Message, 0, len(h))
for _, m := range h {
if strings.TrimSpace(strings.ToLower(m.Role)) == "tool" {
filtered := make([]indexedMsg, 0, len(window))
for _, m := range window {
if strings.TrimSpace(strings.ToLower(m.msg.Role)) == "tool" {
continue
}
filtered = append(filtered, m)
}
h = filtered
window = filtered
}
if roleFilter != "" {
filtered := make([]providers.Message, 0, len(h))
for _, m := range h {
if strings.ToLower(strings.TrimSpace(m.Role)) == roleFilter {
filtered := make([]indexedMsg, 0, len(window))
for _, m := range window {
if strings.ToLower(strings.TrimSpace(m.msg.Role)) == roleFilter {
filtered = append(filtered, m)
}
}
h = filtered
window = filtered
}
if fromMeSet {
targetRole := "user"
if fromMe {
targetRole = "assistant"
}
filtered := make([]providers.Message, 0, len(h))
for _, m := range h {
if strings.ToLower(strings.TrimSpace(m.Role)) == targetRole {
filtered := make([]indexedMsg, 0, len(window))
for _, m := range window {
if strings.ToLower(strings.TrimSpace(m.msg.Role)) == targetRole {
filtered = append(filtered, m)
}
}
h = filtered
window = filtered
}
if query != "" {
filtered := make([]providers.Message, 0, len(h))
for _, m := range h {
blob := strings.ToLower(strings.TrimSpace(m.Role + "\n" + m.Content))
filtered := make([]indexedMsg, 0, len(window))
for _, m := range window {
blob := strings.ToLower(strings.TrimSpace(m.msg.Role + "\n" + m.msg.Content))
if strings.Contains(blob, query) {
filtered = append(filtered, m)
}
}
h = filtered
window = filtered
}
if len(h) == 0 {
if len(window) == 0 {
return "No history (after filters).", nil
}
if len(h) > limit {
h = h[len(h)-limit:]
if len(window) > limit {
window = window[len(window)-limit:]
}
var sb strings.Builder
sb.WriteString(fmt.Sprintf("History for %s:\n", key))
for _, m := range h {
content := strings.TrimSpace(m.Content)
for _, item := range window {
content := strings.TrimSpace(item.msg.Content)
if len(content) > 180 {
content = content[:180] + "..."
}
sb.WriteString(fmt.Sprintf("- [%s] %s\n", m.Role, content))
sb.WriteString(fmt.Sprintf("- [#%d][%s] %s\n", item.idx, item.msg.Role, content))
}
return strings.TrimSpace(sb.String()), nil
default:

View File

@@ -253,6 +253,29 @@ func (sm *SubagentManager) SteerTask(taskID, message string) bool {
return true
}
func (sm *SubagentManager) ResumeTask(ctx context.Context, taskID string) (string, bool) {
sm.mu.RLock()
t, ok := sm.tasks[taskID]
sm.mu.RUnlock()
if !ok {
return "", false
}
if strings.TrimSpace(t.Task) == "" {
return "", false
}
label := strings.TrimSpace(t.Label)
if label == "" {
label = "resumed"
} else {
label = label + "-resumed"
}
_, err := sm.Spawn(ctx, t.Task, label, t.OriginChannel, t.OriginChatID, t.PipelineID, t.PipelineTask)
if err != nil {
return "", false
}
return label, true
}
func (sm *SubagentManager) pruneArchivedLocked() {
if sm.archiveAfterMinute <= 0 {
return

View File

@@ -27,7 +27,7 @@ func (t *SubagentsTool) Parameters() map[string]interface{} {
return map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"action": map[string]interface{}{"type": "string", "description": "list|info|kill|steer|send|log"},
"action": map[string]interface{}{"type": "string", "description": "list|info|kill|steer|send|log|resume"},
"id": map[string]interface{}{"type": "string", "description": "subagent id/#index/all for info/kill/steer/send/log"},
"message": map[string]interface{}{"type": "string", "description": "steering message for steer/send action"},
"recent_minutes": map[string]interface{}{"type": "integer", "description": "optional list/info all filter by recent updated minutes"},
@@ -148,6 +148,16 @@ func (t *SubagentsTool) Execute(ctx context.Context, args map[string]interface{}
sb.WriteString("Result Preview:\n" + result)
}
return strings.TrimSpace(sb.String()), nil
case "resume":
resolvedID, err := t.resolveTaskID(id)
if err != nil {
return err.Error(), nil
}
label, ok := t.manager.ResumeTask(ctx, resolvedID)
if !ok {
return "subagent resume failed", nil
}
return fmt.Sprintf("subagent resumed as %s", label), nil
default:
return "unsupported action", nil
}