@@ -66,12 +66,11 @@ type persistedAskConfig struct {
6666}
6767
6868type persistedMemoConfig struct {
69- Enabled * bool `yaml:"enabled,omitempty"`
70- AutoExtract * bool `yaml:"auto_extract,omitempty"`
71- MaxEntries * int `yaml:"max_entries,omitempty"`
72- MaxIndexBytes * int `yaml:"max_index_bytes,omitempty"`
73- ExtractTimeoutSec * int `yaml:"extract_timeout_sec,omitempty"`
74- ExtractRecentMessages * int `yaml:"extract_recent_messages,omitempty"`
69+ Enabled * bool `yaml:"enabled,omitempty"`
70+ AutoExtract * bool `yaml:"auto_extract,omitempty"`
71+ MaxEntries * int `yaml:"max_entries,omitempty"`
72+ MaxIndexBytes * int `yaml:"max_index_bytes,omitempty"`
73+ ExtractTimeoutSec * int `yaml:"extract_timeout_sec,omitempty"`
7574}
7675
7776func NewLoader (baseDir string , defaults * Config ) * Loader {
@@ -225,6 +224,9 @@ func parseConfigWithContextDefaults(
225224}
226225
227226func parseCurrentConfig (data []byte , contextDefaults ContextConfig , memoDefaults MemoConfig ) (* Config , error ) {
227+ if err := rejectRemovedMemoFields (data ); err != nil {
228+ return nil , err
229+ }
228230 var file persistedConfig
229231 decoder := yaml .NewDecoder (bytes .NewReader (data ))
230232 decoder .KnownFields (true )
@@ -384,14 +386,12 @@ func newPersistedMemoConfig(cfg MemoConfig) persistedMemoConfig {
384386 maxEntries := cfg .MaxEntries
385387 maxIndexBytes := cfg .MaxIndexBytes
386388 extractTimeoutSec := cfg .ExtractTimeoutSec
387- extractRecentMessages := cfg .ExtractRecentMessages
388389 return persistedMemoConfig {
389- Enabled : & enabled ,
390- AutoExtract : & autoExtract ,
391- MaxEntries : & maxEntries ,
392- MaxIndexBytes : & maxIndexBytes ,
393- ExtractTimeoutSec : & extractTimeoutSec ,
394- ExtractRecentMessages : & extractRecentMessages ,
390+ Enabled : & enabled ,
391+ AutoExtract : & autoExtract ,
392+ MaxEntries : & maxEntries ,
393+ MaxIndexBytes : & maxIndexBytes ,
394+ ExtractTimeoutSec : & extractTimeoutSec ,
395395 }
396396}
397397
@@ -413,12 +413,43 @@ func fromPersistedMemoConfig(file persistedMemoConfig, defaults MemoConfig) Memo
413413 if file .ExtractTimeoutSec != nil {
414414 out .ExtractTimeoutSec = * file .ExtractTimeoutSec
415415 }
416- if file .ExtractRecentMessages != nil {
417- out .ExtractRecentMessages = * file .ExtractRecentMessages
418- }
419416 return out
420417}
421418
419+ // rejectRemovedMemoFields 在 strict decode 前拦截已删除的 memo 字段,输出明确迁移提示。
420+ func rejectRemovedMemoFields (data []byte ) error {
421+ var root yaml.Node
422+ if err := yaml .Unmarshal (data , & root ); err != nil {
423+ return err
424+ }
425+ if len (root .Content ) == 0 {
426+ return nil
427+ }
428+ doc := root .Content [0 ]
429+ if doc .Kind != yaml .MappingNode {
430+ return nil
431+ }
432+
433+ for i := 0 ; i < len (doc .Content ); i += 2 {
434+ if strings .TrimSpace (doc .Content [i ].Value ) != "memo" {
435+ continue
436+ }
437+ memoNode := doc .Content [i + 1 ]
438+ if memoNode .Kind != yaml .MappingNode {
439+ return nil
440+ }
441+ for j := 0 ; j < len (memoNode .Content ); j += 2 {
442+ if strings .TrimSpace (memoNode .Content [j ].Value ) == "extract_recent_messages" {
443+ return fmt .Errorf (
444+ "config: memo.extract_recent_messages has been removed; memory extraction now always uses the full run boundary" ,
445+ )
446+ }
447+ }
448+ return nil
449+ }
450+ return nil
451+ }
452+
422453// normalizeVerificationSchemaContent 在内存中预处理 verification schema,避免旧字段先于 strict decode 触发硬失败。
423454func normalizeVerificationSchemaContent (raw []byte ) ([]byte , bool , error ) {
424455 if len (bytes .TrimSpace (raw )) == 0 {
0 commit comments