mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-14 21:08:27 +00:00
Added the Model Comparison assistant for blind comparisons of two models (#1009)
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
1 parent
12f26445ba
commit
b7255694cd
221 files changed
+19989
-90
No files matched your search
@@ -0,0 +1,79 @@
|
||||
using System.Text;
|
||||
|
||||
namespace AIStudio.Chat;
|
||||
|
||||
/// <summary>
|
||||
/// Writes what the user sees of a chat as plain text, for a model which reads the chat, such as a judge.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only the messages the user sees count: hidden requests, the results of tools, and the content of attached files
|
||||
/// stay out. A call of a tool is one line with its name and its arguments, each shortened, so that a reader learns what
|
||||
/// the model looked up without reading everything it got back. The thinking of a model stays out as well.
|
||||
/// </remarks>
|
||||
public static class ChatTranscript
|
||||
{
|
||||
/// <summary>
|
||||
/// How many characters of each argument of a tool call the transcript keeps.
|
||||
/// </summary>
|
||||
public const int MAX_ARGUMENT_LENGTH = 80;
|
||||
|
||||
/// <summary>
|
||||
/// Writes the transcript of a chat.
|
||||
/// </summary>
|
||||
/// <param name="thread">The chat.</param>
|
||||
/// <returns>The messages in their order, each below a line naming who wrote it.</returns>
|
||||
public static string Of(ChatThread thread)
|
||||
{
|
||||
var transcript = new StringBuilder();
|
||||
foreach (var block in thread.Blocks)
|
||||
{
|
||||
if (block is not { HideFromUser: false, Content: ContentText content })
|
||||
continue;
|
||||
|
||||
var message = Message(block.Role, content);
|
||||
if (message.Length == 0)
|
||||
continue;
|
||||
|
||||
if (transcript.Length > 0)
|
||||
transcript.AppendLineLF();
|
||||
|
||||
transcript.AppendLineLF(block.Role is ChatRole.USER ? "[User]" : "[Assistant]");
|
||||
transcript.AppendLineLF(message);
|
||||
}
|
||||
|
||||
return transcript.ToString().TrimEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes one message: the calls of tools first, since the model made them before it answered, then the text, then
|
||||
/// the names of attached files.
|
||||
/// </summary>
|
||||
private static string Message(ChatRole role, ContentText content)
|
||||
{
|
||||
var lines = new List<string>();
|
||||
if (role is ChatRole.AI)
|
||||
lines.AddRange(content.ToolInvocations.OrderBy(call => call.Order).Select(call => $"[Tool call: {call.ToolName}({Arguments(call.Arguments)})]"));
|
||||
|
||||
var text = role is ChatRole.AI ? content.Text.RemoveThinkTags().Trim() : content.Text.Trim();
|
||||
if (text.Length > 0)
|
||||
lines.Add(text);
|
||||
|
||||
if (content.FileAttachments.Count > 0)
|
||||
lines.Add($"[Attached files: {string.Join(", ", content.FileAttachments.Select(attachment => attachment.FileName))}]");
|
||||
|
||||
return string.Join('\n', lines);
|
||||
}
|
||||
|
||||
private static string Arguments(IReadOnlyDictionary<string, string> arguments) => string.Join(", ", arguments.Select(argument => $"{argument.Key}={Shortened(argument.Value)}"));
|
||||
|
||||
private static string Shortened(string value)
|
||||
{
|
||||
var singleLine = value.ReplaceLineEndings(" ").Trim();
|
||||
if (singleLine.Length <= MAX_ARGUMENT_LENGTH)
|
||||
return singleLine;
|
||||
|
||||
// Cutting between the two halves of a character outside the basic plane would leave half of it:
|
||||
var length = char.IsHighSurrogate(singleLine[MAX_ARGUMENT_LENGTH - 1]) ? MAX_ARGUMENT_LENGTH - 1 : MAX_ARGUMENT_LENGTH;
|
||||
return singleLine[..length] + "…";
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user