mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-09-27 03:53:36 +00:00
Moved the rollback rules into the chat thread
This commit is contained in:
parent
7695863201
commit
6e559145ef
@ -351,11 +351,30 @@ public sealed record ChatThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes every content block after the selected content in conversation order.
|
/// Rolls this chat thread back, so that the given content becomes the last block of the conversation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Every later block is removed in conversation order, which is the order of the time stamps and
|
||||||
|
/// the order in which the chat shows the blocks. That includes the blocks hidden from the user,
|
||||||
|
/// such as the prompts an assistant sends into a chat: the user can neither see nor remove them,
|
||||||
|
/// so leaving them behind would continue the chat with messages nobody knows about. Hidden blocks
|
||||||
|
/// before the content stay, e.g. the example conversation of a chat template. The managed
|
||||||
|
/// transcripts of the removed blocks are deleted with them.<br/><br/>
|
||||||
|
///
|
||||||
|
/// The augmented data and the AI-selected data sources are reset, too. Both describe the last
|
||||||
|
/// retrieval, not a certain message, so after a rollback nobody knows whether they belong to a
|
||||||
|
/// kept or to a removed one. The next message with active data sources retrieves anew; without
|
||||||
|
/// active data sources, the chat continues without this context. The data source options stay,
|
||||||
|
/// because they are the user's choice rather than the result of a message.<br/><br/>
|
||||||
|
///
|
||||||
|
/// What stays as well is everything the thread ratchets for security reasons, namely the data
|
||||||
|
/// security and the required provider confidence. Both only ever tighten, because the data which
|
||||||
|
/// raised them was seen by this thread. Removing the message that brought it in does not unsee
|
||||||
|
/// it, so the chat keeps demanding the same of every provider which continues it.
|
||||||
|
/// </remarks>
|
||||||
/// <param name="content">The content to keep as the last block.</param>
|
/// <param name="content">The content to keep as the last block.</param>
|
||||||
/// <returns>True when one or more later blocks were removed.</returns>
|
/// <returns>True when one or more later blocks were removed. False when the content is unknown or already the last block; the thread stays unchanged then.</returns>
|
||||||
public bool RemoveBlocksAfter(IContent content)
|
public bool RollBackTo(IContent content)
|
||||||
{
|
{
|
||||||
var sortedBlocks = this.Blocks.OrderBy(x => x.Time).ToList();
|
var sortedBlocks = this.Blocks.OrderBy(x => x.Time).ToList();
|
||||||
var blockIndex = sortedBlocks.FindIndex(block => ReferenceEquals(block.Content, content));
|
var blockIndex = sortedBlocks.FindIndex(block => ReferenceEquals(block.Content, content));
|
||||||
@ -368,6 +387,8 @@ public sealed record ChatThread
|
|||||||
this.Blocks.Remove(block);
|
this.Blocks.Remove(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.AugmentedData = string.Empty;
|
||||||
|
this.AISelectedDataSources = [];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1463,21 +1463,11 @@ public partial class ChatComponent : MSGComponentBase
|
|||||||
if (this.ChatThread is null || this.IsCurrentChatStreaming)
|
if (this.ChatThread is null || this.IsCurrentChatStreaming)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!this.ChatThread.RemoveBlocksAfter(aiBlock))
|
// Which parts of the thread a rollback resets and which it keeps is documented at RollBackTo:
|
||||||
|
if (!this.ChatThread.RollBackTo(aiBlock))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//
|
// The rollback reset the AI-selected data sources, which the data source selection still shows:
|
||||||
// Only the working state of the next turn is reset here: the augmented data and the
|
|
||||||
// AI-selected data sources are rebuilt by the RAG process anyway, so carrying the ones of a
|
|
||||||
// removed message over would just put stale context into the system prompt.
|
|
||||||
//
|
|
||||||
// What stays is everything the thread ratchets for security reasons, namely DataSecurity and
|
|
||||||
// RequiredProviderConfidence. Both only ever tighten, because the data which raised them was
|
|
||||||
// seen by this thread. Removing the message that brought it in does not unsee it, so the
|
|
||||||
// chat keeps demanding the same of every provider which continues it.
|
|
||||||
//
|
|
||||||
this.ChatThread.AugmentedData = string.Empty;
|
|
||||||
this.ChatThread.AISelectedDataSources = [];
|
|
||||||
this.dataSourceSelectionComponent?.ChangeOptionWithoutSaving(this.ChatThread.DataSourceOptions, this.ChatThread.AISelectedDataSources);
|
this.dataSourceSelectionComponent?.ChangeOptionWithoutSaving(this.ChatThread.DataSourceOptions, this.ChatThread.AISelectedDataSources);
|
||||||
this.hasUnsavedChanges = true;
|
this.hasUnsavedChanges = true;
|
||||||
await this.SaveThread();
|
await this.SaveThread();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user