46 lines
2.4 KiB
C#
46 lines
2.4 KiB
C#
using System.Globalization;
|
|
using Microsoft.Extensions.Logging;
|
|
using Volcanic.AgenticCore.Extensions.A2A;
|
|
using Volcanic.AgenticCore.Telegram.Chats;
|
|
|
|
namespace Volcanic.AgenticCore.Telegram.A2A;
|
|
|
|
/// <summary>
|
|
/// A2A watch results as follow-up prompts in the chat (target = chat id, invariant culture), like scheduled prompts:
|
|
/// never through the inbox. The chat's session is created on demand; <see cref="ChatRegistry.GetAsync"/> returns it only
|
|
/// once its renderer is subscribed, so the answer is always rendered. <see cref="WorkspaceFor"/> never creates a session.
|
|
/// </summary>
|
|
public sealed class TelegramA2AResultDelivery(ChatRegistry chats, ChatSettingsStore settings, TelegramOptions options, TimeProvider time,
|
|
ILogger<TelegramA2AResultDelivery> logger) : IA2AResultDelivery
|
|
{
|
|
private static bool TryChatIdOf(string target, out long chatId) =>
|
|
long.TryParse(target, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out chatId);
|
|
|
|
/// <summary>False (kept for later) for a target that isn't an allowed chat or whose session can't be opened.</summary>
|
|
public async Task<bool> DeliverAsync(string target, string text, CancellationToken cancellationToken)
|
|
{
|
|
if (!TryChatIdOf(target, out var chatId) || !options.IsAllowed(chatId)) return false;
|
|
var chat = await chats.GetAsync(chatId, cancellationToken).ConfigureAwait(false);
|
|
try
|
|
{
|
|
await ChatFollowUps.RunAsync(chat, text, settings.TimeZoneFor(chatId), time, cancellationToken).ConfigureAwait(false);
|
|
}
|
|
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
|
|
{
|
|
throw;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// The prompt was handed to the session: delivered. The user sees why nothing came of it.
|
|
logger.LogError(ex, "A2A result in chat {ChatId} failed", chatId);
|
|
chat.Report($"An A2A result arrived but couldn't be processed: {ex.Message}");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public string? WorkspaceFor(string target) => TryChatIdOf(target, out var chatId) ? ChatRegistry.WorkspaceFor(options, chatId) : null;
|
|
|
|
/// <summary>Allowed chats only: a chat that left the allow-list keeps its pending.json untouched.</summary>
|
|
public IEnumerable<string> KnownTargets() => options.AllowedUserIds.Select(id => id.ToString(CultureInfo.InvariantCulture)).ToList();
|
|
}
|