@@ -9,30 +9,39 @@ import (
99
1010// DefaultBuilder preserves the current runtime context-building behavior.
1111type DefaultBuilder struct {
12- promptSources []promptSectionSource
13- trimPolicy messageTrimPolicy
14- microCompactCfg MicroCompactConfig
12+ stablePromptSources []promptSectionSource
13+ dynamicPromptSources []promptSectionSource
14+ promptSources []promptSectionSource
15+ trimPolicy messageTrimPolicy
16+ microCompactCfg MicroCompactConfig
1517}
1618
17- // newPromptSources 组装系统提示词来源列表,将额外 SectionSource 插入到 systemState 之前 。
18- // nil 元素会被跳过,不会影响来源顺序 。
19- func newPromptSources (extra ... SectionSource ) []promptSectionSource {
19+ // newStablePromptSources 返回稳定提示词来源列表,适合作为缓存前缀 。
20+ // extra 中的非 nil SectionSource 也会追加到 stable 中(如 memo 持久记忆索引) 。
21+ func newStablePromptSources (extra ... SectionSource ) []promptSectionSource {
2022 sources := []promptSectionSource {
2123 corePromptSource {},
22- capabilitiesSource {},
2324 newRulesPromptSource (nil ),
24- taskStateSource {},
25- planModeContextSource {},
26- todosSource {},
27- skillPromptSource {},
2825 }
2926 for _ , src := range extra {
3027 if src != nil {
3128 sources = append (sources , src )
3229 }
3330 }
34- sources = append (sources , repositoryContextSource {})
35- return append (sources , & systemStateSource {})
31+ return sources
32+ }
33+
34+ // newDynamicPromptSources 返回动态提示词来源列表,随任务进度、会话状态变化。
35+ func newDynamicPromptSources () []promptSectionSource {
36+ return []promptSectionSource {
37+ capabilitiesSource {},
38+ taskStateSource {},
39+ planModeContextSource {},
40+ todosSource {},
41+ skillPromptSource {},
42+ repositoryContextSource {},
43+ & systemStateSource {},
44+ }
3645}
3746
3847// NewConfiguredBuilder 基于聚合配置和可选 SectionSource 列表构建上下文构建器,是推荐的统一构造入口。
@@ -42,9 +51,10 @@ func NewConfiguredBuilder(cfg MicroCompactConfig, sources ...SectionSource) Buil
4251 cfg .PinChecker = NewDefaultPinChecker ()
4352 }
4453 return & DefaultBuilder {
45- promptSources : newPromptSources (sources ... ),
46- trimPolicy : spanMessageTrimPolicy {},
47- microCompactCfg : cfg ,
54+ stablePromptSources : newStablePromptSources (sources ... ),
55+ dynamicPromptSources : newDynamicPromptSources (),
56+ trimPolicy : spanMessageTrimPolicy {},
57+ microCompactCfg : cfg ,
4858 }
4959}
5060
@@ -82,20 +92,50 @@ func NewBuilderWithMemoAndSummarizers(policies MicroCompactPolicySource, summari
8292 return NewConfiguredBuilder (MicroCompactConfig {Policies : policies , Summarizers : summarizers }, memoSource )
8393}
8494
95+ // collectPromptSections 遍历 promptSectionSource 列表并收集所有 sections。
96+ func collectPromptSections (ctx context.Context , input BuildInput , sources []promptSectionSource ) ([]promptSection , error ) {
97+ sections := make ([]promptSection , 0 , len (sources ))
98+ for _ , source := range sources {
99+ sourceSections , err := source .Sections (ctx , input )
100+ if err != nil {
101+ return nil , err
102+ }
103+ sections = append (sections , sourceSections ... )
104+ }
105+ return sections , nil
106+ }
107+
85108// Build assembles the provider-facing context for the current round.
86109func (b * DefaultBuilder ) Build (ctx context.Context , input BuildInput ) (BuildResult , error ) {
87110 if err := ctx .Err (); err != nil {
88111 return BuildResult {}, err
89112 }
90113
91- sections := make ([]promptSection , 0 , len (b .promptSources )+ 1 )
92- for _ , source := range b .promptSources {
93- sourceSections , err := source .Sections (ctx , input )
114+ stableSources := b .stablePromptSources
115+ dynamicSources := b .dynamicPromptSources
116+
117+ // 兼容旧构造方式:如果新字段未设置但旧 promptSources 有内容,回退到旧单列表。
118+ if len (stableSources ) == 0 && len (dynamicSources ) == 0 && len (b .promptSources ) > 0 {
119+ stableSources = b .promptSources
120+ }
121+
122+ var stablePrompt , dynamicPrompt string
123+ if stableSources != nil {
124+ stableSections , err := collectPromptSections (ctx , input , stableSources )
94125 if err != nil {
95126 return BuildResult {}, err
96127 }
97- sections = append ( sections , sourceSections ... )
128+ stablePrompt = composeSystemPrompt ( stableSections ... )
98129 }
130+ if dynamicSources != nil {
131+ dynamicSections , err := collectPromptSections (ctx , input , dynamicSources )
132+ if err != nil {
133+ return BuildResult {}, err
134+ }
135+ dynamicPrompt = composeSystemPrompt (dynamicSections ... )
136+ }
137+
138+ systemPrompt := joinSystemPromptParts (stablePrompt , dynamicPrompt )
99139
100140 trimPolicy := b .trimPolicy
101141 if trimPolicy == nil {
@@ -107,7 +147,9 @@ func (b *DefaultBuilder) Build(ctx context.Context, input BuildInput) (BuildResu
107147 }
108148
109149 return BuildResult {
110- SystemPrompt : composeSystemPrompt (sections ... ),
150+ SystemPrompt : systemPrompt ,
151+ StableSystemPrompt : stablePrompt ,
152+ DynamicSystemPrompt : dynamicPrompt ,
111153 Messages : applyReadTimeContextProjection (
112154 trimPolicy .Trim (input .Messages , input .Compact ),
113155 input .TaskState ,
0 commit comments