1062
// the source session's turns so the client sees the forked history.
1063
if (config?.fork) {
1064
>
const sourceState = this._stateManager.getSessionState(config.fork.session.toString());
agentService.ts
1065
>
const sourceChatUri = buildDefaultChatUri(config.fork.session).toString();
1066
>
const newChatUri = buildDefaultChatUri(session).toString();
1067
>
let sourceTurns: Turn[] = [];
1068
>
if (sourceState && config.fork.turnIdMapping) {
1069
>
const originalSlice = sourceState.turns.slice(0, config.fork.turnIndex + 1);
1070
>
const mapping = config.fork.turnIdMapping;
1071
>
sourceTurns = originalSlice.map(t => ({ ...t, id: mapping.get(t.id) ?? generateUuid() }));
1072
>
// Re-persist forked local turns (`/rename`, `!command`) under the
1073
>
// new session's default chat. `record` (keyed by turn id)
1074
>
// overwrites any rows a DB copy carried with the SOURCE chat URI,
1075
>
// and seeds the in-memory index for same-process fork/truncate.
1076
>
this._persistForkedLocalTurns(session.toString(), sourceChatUri, newChatUri, originalSlice, sourceTurns, mapping);
1077
>
}
1078
>
1079
>
// Prefix the forked session's title so consumers (sidebar, chat
1080
>
// model) can distinguish it from the source without each surface
1081
>
// reinventing the convention. Avoid double-prefixing when a user
1082
>
// forks an already-forked session.
1083
>
const forkedTitlePrefix = localize('agentHost.forkedTitlePrefix', "Forked: ");
1084
>
const sourceTitle = sourceState?.title;
1085
>
const forkedTitle = sourceTitle
1086
>
? (sourceTitle.startsWith(forkedTitlePrefix) ? sourceTitle : `${forkedTitlePrefix}${sourceTitle}`)
1087
: localize('agentHost.forkedSessionFallback', "Forked Session");
1088
>
const summary = this._buildInitialSummary(provider, session, config, created, forkedTitle);
agentService.ts
1089
>
const state = this._stateManager.createSession(summary);
1090
>
state.config = sessionConfig;
1091
>
this._stateManager.seedDefaultChatTurns(summary.resource, sourceTurns);
1092
>
state.activeClients = config.activeClient ? [config.activeClient] : [];
1093
>
if (initialCustomizations && initialCustomizations.length > 0) {
1094
state.customizations = [...initialCustomizations];
1095
}
1097
>
// Refine the forked session's placeholder `Forked: …` title into one
1098
>
// derived from the inherited chat. Forks seed pre-existing
1099
>
// turns, so the normal first-message/first-turn title generation
1100
>
// never fires for them — this is the fork-time equivalent.
1101
>
if (sourceTurns.length > 0) {
1102
>
this._sideEffects.generateForkedTitle(summary.resource, undefined, sourceTurns, forkedTitle, sourceTitle);
1103
>
}
1104
} else if (config?.importConversation) {
1105
// An imported conversation arrives with pre-existing turns (assigned