admin/src/Oms.Application/Shared/XhsHelper.cs
zzh 50c6fd8ac8 fix(xhs): reject offline agent for analysis and normalize browse task results
Validate agent is online before starting analysis tasks; normalize list_feeds JSON when persisting task reports.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 12:36:28 +08:00

121 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}