forked from admin/VolcanicAgenticCore
78 lines
3.3 KiB
C#
78 lines
3.3 KiB
C#
using System.Globalization;
|
|
using System.Text.Json.Nodes;
|
|
using Volcanic.AgenticCore.Telegram.Groups;
|
|
|
|
namespace Volcanic.AgenticCore.Telegram.Triggers;
|
|
|
|
/// <summary>What Jev is asked: the state for one message or a snooze batch, and each trigger's question.</summary>
|
|
public static class JevStates
|
|
{
|
|
/// <summary><c>{ group, sender, text, reply_to? }</c>.</summary>
|
|
public static JsonObject Single(GroupMessage message)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(message);
|
|
var state = new JsonObject { ["group"] = message.GroupTitle, ["sender"] = message.Sender, ["text"] = message.Text ?? "" };
|
|
AddReply(state, message);
|
|
return state;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <c>{ group, messages: [ { time, sender, text, reply_to? } ] }</c>, split so each state stays under
|
|
/// <paramref name="maxChars"/> characters of JSON (one oversized message still gets a state of its own).
|
|
/// </summary>
|
|
public static IReadOnlyList<JsonObject> Batches(string groupTitle, IReadOnlyList<GroupMessage> messages, TimeZoneInfo zone, int maxChars)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(messages);
|
|
ArgumentNullException.ThrowIfNull(zone);
|
|
var states = new List<JsonObject>();
|
|
JsonArray? current = null;
|
|
var size = 0;
|
|
foreach (var message in messages)
|
|
{
|
|
var item = new JsonObject
|
|
{
|
|
["time"] = TimeZoneInfo.ConvertTime(message.Time, zone).ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture),
|
|
["sender"] = message.Sender,
|
|
["text"] = message.Text ?? "",
|
|
};
|
|
AddReply(item, message);
|
|
var itemSize = item.ToJsonString().Length + 1;
|
|
if (current is null || (size + itemSize > maxChars && current.Count > 0))
|
|
{
|
|
current = [];
|
|
states.Add(new JsonObject { ["group"] = groupTitle, ["messages"] = current });
|
|
size = groupTitle.Length + 30;
|
|
}
|
|
current.Add(item);
|
|
size += itemSize;
|
|
}
|
|
return states;
|
|
}
|
|
|
|
public static JevQuestion Question(string id, Trigger trigger)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(trigger);
|
|
return new JevQuestion(id, trigger.Instructions, trigger.CriteriaTrue, trigger.CriteriaFalse);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The trigger's one-message question wrapped for a batch: asked plainly, a batch scores high on loosely related
|
|
/// chatter and lower on the real thing (measured: 0.92 vs 0.99 plain, 0.12 vs 0.99 wrapped).
|
|
/// </summary>
|
|
public static JevQuestion BatchQuestion(string id, Trigger trigger)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(trigger);
|
|
var both = !string.IsNullOrWhiteSpace(trigger.CriteriaTrue) && !string.IsNullOrWhiteSpace(trigger.CriteriaFalse);
|
|
return new JevQuestion(id,
|
|
"Answer yes if at least one message in the batch passes this check: " + trigger.Instructions,
|
|
both ? "At least one message: " + trigger.CriteriaTrue : null,
|
|
both ? "No message does; all are like: " + trigger.CriteriaFalse : null);
|
|
}
|
|
|
|
private static void AddReply(JsonObject target, GroupMessage message)
|
|
{
|
|
if (message.ReplyTo is { } reply)
|
|
target["reply_to"] = new JsonObject { ["sender"] = reply.Sender, ["text"] = reply.Text ?? "" };
|
|
}
|
|
}
|