diff --git a/packages/__tests__/prompts/templates.test.ts b/packages/__tests__/prompts/templates.test.ts new file mode 100644 index 0000000000..f1cd7312bb --- /dev/null +++ b/packages/__tests__/prompts/templates.test.ts @@ -0,0 +1,49 @@ +import { describe, it, expect } from "@jest/globals"; +import { HeliconeTemplateManager } from "@helicone-package/prompts/templates"; + +describe("HeliconeTemplateManager.substituteVariables", () => { + it("substitutes falsy-but-valid values (0, false, empty string)", () => { + expect( + HeliconeTemplateManager.substituteVariables( + "You have {{hc:count:number}} new messages", + { count: 0 }, + {} + ).result + ).toBe("You have 0 new messages"); + + expect( + HeliconeTemplateManager.substituteVariables( + "Enabled: {{hc:flag:boolean}}", + { flag: false }, + {} + ).result + ).toBe("Enabled: false"); + + expect( + HeliconeTemplateManager.substituteVariables( + "Name=[{{hc:name:string}}]", + { name: "" }, + {} + ).result + ).toBe("Name=[]"); + }); + + it("still substitutes truthy values and leaves missing variables untouched", () => { + expect( + HeliconeTemplateManager.substituteVariables( + "You have {{hc:count:number}} new messages", + { count: 5 }, + {} + ).result + ).toBe("You have 5 new messages"); + + // Missing input -> placeholder is left as-is + expect( + HeliconeTemplateManager.substituteVariables( + "Hi {{hc:name:string}}", + {}, + {} + ).result + ).toBe("Hi {{hc:name:string}}"); + }); +}); diff --git a/packages/prompts/templates.ts b/packages/prompts/templates.ts index 01a868338d..8a502de162 100644 --- a/packages/prompts/templates.ts +++ b/packages/prompts/templates.ts @@ -129,7 +129,7 @@ export class HeliconeTemplateManager { TEMPLATE_REGEX.lastIndex = 0; result = result.replace(TEMPLATE_REGEX, (match, name) => { const value = name.trim() in inputs ? inputs[name.trim()] : undefined; - return value ? String(value) : match; + return value !== undefined && value !== null ? String(value) : match; }); return {