Skip to content

Commit cc3b794

Browse files
committed
refactor(agent): adapt fitMessages to the non-mutating messagefit API
messagefit.Fit now returns (kept, keptIdx, count) instead of clearing dropped entries in place. Iterate keptIdx and write kept[j].Content back to the right field; the empty-content sentinel check (and fitSource.hadText) is no longer needed because dropped entries are simply absent from keptIdx.
1 parent 6aae7ae commit cc3b794

1 file changed

Lines changed: 16 additions & 20 deletions

File tree

  • internal/agent/component

internal/agent/component/llm.go

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,19 +1047,18 @@ func fitMessages(systemPrompt string, msgs []schema.Message, maxLength int) ([]s
10471047
// Convert to messagefit.Message. Track where each entry's text lives
10481048
// (plain Content or a multi-modal text part) so the fitted text can be
10491049
// written back to the right field. Entries with no text at all
1050-
// (image-only turns) have hadText=false and are preserved even though
1051-
// messagefit represents them with an empty Content.
1050+
// (image-only turns) carry an empty Content in messagefit and survive
1051+
// fitting when kept.
10521052
type fitSource struct {
10531053
copiedIdx int // index into copied; -1 for the synthetic system prompt
10541054
multiIdx int // -1 means the text lives in Content
1055-
hadText bool
10561055
}
10571056
all := make([]messagefit.Message, 0, 1+len(copied))
10581057
sources := make([]fitSource, 0, 1+len(copied))
10591058

10601059
if systemPrompt != "" {
10611060
all = append(all, messagefit.Message{Role: "system", Content: systemPrompt})
1062-
sources = append(sources, fitSource{copiedIdx: -1, multiIdx: 0, hadText: true})
1061+
sources = append(sources, fitSource{copiedIdx: -1, multiIdx: 0})
10631062
}
10641063

10651064
for i := range copied {
@@ -1085,42 +1084,39 @@ func fitMessages(systemPrompt string, msgs []schema.Message, maxLength int) ([]s
10851084
}
10861085
}
10871086
all = append(all, messagefit.Message{Role: string(copied[i].Role), Content: text})
1088-
sources = append(sources, fitSource{copiedIdx: i, multiIdx: multiIdx, hadText: hadText})
1087+
sources = append(sources, fitSource{copiedIdx: i, multiIdx: multiIdx})
10891088
}
10901089

10911090
// Use 97% of effective context as the token budget.
10921091
budget := contextFitBudget(maxLength)
1093-
messagefit.Fit(all, budget)
1092+
kept, keptIdx, _ := messagefit.Fit(all, budget)
10941093

1095-
// Convert back to []schema.Message. messagefit marks dropped entries by
1096-
// emptying their Content; image-only entries were already empty before
1097-
// fitting and are always preserved.
1098-
result := make([]schema.Message, 0, len(all))
1099-
for i := range all {
1094+
// Convert back to []schema.Message. messagefit.Fit reports exactly which
1095+
// entries are kept (keptIdx); dropped entries are simply absent, so no
1096+
// empty-content sentinel is needed and image-only turns are preserved.
1097+
result := make([]schema.Message, 0, len(kept))
1098+
for j, i := range keptIdx {
11001099
src := sources[i]
1101-
if all[i].Content == "" && src.hadText {
1102-
continue // dropped by fitter
1103-
}
11041100
if src.copiedIdx < 0 {
1105-
result = append(result, schema.Message{Role: schema.System, Content: all[i].Content})
1101+
result = append(result, schema.Message{Role: schema.System, Content: kept[j].Content})
11061102
continue
11071103
}
11081104
m := copied[src.copiedIdx]
11091105
if src.multiIdx >= 0 && src.multiIdx < len(m.UserInputMultiContent) {
1110-
m.UserInputMultiContent[src.multiIdx].Text = all[i].Content
1106+
m.UserInputMultiContent[src.multiIdx].Text = kept[j].Content
11111107
// Drop any additional text parts: their content was folded into
11121108
// the first part before fitting, so keeping them would re-introduce
11131109
// text outside the token budget.
11141110
keptParts := m.UserInputMultiContent[:0]
1115-
for j, part := range m.UserInputMultiContent {
1116-
if part.Type == schema.ChatMessagePartTypeText && j != src.multiIdx {
1111+
for k, part := range m.UserInputMultiContent {
1112+
if part.Type == schema.ChatMessagePartTypeText && k != src.multiIdx {
11171113
continue
11181114
}
11191115
keptParts = append(keptParts, part)
11201116
}
11211117
m.UserInputMultiContent = keptParts
1122-
} else if all[i].Content != "" {
1123-
m.Content = all[i].Content
1118+
} else if kept[j].Content != "" {
1119+
m.Content = kept[j].Content
11241120
}
11251121
result = append(result, m)
11261122
}

0 commit comments

Comments
 (0)