using AIStudio.Provider;
namespace AIStudio.Chat;
///
/// What a conversation carries into its next request, as far as a provider has stated it.
///
///
/// Two parts, and only one of them is the provider's statement. PromptTokens is what the provider
/// counted for the request behind the last answer: the system prompt, the tools, and every message
/// up to the question. The answer travels in the next request as well, though not in the shape the
/// provider charged for: its completion included the model's reasoning and whatever the model wrote
/// between think tags. So the answer comes along as the text it will be sent as, and is counted the
/// same way every other text is.
///
/// That text is the answer alone. Reasoning never belongs to it, whether it was thrown away or kept
/// to be read next to the answer: it is there for a person, and no request carries it. An answer
/// which consists of reasoning only has no text at all, is not sent, and adds nothing to the prompt.
///
/// What is estimated that way is one answer, next to a prompt which holds the whole conversation
/// before it. The error is the tokenizer's error on that one answer, not on the chat.
///
public sealed record ReportedHistory
{
///
/// The history of a conversation no report describes.
///
public static readonly ReportedHistory UNKNOWN = new();
///
/// Whether a report describes the conversation. When false, nothing else here means anything.
///
public bool IsKnown { get; private init; }
///
/// What the provider counted for the request behind the last answer.
///
public int PromptTokens { get; private init; }
///
/// The text of the last answer, as the next request will carry it, without any reasoning.
///
public string LastAnswer { get; private init; } = string.Empty;
///
/// States what a report says about the conversation.
///
/// What the provider reported for the request behind the last answer.
/// The text of that answer.
/// The history, or UNKNOWN when the usage states nothing.
public static ReportedHistory Of(TokenUsage usage, string lastAnswer) => usage.IsKnown
? new()
{
IsKnown = true,
PromptTokens = usage.PromptTokens,
LastAnswer = lastAnswer,
}
: UNKNOWN;
}