refactor(graph_overview): related_tasks 冷区统一走 coldDigestsRecent 并封顶

- coldDigestsRecent 改为接收 store 的自由函数,主概览与关联任务概览共用
- related_tasks 的 cold_digests 由无上限的 activeDigestBodies 换成
  coldDigestsRecent(ts, 6):按最新成员时间排序、每源截 6,溢出 digest id
  带 inherited/source_task_id 入 cold_digests_more,仍可 expand_digest 展开
- 删除随之无用的 activeDigestBodies
This commit is contained in:
Autumn-27 committed 2026-09-24 13:11:28 -04:00
1 parent 3aac6754a8
commit b5704eb361
2 files changed
+24 -38

No files matched your search

+16 -11
View File
@@ -501,7 +501,7 @@ func (t *ToolSet) graphOverviewData() map[string]any {
// cold-digest §6.1: 折叠冷区的 digest body,按最新成员时间降序取前 N;被截的更旧 digest
// 只给裸 id(仍可 expand_digest 展开),避免冷区唯一出口被无限拉长。
const coldDigestsCap = 15
if cds, more := t.coldDigestsRecent(coldDigestsCap); len(cds) > 0 {
if cds, more := coldDigestsRecent(t.ts, coldDigestsCap); len(cds) > 0 {
out["cold_digests"] = cds // [{id, body, member_count}] —— 直接读 body (§6.1)
if len(more) > 0 {
out["cold_digests_more"] = more // 被截断的更旧 digest 的 id;用 expand_digest(id) 展开
@@ -558,14 +558,15 @@ func inheritedMap(m map[string]any, sourceTaskID int64) map[string]any {
}
const (
relatedOverviewTotalTextRunes = 48_000
relatedOverviewMaxTextPerSource = 8_000
relatedOverviewMaxGoalsPerSource = 8
relatedOverviewMaxHintsPerSource = 6
relatedOverviewMaxFactsPerSource = 12
relatedOverviewMaxFindingsPerTask = 6
relatedOverviewMaxIntentsPerTask = 8
relatedOverviewMaxScopePerSource = 12
relatedOverviewTotalTextRunes = 48_000
relatedOverviewMaxTextPerSource = 8_000
relatedOverviewMaxGoalsPerSource = 8
relatedOverviewMaxHintsPerSource = 6
relatedOverviewMaxFactsPerSource = 12
relatedOverviewMaxFindingsPerTask = 6
relatedOverviewMaxIntentsPerTask = 8
relatedOverviewMaxScopePerSource = 12
relatedOverviewMaxDigestsPerSource = 6
)
// overviewTextBudget bounds inherited prompt text while preserving a fair slice
@@ -800,14 +801,18 @@ func (t *ToolSet) relatedTaskOverviews() []map[string]any {
}
}
item["recent_intent_results"] = intentResults
// §2 cross-task: the source task's folded cold region, read-only. Members are
// §2 cross-task: the source task's folded cold region, read-only, newest-member
// first & capped like the current task's. Members (and overflow digests) are
// resolvable via expand_digest(id)/node_detail(id), which search source tasks.
if cds := activeDigestBodies(ts); len(cds) > 0 {
if cds, more := coldDigestsRecent(ts, relatedOverviewMaxDigestsPerSource); len(cds) > 0 {
for _, cd := range cds {
cd["inherited"] = true
cd["source_task_id"] = source.Task.TaskID
}
item["cold_digests"] = cds
if len(more) > 0 {
item["cold_digests_more"] = more // 被截断的更旧 digest 的 id;expand_digest(id) 展开
}
}
if statsErr == nil {
item["node_stats"] = stats
+8 -27
View File
@@ -2,8 +2,8 @@ package agent
// cold-digest §6: graph_overview folding + the restore tools.
//
// activeDigestBodies — builds the folded cold region for graph_overview:
// cold_digests (flat {id, body, member_count}).
// coldDigestsRecent — builds the folded cold region for graph_overview:
// cold_digests (flat {id, body, member_count}), newest-member first, capped.
// expand_digest(id) — level-1 restore: a digest's member compact list.
import (
@@ -35,34 +35,15 @@ func (t *ToolSet) digestMemberEntry(store *db.ExplorationStore, id int64) map[st
return m
}
// activeDigestBodies returns [{id, body, member_count}] for a store's active
// digests — the folded cold region as flat bodies (§6.1). Shared by the current
// task overview and the read-only related-task overview (§2 cross-task reuse).
func activeDigestBodies(store *db.ExplorationStore) []map[string]any {
ads, err := store.ActiveDigests()
if err != nil || len(ads) == 0 {
return nil
}
out := make([]map[string]any, 0, len(ads))
for _, d := range ads {
var p struct {
Body string `json:"body"`
}
_ = json.Unmarshal(d.Payload, &p)
ms, _ := store.DigestMembers(d.ID)
out = append(out, map[string]any{"id": d.ID, "body": p.Body, "member_count": len(ms)})
}
return out
}
// coldDigestsRecent returns the current task's active digests as flat bodies for
// coldDigestsRecent returns a store's active digests as flat bodies for
// graph_overview, ordered by the recency of their freshest member (max member id ≈
// latest cooled node — a digest near the live frontier is likelier relevant), and
// capped at `cap`. Overflow digest ids are returned separately (moreIDs) so they
// stay reachable via expand_digest even when not shown inline — cold_digests is the
// only exit for folded cold nodes.
func (t *ToolSet) coldDigestsRecent(cap int) (shown []map[string]any, moreIDs []int64) {
ads, err := t.ts.ActiveDigests()
// only exit for folded cold nodes. Shared by the current task overview and the
// read-only related-task overview (§2 cross-task reuse).
func coldDigestsRecent(store *db.ExplorationStore, cap int) (shown []map[string]any, moreIDs []int64) {
ads, err := store.ActiveDigests()
if err != nil || len(ads) == 0 {
return nil, nil
}
@@ -77,7 +58,7 @@ func (t *ToolSet) coldDigestsRecent(cap int) (shown []map[string]any, moreIDs []
Body string `json:"body"`
}
_ = json.Unmarshal(d.Payload, &p)
ms, _ := t.ts.DigestMembers(d.ID) // sorted asc → last = freshest
ms, _ := store.DigestMembers(d.ID) // sorted asc → last = freshest
var fresh int64
if len(ms) > 0 {
fresh = ms[len(ms)-1]