feat: support long text and safe attachment batches
Build web service image / build (push) Successful in 1m15s

This commit is contained in:
2026-09-30 09:16:36 +08:00
parent a977902b25
commit edba7d0d38
26 changed files with 720 additions and 82 deletions
+33 -6
View File
@@ -309,6 +309,14 @@ try
WriteJson(result);
return result.Success ? 0 : 2;
}
case "chat" when args[1] == "send-files":
{
var paths = GetOptions(args, "--path");
var session = GetOption(args, "--session") ?? WechatLocators.FileTransferAssistant;
var messages = await WechatChatClient.SendFilesAsync(paths, cancellationToken, session);
WriteJson(new { requestedCount = messages.Count, confirmedCount = messages.Count });
return 0;
}
case "chat" when args[1] is "send-file" or "send-image":
{
var path = GetRequiredOption(args, "--path");
@@ -793,10 +801,16 @@ static int ValidateCommandLine(string[] values)
return 60;
case "send":
ValidateOptions(values, 2, ["--text", "--session", "--timeout"], []);
return 30;
return 120;
case "reply-latest":
ValidateOptions(values, 2, ["--text", "--session", "--timeout"], []);
return 60;
case "send-files":
ValidateOptions(values, 2, ["--path", "--session", "--timeout"], [], ["--path"]);
var pathCount = GetOptions(values, "--path").Count;
if (pathCount is < 2 or > WechatAttachmentInput.MaxBatchSize)
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, $"send-files requires 2-{WechatAttachmentInput.MaxBatchSize} --path values.");
return checked(pathCount * 40 + 30);
case "send-file":
case "send-image":
ValidateOptions(values, 2, ["--path", "--session", "--timeout"], []);
@@ -888,13 +902,13 @@ static int ValidateCommandLine(string[] values)
}
}
static void ValidateOptions(string[] values, int startIndex, HashSet<string> valueOptions, HashSet<string> flagOptions)
static void ValidateOptions(string[] values, int startIndex, HashSet<string> valueOptions, HashSet<string> flagOptions, HashSet<string>? repeatableValueOptions = null)
{
var seen = new HashSet<string>(StringComparer.Ordinal);
for (var index = startIndex; index < values.Length; index++)
{
var option = values[index];
if (!seen.Add(option))
if (!seen.Add(option) && repeatableValueOptions?.Contains(option) != true)
{
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, $"Duplicate option {option}.");
}
@@ -924,6 +938,19 @@ static string? GetOption(string[] values, string name)
: null;
}
static IReadOnlyList<string> GetOptions(string[] values, string name)
{
var options = new List<string>();
for (var index = 0; index + 1 < values.Length; index++)
{
if (string.Equals(values[index], name, StringComparison.Ordinal))
{
options.Add(values[++index]);
}
}
return options;
}
static string GetRequiredOption(string[] values, string name) =>
GetOption(values, name) ?? throw new WxAgentException(WxAgentErrorCode.InvalidArgument, $"Missing required option {name}.");
@@ -993,8 +1020,7 @@ static int GetPositiveIntOption(string[] values, string name, int fallback, int
return parsed;
}
static bool IsImagePath(string path) => new[] { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp" }
.Contains(Path.GetExtension(path), StringComparer.OrdinalIgnoreCase);
static bool IsImagePath(string path) => WechatAttachmentInput.IsImagePath(path);
static object ToEventOutput(MessageEvent messageEvent, bool includeContent) => new
{
@@ -1041,10 +1067,11 @@ WxAgent.Tray.exe must be started by double-click; use its 服务设置... window
group verify-at-all --group <name> --message <text> [--timeout 30]
chat send-url-card --to <name> --url <http-url> [--message <text>] [--timeout 60]
chat send-audio --to <name> --path <audio-file> --confirm CONFIRM [--timeout 60]
chat send --text <text-up-to-4000-chars; multiline-supported> [--session <name>] [--timeout 30]
chat send --text <text-up-to-20000-chars; split-into-4000-char-messages; multiline-supported> [--session <name>] [--timeout 120]
chat reply-latest --text <text-up-to-4000-chars; multiline-supported> [--session <name>] [--timeout 60]
chat send-file --path <file> [--session <name>] [--timeout 60]
chat send-image --path <image> [--session <name>] [--timeout 60]
chat send-files --path <file> --path <file> ... [--session <name>] [--timeout <seconds>] (2-10; images sent as images)
chat mention --session <name> --member <display-name> --text <text> --confirm CONFIRM [--timeout 60]
chat read [--limit 20] [--include-content] [--timeout 30]
chat history [--session <name>] [--limit 100] [--scrolls 10] [--include-content] [--timeout 60]