@@ -19,6 +19,7 @@ import (
1919type yamlMessage struct {
2020 Role string `yaml:"role"`
2121 Content string `yaml:"content"`
22+ Compacted string `yaml:"compacted,omitempty"`
2223 ReasoningContent string `yaml:"reasoning_content,omitempty"`
2324 Timestamp int64 `yaml:"timestamp"`
2425 ToolCallID string `yaml:"tool_call_id,omitempty"`
@@ -86,9 +87,14 @@ func newYamlMessage(msg goharnesssession.Message) yamlMessage {
8687 Arguments : tc .Arguments ,
8788 })
8889 }
90+ compacted := ""
91+ if msg .Compacted != "" {
92+ compacted = base64 .StdEncoding .EncodeToString ([]byte (msg .Compacted ))
93+ }
8994 return yamlMessage {
9095 Role : msg .Role ,
9196 Content : base64 .StdEncoding .EncodeToString ([]byte (msg .Content )),
97+ Compacted : compacted ,
9298 ReasoningContent : base64 .StdEncoding .EncodeToString ([]byte (msg .ReasoningContent )),
9399 Timestamp : msg .Timestamp ,
94100 ToolCallID : msg .ToolCallID ,
@@ -107,6 +113,11 @@ func (ym yamlMessage) toCoreMessage() goharnesssession.Message {
107113 log .Printf ("[WARN] session: failed to base64-decode reasoning_content for role=%q: %v" , ym .Role , reasoningErr )
108114 reasoningDecoded = []byte (ym .ReasoningContent )
109115 }
116+ compactedDecoded , compactedErr := base64 .StdEncoding .DecodeString (ym .Compacted )
117+ if compactedErr != nil && ym .Compacted != "" {
118+ log .Printf ("[WARN] session: failed to base64-decode compacted for role=%q: %v" , ym .Role , compactedErr )
119+ compactedDecoded = []byte (ym .Compacted )
120+ }
110121 var tcs []goharnesssession.ToolCall
111122 for _ , ytc := range ym .ToolCalls {
112123 tcs = append (tcs , goharnesssession.ToolCall {
@@ -118,6 +129,7 @@ func (ym yamlMessage) toCoreMessage() goharnesssession.Message {
118129 return goharnesssession.Message {
119130 Role : ym .Role ,
120131 Content : string (decoded ),
132+ Compacted : string (compactedDecoded ),
121133 ReasoningContent : string (reasoningDecoded ),
122134 Timestamp : ym .Timestamp ,
123135 ToolCallID : ym .ToolCallID ,
@@ -883,3 +895,30 @@ func (s *FileSessionStore) Truncate(_ context.Context, sessionID string, keepCou
883895 msgs = msgs [:keepCount ]
884896 return writeMessagesToFile (path , msgs )
885897}
898+
899+ // UpdateMessages replaces all messages in the session file with the given messages.
900+ // This writes the complete message list to session.yml, overwriting any existing content.
901+ // Also persists the compaction cursor position.
902+ func (s * FileSessionStore ) UpdateMessages (_ context.Context , sessionID string , cursor int , msgs []goharnesssession.Message ) error {
903+ s .ioMu .Lock ()
904+ defer s .ioMu .Unlock ()
905+
906+ dirPath := s .findSessionDir (sessionID )
907+ if dirPath == "" {
908+ return goharnesssession .ErrSessionNotFound
909+ }
910+
911+ path := filepath .Join (dirPath , "session.yml" )
912+ if err := writeMessagesToFile (path , msgs ); err != nil {
913+ return err
914+ }
915+
916+ // Persist cursor alongside messages
917+ meta , err := LoadSessionMeta (dirPath )
918+ if err != nil {
919+ meta = & SessionMeta {SessionID : sessionID , Cursor : cursor }
920+ } else {
921+ meta .Cursor = cursor
922+ }
923+ return meta .Save (dirPath )
924+ }
0 commit comments