package glue import ( "context" "mind/internal/models" ) type Linearized struct { Nodes []models.Node `json:"nodes"` Text string `json:"text"` } func (g *Glue) LinearizeByBranch(ctx context.Context, convID int64, branchName string) (Linearized, error) { b, err := g.repo.GetBranch(ctx, convID, branchName) if err != nil { return Linearized{}, err } return g.linearizeFromHead(ctx, b.HeadNodeID) } func (g *Glue) linearizeFromHead(ctx context.Context, head int64) (Linearized, error) { var seq []models.Node // Walk parents by latest-created parent until none curID := head for { n, err := g.repo.GetNode(ctx, curID) if err != nil { return Linearized{}, err } seq = append(seq, n) p, ok, err := g.repo.LatestParent(ctx, curID) if err != nil { return Linearized{}, err } if !ok { break } curID = p.ID } // Reverse seq to root→head, and stitch text for i, j := 0, len(seq)-1; i < j; i, j = i+1, j-1 { seq[i], seq[j] = seq[j], seq[i] } var txt string for _, n := range seq { role := "[user]" if n.AuthorKind == "assistant" { role = "[assistant]" } txt += role + "\n" + n.Content + "\n\n" } return Linearized{Nodes: seq, Text: txt}, nil }