@langchain/core
Version:
Core LangChain.js abstractions and schemas
356 lines (355 loc) • 13.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FewShotChatMessagePromptTemplate = exports.FewShotPromptTemplate = void 0;
const string_js_1 = require("./string.cjs");
const template_js_1 = require("./template.cjs");
const prompt_js_1 = require("./prompt.cjs");
const chat_js_1 = require("./chat.cjs");
/**
* Prompt template that contains few-shot examples.
* @augments BasePromptTemplate
* @augments FewShotPromptTemplateInput
* @example
* ```typescript
* const examplePrompt = PromptTemplate.fromTemplate(
* "Input: {input}\nOutput: {output}",
* );
*
* const exampleSelector = await SemanticSimilarityExampleSelector.fromExamples(
* [
* { input: "happy", output: "sad" },
* { input: "tall", output: "short" },
* { input: "energetic", output: "lethargic" },
* { input: "sunny", output: "gloomy" },
* { input: "windy", output: "calm" },
* ],
* new OpenAIEmbeddings(),
* HNSWLib,
* { k: 1 },
* );
*
* const dynamicPrompt = new FewShotPromptTemplate({
* exampleSelector,
* examplePrompt,
* prefix: "Give the antonym of every input",
* suffix: "Input: {adjective}\nOutput:",
* inputVariables: ["adjective"],
* });
*
* // Format the dynamic prompt with the input 'rainy'
* console.log(await dynamicPrompt.format({ adjective: "rainy" }));
*
* ```
*/
class FewShotPromptTemplate extends string_js_1.BaseStringPromptTemplate {
constructor(input) {
super(input);
Object.defineProperty(this, "lc_serializable", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "examples", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "exampleSelector", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "examplePrompt", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "suffix", {
enumerable: true,
configurable: true,
writable: true,
value: ""
});
Object.defineProperty(this, "exampleSeparator", {
enumerable: true,
configurable: true,
writable: true,
value: "\n\n"
});
Object.defineProperty(this, "prefix", {
enumerable: true,
configurable: true,
writable: true,
value: ""
});
Object.defineProperty(this, "templateFormat", {
enumerable: true,
configurable: true,
writable: true,
value: "f-string"
});
Object.defineProperty(this, "validateTemplate", {
enumerable: true,
configurable: true,
writable: true,
value: true
});
Object.assign(this, input);
if (this.examples !== undefined && this.exampleSelector !== undefined) {
throw new Error("Only one of 'examples' and 'example_selector' should be provided");
}
if (this.examples === undefined && this.exampleSelector === undefined) {
throw new Error("One of 'examples' and 'example_selector' should be provided");
}
if (this.validateTemplate) {
let totalInputVariables = this.inputVariables;
if (this.partialVariables) {
totalInputVariables = totalInputVariables.concat(Object.keys(this.partialVariables));
}
(0, template_js_1.checkValidTemplate)(this.prefix + this.suffix, this.templateFormat, totalInputVariables);
}
}
_getPromptType() {
return "few_shot";
}
static lc_name() {
return "FewShotPromptTemplate";
}
async getExamples(inputVariables) {
if (this.examples !== undefined) {
return this.examples;
}
if (this.exampleSelector !== undefined) {
return this.exampleSelector.selectExamples(inputVariables);
}
throw new Error("One of 'examples' and 'example_selector' should be provided");
}
async partial(values) {
const newInputVariables = this.inputVariables.filter((iv) => !(iv in values));
const newPartialVariables = {
...(this.partialVariables ?? {}),
...values,
};
const promptDict = {
...this,
inputVariables: newInputVariables,
partialVariables: newPartialVariables,
};
return new FewShotPromptTemplate(promptDict);
}
/**
* Formats the prompt with the given values.
* @param values The values to format the prompt with.
* @returns A promise that resolves to a string representing the formatted prompt.
*/
async format(values) {
const allValues = await this.mergePartialAndUserVariables(values);
const examples = await this.getExamples(allValues);
const exampleStrings = await Promise.all(examples.map((example) => this.examplePrompt.format(example)));
const template = [this.prefix, ...exampleStrings, this.suffix].join(this.exampleSeparator);
return (0, template_js_1.renderTemplate)(template, this.templateFormat, allValues);
}
serialize() {
if (this.exampleSelector || !this.examples) {
throw new Error("Serializing an example selector is not currently supported");
}
if (this.outputParser !== undefined) {
throw new Error("Serializing an output parser is not currently supported");
}
return {
_type: this._getPromptType(),
input_variables: this.inputVariables,
example_prompt: this.examplePrompt.serialize(),
example_separator: this.exampleSeparator,
suffix: this.suffix,
prefix: this.prefix,
template_format: this.templateFormat,
examples: this.examples,
};
}
static async deserialize(data) {
const { example_prompt } = data;
if (!example_prompt) {
throw new Error("Missing example prompt");
}
const examplePrompt = await prompt_js_1.PromptTemplate.deserialize(example_prompt);
let examples;
if (Array.isArray(data.examples)) {
examples = data.examples;
}
else {
throw new Error("Invalid examples format. Only list or string are supported.");
}
return new FewShotPromptTemplate({
inputVariables: data.input_variables,
examplePrompt,
examples,
exampleSeparator: data.example_separator,
prefix: data.prefix,
suffix: data.suffix,
templateFormat: data.template_format,
});
}
}
exports.FewShotPromptTemplate = FewShotPromptTemplate;
/**
* Chat prompt template that contains few-shot examples.
* @augments BasePromptTemplateInput
* @augments FewShotChatMessagePromptTemplateInput
*/
class FewShotChatMessagePromptTemplate extends chat_js_1.BaseChatPromptTemplate {
_getPromptType() {
return "few_shot_chat";
}
static lc_name() {
return "FewShotChatMessagePromptTemplate";
}
constructor(fields) {
super(fields);
Object.defineProperty(this, "lc_serializable", {
enumerable: true,
configurable: true,
writable: true,
value: true
});
Object.defineProperty(this, "examples", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "exampleSelector", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "examplePrompt", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "suffix", {
enumerable: true,
configurable: true,
writable: true,
value: ""
});
Object.defineProperty(this, "exampleSeparator", {
enumerable: true,
configurable: true,
writable: true,
value: "\n\n"
});
Object.defineProperty(this, "prefix", {
enumerable: true,
configurable: true,
writable: true,
value: ""
});
Object.defineProperty(this, "templateFormat", {
enumerable: true,
configurable: true,
writable: true,
value: "f-string"
});
Object.defineProperty(this, "validateTemplate", {
enumerable: true,
configurable: true,
writable: true,
value: true
});
this.examples = fields.examples;
this.examplePrompt = fields.examplePrompt;
this.exampleSeparator = fields.exampleSeparator ?? "\n\n";
this.exampleSelector = fields.exampleSelector;
this.prefix = fields.prefix ?? "";
this.suffix = fields.suffix ?? "";
this.templateFormat = fields.templateFormat ?? "f-string";
this.validateTemplate = fields.validateTemplate ?? true;
if (this.examples !== undefined && this.exampleSelector !== undefined) {
throw new Error("Only one of 'examples' and 'example_selector' should be provided");
}
if (this.examples === undefined && this.exampleSelector === undefined) {
throw new Error("One of 'examples' and 'example_selector' should be provided");
}
if (this.validateTemplate) {
let totalInputVariables = this.inputVariables;
if (this.partialVariables) {
totalInputVariables = totalInputVariables.concat(Object.keys(this.partialVariables));
}
(0, template_js_1.checkValidTemplate)(this.prefix + this.suffix, this.templateFormat, totalInputVariables);
}
}
async getExamples(inputVariables) {
if (this.examples !== undefined) {
return this.examples;
}
if (this.exampleSelector !== undefined) {
return this.exampleSelector.selectExamples(inputVariables);
}
throw new Error("One of 'examples' and 'example_selector' should be provided");
}
/**
* Formats the list of values and returns a list of formatted messages.
* @param values The values to format the prompt with.
* @returns A promise that resolves to a string representing the formatted prompt.
*/
async formatMessages(values) {
const allValues = await this.mergePartialAndUserVariables(values);
let examples = await this.getExamples(allValues);
examples = examples.map((example) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const result = {};
this.examplePrompt.inputVariables.forEach((inputVariable) => {
result[inputVariable] = example[inputVariable];
});
return result;
});
const messages = [];
for (const example of examples) {
const exampleMessages = await this.examplePrompt.formatMessages(example);
messages.push(...exampleMessages);
}
return messages;
}
/**
* Formats the prompt with the given values.
* @param values The values to format the prompt with.
* @returns A promise that resolves to a string representing the formatted prompt.
*/
async format(values) {
const allValues = await this.mergePartialAndUserVariables(values);
const examples = await this.getExamples(allValues);
const exampleMessages = await Promise.all(examples.map((example) => this.examplePrompt.formatMessages(example)));
const exampleStrings = exampleMessages
.flat()
.map((message) => message.content);
const template = [this.prefix, ...exampleStrings, this.suffix].join(this.exampleSeparator);
return (0, template_js_1.renderTemplate)(template, this.templateFormat, allValues);
}
/**
* Partially formats the prompt with the given values.
* @param values The values to partially format the prompt with.
* @returns A promise that resolves to an instance of `FewShotChatMessagePromptTemplate` with the given values partially formatted.
*/
async partial(values) {
const newInputVariables = this.inputVariables.filter((variable) => !(variable in values));
const newPartialVariables = {
...(this.partialVariables ?? {}),
...values,
};
const promptDict = {
...this,
inputVariables: newInputVariables,
partialVariables: newPartialVariables,
};
return new FewShotChatMessagePromptTemplate(promptDict);
}
}
exports.FewShotChatMessagePromptTemplate = FewShotChatMessagePromptTemplate;