Skip to content

Commit 82c799a

Browse files
committed
build: update mermaid frontend assets and dependencies
- 更新前端静态资源文件,替换旧版chunk和diagram资源 - 更新go.mod依赖:github.com/DotNetAge/gorag/v2 到v2.0.8 - 新增知识库区域健康检查和修复的RPC接口 - 新增区域节点修复相关的后端处理逻辑 - 重构图节点匹配逻辑,支持Region节点前缀匹配
1 parent 7a88862 commit 82c799a

81 files changed

Lines changed: 448 additions & 157 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ require (
2626
github.com/DotNetAge/gochat v0.2.7
2727
github.com/DotNetAge/gograph v0.2.6
2828
github.com/DotNetAge/goharness v0.2.13
29-
github.com/DotNetAge/gorag/v2 v2.0.7
29+
github.com/DotNetAge/gorag/v2 v2.0.8
3030
github.com/creack/pty v1.1.24
3131
go.etcd.io/bbolt v1.4.3
3232
golang.org/x/text v0.37.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ github.com/DotNetAge/gograph v0.2.6 h1:LhYERtYTPaWXvbBy9bO/6XGmYTW/OZGXQ+zyfycse
1717
github.com/DotNetAge/gograph v0.2.6/go.mod h1:Ia2wvbkpdJvFJEZ1vw+IklbhNbWjPli2dnU21jbmy7I=
1818
github.com/DotNetAge/goharness v0.2.13 h1:MkGvj7+3UadfSpb3kz3F0Gb1NhI8L0e5CKhw3dOAgaQ=
1919
github.com/DotNetAge/goharness v0.2.13/go.mod h1:2+Ze4Att5hP3oRR9/5Rqv506hr38G5qwaWQz6ChOu8c=
20-
github.com/DotNetAge/gorag/v2 v2.0.7 h1:HXHAPUUDV+U8B4pflTGEmAokSCzipwlgLW1tzo5AiZc=
21-
github.com/DotNetAge/gorag/v2 v2.0.7/go.mod h1:K8YAydeJR41JMY59xrzgMNDKRHVg3cwB2pYwJSwVjbE=
20+
github.com/DotNetAge/gorag/v2 v2.0.8 h1:TmPnZvkirhAm1GLzw42hTIA1xUtIMa4TpydpeaDGNt8=
21+
github.com/DotNetAge/gorag/v2 v2.0.8/go.mod h1:K8YAydeJR41JMY59xrzgMNDKRHVg3cwB2pYwJSwVjbE=
2222
github.com/DotNetAge/gort v0.1.4 h1:nUZdy3cN3Kif21GWIYkxlIS/iFr62eN5boBmCzmI3xw=
2323
github.com/DotNetAge/gort v0.1.4/go.mod h1:m6mjzyaP/Ufx+Uv7uh51BSK7N4LVR/viWEHV9ZQ3OM8=
2424
github.com/DotNetAge/govector v0.1.8 h1:LwNJecCbLgj0ISXBRUCQziPYBbYxtr+3jVEKvXzK7wo=

internal/svc/daemon.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ func (d *Daemon) getIndexer(projectDir string) (*indexing.Indexer, error) {
654654
}
655655
if d.modelName != "" {
656656
if mc, ok := d.app.ModelCost(d.modelName); ok && (mc.CostPer1MIn > 0 || mc.CostPer1MOut > 0) {
657-
opts = append(opts, indexing.WithCostRates(mc.CostPer1MIn, mc.CostPer1MOut))
657+
opts = append(opts, indexing.WithCostRates(mc.CostPer1MIn, mc.CostPer1MOut, mc.CostPer1MInCached))
658658
}
659659
}
660660

internal/svc/handler_graph.go

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"os"
99
"path/filepath"
10+
"strings"
1011

1112
graphapi "github.com/DotNetAge/gograph/pkg/api"
1213
"github.com/DotNetAge/gograph/pkg/graph"
@@ -368,23 +369,35 @@ func (d *Daemon) handleGraphListNodesByProject(_ context.Context, params json.Ra
368369
}
369370

370371
// Helper: check if a node's source_chunk_ids overlaps with chunkIDSet
372+
// Region 节点没有 source_chunk_ids,通过 dir 属性前缀匹配
371373
nodeInRegion := func(n *graph.Node) bool {
372374
v, ok := n.GetProperty("source_chunk_ids")
373-
if !ok {
374-
return false
375-
}
376-
raw := v.InterfaceValue()
377-
switch ids := raw.(type) {
378-
case []string:
379-
for _, id := range ids {
380-
if chunkIDSet[id] {
381-
return true
375+
if ok {
376+
raw := v.InterfaceValue()
377+
switch ids := raw.(type) {
378+
case []string:
379+
for _, id := range ids {
380+
if chunkIDSet[id] {
381+
return true
382+
}
383+
}
384+
case []interface{}:
385+
for _, id := range ids {
386+
if s, ok := id.(string); ok && chunkIDSet[s] {
387+
return true
388+
}
382389
}
383390
}
384-
case []interface{}:
385-
for _, id := range ids {
386-
if s, ok := id.(string); ok && chunkIDSet[s] {
387-
return true
391+
}
392+
// Region 节点:通过 dir 属性前缀匹配
393+
for _, label := range n.Labels {
394+
if label == "Region" {
395+
if dirV, dirOK := n.GetProperty("dir"); dirOK {
396+
if dirStr, ok := dirV.InterfaceValue().(string); ok {
397+
if strings.HasPrefix(dirStr, absDir) {
398+
return true
399+
}
400+
}
388401
}
389402
}
390403
}

internal/svc/handler_kb_region.go

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package svc
2+
3+
import (
4+
"context"
5+
"crypto/sha256"
6+
"encoding/json"
7+
"fmt"
8+
"path/filepath"
9+
"time"
10+
11+
goragcore "github.com/DotNetAge/gorag/v2/core"
12+
goragindexer "github.com/DotNetAge/gorag/v2/indexer"
13+
"github.com/DotNetAge/mindx/pkg/rpc"
14+
)
15+
16+
// handleKBCheckRegionHealth checks whether the Region graph for projectDir is
17+
// complete. Returns one of:
18+
//
19+
// { "health": "no_data" } — zero chunks found, nothing to repair
20+
// { "health": "healthy" } — Region node exists with proper structure
21+
// { "health": "needs_repair" } — chunks exist but Region node is missing
22+
func (d *Daemon) handleKBCheckRegionHealth(_ context.Context, params json.RawMessage) (any, error) {
23+
var p rpc.KBCheckRegionHealthParams
24+
if err := unmarshalParams(params, &p); err != nil {
25+
return nil, err
26+
}
27+
if p.ProjectDir == "" {
28+
return nil, fmt.Errorf("project_dir is required")
29+
}
30+
31+
if d.graphIndexer == nil {
32+
return nil, fmt.Errorf("knowledge base not available")
33+
}
34+
35+
absDir, err := filepath.Abs(p.ProjectDir)
36+
if err != nil {
37+
return nil, fmt.Errorf("resolve project dir: %w", err)
38+
}
39+
absDir = filepath.Clean(absDir)
40+
regionID := fmt.Sprintf("%x", sha256.Sum256([]byte(absDir)))
41+
42+
// 1. Query vectorDB for chunks with this region_id
43+
vectors, _, err := d.graphIndexer.VectorDB().ListFiltered(context.Background(), 0, 1, []goragcore.FilterCondition{
44+
{Key: "region_id", Type: "exact", Value: regionID},
45+
})
46+
if err != nil {
47+
d.logger.Warn("kb.check_region_health: vectorDB query failed", "error", err)
48+
return nil, fmt.Errorf("query vectorDB: %w", err)
49+
}
50+
51+
// No chunks at all → no data to repair
52+
if len(vectors) == 0 {
53+
return map[string]any{"health": "no_data"}, nil
54+
}
55+
56+
// 2. Check if the project-level Region node exists in graphDB
57+
if d.graphStore == nil {
58+
return map[string]any{"health": "needs_repair"}, nil
59+
}
60+
61+
allNodes, err := d.graphStore.ListNodes()
62+
if err != nil {
63+
d.logger.Warn("kb.check_region_health: listNodes failed", "error", err)
64+
return map[string]any{"health": "needs_repair"}, nil
65+
}
66+
67+
projectDirPrefix := absDir
68+
hasProjectRegion := false
69+
for _, n := range allNodes {
70+
isRegion := false
71+
for _, l := range n.Labels {
72+
if l == "Region" {
73+
isRegion = true
74+
break
75+
}
76+
}
77+
if !isRegion {
78+
continue
79+
}
80+
dirV, ok := n.GetProperty("dir")
81+
if !ok {
82+
continue
83+
}
84+
dirStr, _ := dirV.InterfaceValue().(string)
85+
if dirStr == projectDirPrefix {
86+
hasProjectRegion = true
87+
break
88+
}
89+
}
90+
91+
if !hasProjectRegion {
92+
return map[string]any{"health": "needs_repair"}, nil
93+
}
94+
95+
return map[string]any{"health": "healthy"}, nil
96+
}
97+
98+
// ---------------------------------------------------------------------------
99+
// kb.repair_region — generate Region chunks + graph nodes for projectDir
100+
// ---------------------------------------------------------------------------
101+
102+
// handleKBRepairRegion calls RegionIndexer.IndexRegion followed by
103+
// GraphIndexer.AddFile to fill in missing Region-level chunks and graph nodes
104+
// for the given projectDir.
105+
func (d *Daemon) handleKBRepairRegion(ctx context.Context, params json.RawMessage) (any, error) {
106+
var p rpc.KBRepairRegionParams
107+
if err := unmarshalParams(params, &p); err != nil {
108+
return nil, err
109+
}
110+
if p.ProjectDir == "" {
111+
return nil, fmt.Errorf("project_dir is required")
112+
}
113+
114+
if d.regionIndexer == nil {
115+
return nil, fmt.Errorf("region indexer not available")
116+
}
117+
if d.graphIndexer == nil {
118+
return nil, fmt.Errorf("knowledge base not available")
119+
}
120+
if d.graphStore == nil {
121+
return nil, fmt.Errorf("graph store not available")
122+
}
123+
124+
absDir, err := filepath.Abs(p.ProjectDir)
125+
if err != nil {
126+
return nil, fmt.Errorf("resolve project dir: %w", err)
127+
}
128+
absDir = filepath.Clean(absDir)
129+
130+
d.logger.Info("kb.repair_region: starting", "project_dir", absDir)
131+
132+
// 1. Generate .README.md + Region graph nodes/edges
133+
result, riErr := d.regionIndexer.IndexRegion(ctx, absDir)
134+
if riErr != nil {
135+
d.logger.Error("kb.repair_region: IndexRegion failed", riErr, "project_dir", absDir)
136+
return nil, fmt.Errorf("index region: %w", riErr)
137+
}
138+
if result == nil || result.RegionFilePath == "" {
139+
d.logger.Info("kb.repair_region: no content to index", "project_dir", absDir)
140+
return map[string]any{
141+
"status": "no_change",
142+
"message": "no content to index for this directory",
143+
}, nil
144+
}
145+
146+
d.logger.Info("kb.repair_region: .README.md generated, now indexing it",
147+
"path", result.RegionFilePath)
148+
149+
// 2. Index the generated .README.md through GraphIndexer
150+
regionID := fmt.Sprintf("%x", sha256.Sum256([]byte(absDir)))
151+
fileCtx := goragindexer.WithRegionID(ctx, regionID)
152+
153+
indexStart := time.Now()
154+
chunks, idxErr := d.graphIndexer.AddFile(fileCtx, result.RegionFilePath)
155+
if idxErr != nil {
156+
d.logger.Error("kb.repair_region: AddFile failed", idxErr,
157+
"path", result.RegionFilePath)
158+
return nil, fmt.Errorf("index region file: %w", idxErr)
159+
}
160+
161+
elapsed := time.Since(indexStart).Milliseconds()
162+
d.logger.Info("kb.repair_region: completed",
163+
"project_dir", absDir,
164+
"chunks", len(chunks),
165+
"elapsed_ms", elapsed)
166+
167+
return map[string]any{
168+
"status": "repaired",
169+
"chunks": len(chunks),
170+
"region_file": result.RegionFilePath,
171+
}, nil
172+
}

internal/svc/handler_registry.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ func (r *RPCHandlerRegistry) handlers() map[string]gateway.MethodHandler {
110110
"kb.index.enqueue": r.daemon.handleKBIndexEnqueue,
111111
"kb.schema_properties": r.daemon.handleSchemaProperties,
112112
"kb.file_states": r.daemon.handleKBFileStates,
113+
"kb.check_region_health": r.daemon.handleKBCheckRegionHealth,
114+
"kb.repair_region": r.daemon.handleKBRepairRegion,
113115
"entity_tags.get": r.daemon.handleEntityTagsGet,
114116
"entity_tags.save": r.daemon.handleEntityTagsSave,
115117
"schema.get": r.daemon.handleSchemaGet,

0 commit comments

Comments
 (0)