fix: avoid base string coercion in auto-reply formatting

This commit is contained in:
Peter Steinberger
2026-01-15 17:01:28 +00:00
parent fc4aa9a683
commit 01c43b0b0c
3 changed files with 37 additions and 6 deletions

View File

@@ -4,8 +4,14 @@ export type CommandArgsFormatter = (values: CommandArgValues) => string | undefi
function normalizeArgValue(value: unknown): string | undefined { function normalizeArgValue(value: unknown): string | undefined {
if (value == null) return undefined; if (value == null) return undefined;
const text = typeof value === "string" ? value.trim() : String(value).trim(); if (typeof value === "string") {
return text ? text : undefined; const trimmed = value.trim();
return trimmed ? trimmed : undefined;
}
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
return String(value);
}
return undefined;
} }
const formatConfigArgs: CommandArgsFormatter = (values) => { const formatConfigArgs: CommandArgsFormatter = (values) => {

View File

@@ -137,9 +137,13 @@ function formatPositionalArgs(
for (const definition of definitions) { for (const definition of definitions) {
const value = values[definition.name]; const value = values[definition.name];
if (value == null) continue; if (value == null) continue;
const rendered = typeof value === "string" ? value.trim() : String(value); if (typeof value === "string") {
if (!rendered) continue; const trimmed = value.trim();
parts.push(rendered); if (!trimmed) continue;
parts.push(trimmed);
} else if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
parts.push(String(value));
}
if (definition.captureRemaining) break; if (definition.captureRemaining) break;
} }
return parts.length > 0 ? parts.join(" ") : undefined; return parts.length > 0 ? parts.join(" ") : undefined;

View File

@@ -78,11 +78,32 @@ export type TemplateContext = MsgContext & {
IsNewSession?: string; IsNewSession?: string;
}; };
function formatTemplateValue(value: unknown): string {
if (value == null) return "";
if (typeof value === "string") return value;
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
return String(value);
}
if (Array.isArray(value)) {
return value
.flatMap((entry) => {
if (entry == null) return [];
if (typeof entry === "string") return [entry];
if (typeof entry === "number" || typeof entry === "boolean" || typeof entry === "bigint") {
return [String(entry)];
}
return [];
})
.join(",");
}
return "";
}
// Simple {{Placeholder}} interpolation using inbound message context. // Simple {{Placeholder}} interpolation using inbound message context.
export function applyTemplate(str: string | undefined, ctx: TemplateContext) { export function applyTemplate(str: string | undefined, ctx: TemplateContext) {
if (!str) return ""; if (!str) return "";
return str.replace(/{{\s*(\w+)\s*}}/g, (_, key) => { return str.replace(/{{\s*(\w+)\s*}}/g, (_, key) => {
const value = ctx[key as keyof TemplateContext]; const value = ctx[key as keyof TemplateContext];
return value == null ? "" : String(value); return formatTemplateValue(value);
}); });
} }