mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 18:01:22 +00:00
fix(coding-agent): prevent duplicate session headers when forking from pre-assistant entry
createBranchedSession() wrote the file and set flushed=true even when the branched path had no assistant message. The next _persist() call saw no assistant, reset flushed=false, and the subsequent flush appended all in-memory entries to the already-populated file, duplicating the header and entries. Fix: defer file creation when the branched path has no assistant message, matching the newSession() contract. _persist() creates the file on the first assistant response. closes #1672
This commit is contained in:
parent
9825c13f5f
commit
2f64df1e52
3 changed files with 90 additions and 7 deletions
|
|
@ -1187,11 +1187,7 @@ export class SessionManager {
|
|||
}
|
||||
|
||||
if (this.persist) {
|
||||
appendFileSync(newSessionFile, `${JSON.stringify(header)}\n`);
|
||||
for (const entry of pathWithoutLabels) {
|
||||
appendFileSync(newSessionFile, `${JSON.stringify(entry)}\n`);
|
||||
}
|
||||
// Write fresh label entries at the end
|
||||
// Build label entries
|
||||
const lastEntryId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null;
|
||||
let parentId = lastEntryId;
|
||||
const labelEntries: LabelEntry[] = [];
|
||||
|
|
@ -1204,16 +1200,29 @@ export class SessionManager {
|
|||
targetId,
|
||||
label,
|
||||
};
|
||||
appendFileSync(newSessionFile, `${JSON.stringify(labelEntry)}\n`);
|
||||
pathEntryIds.add(labelEntry.id);
|
||||
labelEntries.push(labelEntry);
|
||||
parentId = labelEntry.id;
|
||||
}
|
||||
|
||||
this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];
|
||||
this.sessionId = newSessionId;
|
||||
this.sessionFile = newSessionFile;
|
||||
this.flushed = true;
|
||||
this._buildIndex();
|
||||
|
||||
// Only write the file now if it contains an assistant message.
|
||||
// Otherwise defer to _persist(), which creates the file on the
|
||||
// first assistant response, matching the newSession() contract
|
||||
// and avoiding the duplicate-header bug when _persist()'s
|
||||
// no-assistant guard later resets flushed to false.
|
||||
const hasAssistant = this.fileEntries.some((e) => e.type === "message" && e.message.role === "assistant");
|
||||
if (hasAssistant) {
|
||||
this._rewriteFile();
|
||||
this.flushed = true;
|
||||
} else {
|
||||
this.flushed = false;
|
||||
}
|
||||
|
||||
return newSessionFile;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue