Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions langchain-core/src/prompts/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -642,11 +642,13 @@ class _StringImageMessagePromptTemplate<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
additionalContentFields = prompt.additionalContentFields as any;
}
content.push({
...additionalContentFields,
type: "text",
text: formatted,
});
if (formatted !== "") {
content.push({
...additionalContentFields,
type: "text",
text: formatted,
});
}
/** @TODO replace this */
// eslint-disable-next-line no-instanceof/no-instanceof
} else if (prompt instanceof ImagePromptTemplate) {
Expand Down
281 changes: 281 additions & 0 deletions langchain-core/src/prompts/tests/chat.mustache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AIMessage } from "../../messages/ai.js";
import { HumanMessage } from "../../messages/human.js";
import { SystemMessage } from "../../messages/system.js";
import { ChatPromptTemplate, HumanMessagePromptTemplate } from "../chat.js";
import { load } from "../../load/index.js";

test("Test creating a chat prompt template from role string messages", async () => {
const template = ChatPromptTemplate.fromMessages(
Expand Down Expand Up @@ -199,3 +200,283 @@ test("with ChatPromptTemplate", async () => {
`System: ${expectedResult}`
);
});

test("Rendering a prompt with conditionals doesn't result in empty text blocks", async () => {
const manifest = {
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "chat", "ChatPromptTemplate"],
kwargs: {
messages: [
{
lc: 1,
type: "constructor",
id: [
"langchain_core",
"prompts",
"chat",
"SystemMessagePromptTemplate",
],
kwargs: {
prompt: {
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: [],
template_format: "mustache",
template: "Always echo back whatever I send you.",
},
},
},
},
{
lc: 1,
type: "constructor",
id: [
"langchain_core",
"prompts",
"chat",
"HumanMessagePromptTemplate",
],
kwargs: {
prompt: [
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: [],
template_format: "mustache",
template: "Here is the teacher's prompt:",
additional_content_fields: {
text: "Here is the teacher's prompt:",
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: ["promptDescription"],
template_format: "mustache",
template: '"{{promptDescription}}"\n',
additional_content_fields: {
text: '"{{promptDescription}}"\n',
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: [],
template_format: "mustache",
template:
"Here is the expected answer or success criteria given by the teacher:",
additional_content_fields: {
text: "Here is the expected answer or success criteria given by the teacher:",
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: ["expectedResponse"],
template_format: "mustache",
template: '"{{expectedResponse}}"\n',
additional_content_fields: {
text: '"{{expectedResponse}}"\n',
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: [],
template_format: "mustache",
template:
"Note: This may be just one example many possible correct ways for the student to respond.\n",
additional_content_fields: {
text: "Note: This may be just one example many possible correct ways for the student to respond.\n",
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: [],
template_format: "mustache",
template: "For your evaluation of the student's response:\n",
additional_content_fields: {
text: "For your evaluation of the student's response:\n",
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: [],
template_format: "mustache",
template:
"Here is a transcript of the student's explanation:",
additional_content_fields: {
text: "Here is a transcript of the student's explanation:",
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: ["responseTranscript"],
template_format: "mustache",
template: '"{{responseTranscript}}"\n',
additional_content_fields: {
text: '"{{responseTranscript}}"\n',
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: ["readingFluencyAnalysis"],
template_format: "mustache",
template:
"{{#readingFluencyAnalysis}} For this task, the student's reading pronunciation and fluency were important. Here is analysis of the student's oral response: \"{{readingFluencyAnalysis}}\" {{/readingFluencyAnalysis}}",
additional_content_fields: {
text: "{{#readingFluencyAnalysis}} For this task, the student's reading pronunciation and fluency were important. Here is analysis of the student's oral response: \"{{readingFluencyAnalysis}}\" {{/readingFluencyAnalysis}}",
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: ["readingFluencyAnalysis"],
template_format: "mustache",
template:
"{{#readingFluencyAnalysis}}Root analysis of the student's response (step 3) in this oral analysis rather than inconsistencies in the transcript.{{/readingFluencyAnalysis}}",
additional_content_fields: {
text: "{{#readingFluencyAnalysis}}Root analysis of the student's response (step 3) in this oral analysis rather than inconsistencies in the transcript.{{/readingFluencyAnalysis}}",
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: ["readingFluencyAnalysis"],
template_format: "mustache",
template:
"{{#readingFluencyAnalysis}}Remember this is a student, so we care about general fluency - not voice acting. {{/readingFluencyAnalysis}}\n",
additional_content_fields: {
text: "{{#readingFluencyAnalysis}}Remember this is a student, so we care about general fluency - not voice acting. {{/readingFluencyAnalysis}}\n",
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: ["multipleChoiceAnalysis"],
template_format: "mustache",
template:
"{{#multipleChoiceAnalysis}}Here is an analysis of the student's multiple choice response: {{multipleChoiceAnalysis}}{{/multipleChoiceAnalysis}}\n",
additional_content_fields: {
text: "{{#multipleChoiceAnalysis}}Here is an analysis of the student's multiple choice response: {{multipleChoiceAnalysis}}{{/multipleChoiceAnalysis}}\n",
},
},
},
{
lc: 1,
type: "constructor",
id: ["langchain_core", "prompts", "prompt", "PromptTemplate"],
kwargs: {
input_variables: [],
template_format: "mustache",
template: "Here is the student's whiteboard:\n",
additional_content_fields: {
text: "Here is the student's whiteboard:\n",
},
},
},
{
lc: 1,
type: "constructor",
id: [
"langchain_core",
"prompts",
"image",
"ImagePromptTemplate",
],
kwargs: {
template: {
url: "{{whiteboard}}",
},
input_variables: ["whiteboard"],
template_format: "mustache",
additional_content_fields: {
image_url: {
url: "{{whiteboard}}",
},
},
},
},
],
additional_options: {},
},
},
],
input_variables: [
"promptDescription",
"expectedResponse",
"responseTranscript",
"readingFluencyAnalysis",
"readingFluencyAnalysis",
"readingFluencyAnalysis",
"multipleChoiceAnalysis",
"whiteboard",
],
template_format: "mustache",
metadata: {
lc_hub_owner: "jacob",
lc_hub_repo: "mustache-conditionals",
lc_hub_commit_hash:
"836ad82d512409ea6024fb760b76a27ba58fc68b1179656c0ba2789778686d46",
},
},
};
const prompt = await load<ChatPromptTemplate>(JSON.stringify(manifest));
const res = await prompt.invoke({
promptDescription: "What is the capital of the USA?",
expectedResponse: "Washington, D.C.",
responseTranscript: "Washington, D.C.",
readingFluencyAnalysis: undefined,
multipleChoiceAnalysis: "testing2",
whiteboard: "https://foo.com/bar.png",
});
const content = res.messages[1].content;
expect(Array.isArray(content)).toBe(true);
const emptyTextBlocks = (content as Record<string, unknown>[]).filter(
(block: Record<string, unknown>) =>
block.type === "text" && block.text === ""
);
expect(emptyTextBlocks.length).toBe(0);
});
Loading