1229
}
1230
case ActionType.ChatTruncated: {
1232
throw new Error(`ChatTruncated must be handled on an AHP chat channel: ${channel}`);
1233
}
1235
>
// When the truncation boundary is a host-injected local turn
1236
>
// (`/rename` / `!command`), redirect the SDK truncation to the
1237
>
// preceding concrete turn so the agent keeps everything up to
1238
>
// the real message before it.
1239
>
const sdkTurnId = action.turnId !== undefined
1240
? this._options.localTurns.resolveConcreteTurnId(chatChannel, action.turnId)
1241
: action.turnId;
1243
>
// by the session) or a peer chat with its own backing.
1244
>
agent?.truncateSession?.(URI.parse(sessionChannel), sdkTurnId, URI.parse(chatChannel)).catch(err => {
1245
this._logService.error('[AgentSideEffects] truncateSession failed', err);
1247
>
// Drop persisted local turns that no longer survive in the
1248
>
// (already-truncated) chat state.
1249
>
const survivingIds = new Set((this._stateManager.getChatState(chatChannel)?.turns ?? []).map(t => t.id));
1250
>
const removed = this._options.localTurns.getLocalTurnIds(chatChannel).filter(id => !survivingIds.has(id));
1251
>
this._options.localTurns.deleteLocals(sessionChannel, removed);
1252
>
this._changesets.onSessionTruncated(sessionChannel);
1253
>
break;
1254
>
}
1255
case ActionType.SessionActiveClientSet: {
1256
const agent = this._options.getAgent(channel);