Validate agent is online before starting analysis tasks; normalize list_feeds JSON when persisting task reports. Co-authored-by: Cursor <cursoragent@cursor.com>
121 lines
3.1 KiB
C#
121 lines
3.1 KiB
C#
using Oms.Domain.XhsAggregate.Entities;
|
||
|
||
namespace Oms.Application.Shared;
|
||
|
||
/// <summary>
|
||
/// 小红书模块通用辅助。
|
||
/// </summary>
|
||
public static class XhsHelper
|
||
{
|
||
public const int OnlineThresholdSeconds = 90;
|
||
|
||
public static bool IsAgentOnline(XhsAgent agent, DateTime? now = null)
|
||
{
|
||
if (!string.Equals(agent.Status, "online", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (agent.LastHeartbeatTime == null)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
var current = now ?? DateTime.Now;
|
||
return (current - agent.LastHeartbeatTime.Value).TotalSeconds <= OnlineThresholdSeconds;
|
||
}
|
||
|
||
public static string BuildContentPreview(string? content, int maxLen = 200)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(content))
|
||
{
|
||
return string.Empty;
|
||
}
|
||
|
||
var text = content.Trim();
|
||
return text.Length <= maxLen ? text : text[..maxLen];
|
||
}
|
||
|
||
public static string? ExtractRecipeNotes(string? recipeJson)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(recipeJson))
|
||
{
|
||
return null;
|
||
}
|
||
|
||
try
|
||
{
|
||
using var doc = System.Text.Json.JsonDocument.Parse(recipeJson);
|
||
if (doc.RootElement.TryGetProperty("notes", out var notes))
|
||
{
|
||
var text = notes.GetString();
|
||
if (!string.IsNullOrWhiteSpace(text))
|
||
{
|
||
return text.Trim();
|
||
}
|
||
}
|
||
|
||
if (doc.RootElement.TryGetProperty("body", out var body) &&
|
||
body.TryGetProperty("domain", out var domain))
|
||
{
|
||
return domain.GetString()?.Trim();
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
return null;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
public static string SerializeFeedsForPrompt(object? feeds)
|
||
{
|
||
if (feeds == null)
|
||
{
|
||
return string.Empty;
|
||
}
|
||
|
||
var json = OmsDocHelper.SerializeJson(feeds) ?? string.Empty;
|
||
return json.Length <= 12000 ? json : json[..12000];
|
||
}
|
||
|
||
/// <summary>
|
||
/// Agent 上报的 browse 结果可能是 { summary, raw },raw 内为 CLI JSON 输出。
|
||
/// </summary>
|
||
public static object? NormalizeBrowseTaskResult(object? result)
|
||
{
|
||
if (result == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
var json = OmsDocHelper.SerializeJson(result);
|
||
var obj = OmsDocHelper.DeserializeJson<Dictionary<string, object>>(json);
|
||
if (obj == null)
|
||
{
|
||
return result;
|
||
}
|
||
|
||
if (obj.ContainsKey("feeds") || obj.ContainsKey("items") || obj.ContainsKey("notes"))
|
||
{
|
||
return obj;
|
||
}
|
||
|
||
if (obj.TryGetValue("raw", out var raw) && raw != null)
|
||
{
|
||
var rawText = raw.ToString();
|
||
if (!string.IsNullOrWhiteSpace(rawText))
|
||
{
|
||
var parsed = OmsDocHelper.DeserializeJsonObject(rawText);
|
||
if (parsed != null)
|
||
{
|
||
return parsed;
|
||
}
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
}
|