@jackhua/mini-langchain
Version:
A lightweight TypeScript implementation of LangChain with cost optimization features
184 lines (179 loc) • 5.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PromptTemplates = exports.ChatPromptTemplate = exports.PromptTemplate = void 0;
/**
* A prompt template for a language model.
*
* A prompt template consists of a string template with variables that can be formatted.
*
* Example:
* ```typescript
* const template = new PromptTemplate({
* template: "Tell me a {adjective} joke about {topic}",
* inputVariables: ["adjective", "topic"]
* });
*
* const prompt = template.format({
* adjective: "funny",
* topic: "chickens"
* });
* // Result: "Tell me a funny joke about chickens"
* ```
*/
class PromptTemplate {
constructor(config) {
this.template = config.template;
this.inputVariables = config.inputVariables;
this.partialVariables = config.partialVariables || {};
if (!config.skipValidation) {
this.validateTemplate();
}
}
/**
* Validate that all variables in the template are accounted for
*/
validateTemplate() {
const templateVars = this.extractVariables(this.template);
const allInputVars = new Set([
...this.inputVariables,
...Object.keys(this.partialVariables)
]);
for (const variable of templateVars) {
if (!allInputVars.has(variable)) {
throw new Error(`Variable "${variable}" found in template but not in inputVariables or partialVariables`);
}
}
}
/**
* Extract variables from a template string
*/
extractVariables(template) {
const regex = /\{([^}]+)\}/g;
const variables = [];
let match;
while ((match = regex.exec(template)) !== null) {
variables.push(match[1]);
}
return [...new Set(variables)];
}
/**
* Format the prompt with the given values
*/
format(values) {
// Merge with partial variables
const allValues = { ...this.partialVariables, ...values };
// Check that all required variables are provided
for (const variable of this.inputVariables) {
if (!(variable in allValues)) {
throw new Error(`Missing value for input variable "${variable}"`);
}
}
// Replace variables in template
let formatted = this.template;
for (const [key, value] of Object.entries(allValues)) {
const regex = new RegExp(`\\{${key}\\}`, 'g');
formatted = formatted.replace(regex, String(value));
}
return formatted;
}
/**
* Partial format - create a new template with some variables already filled
*/
partial(values) {
const newPartialVariables = { ...this.partialVariables, ...values };
const newInputVariables = this.inputVariables.filter(variable => !(variable in values));
return new PromptTemplate({
template: this.template,
inputVariables: newInputVariables,
partialVariables: newPartialVariables
});
}
/**
* Create a prompt template from a string with automatic variable detection
*/
static fromTemplate(template) {
// Create a temporary instance just to extract variables
const tempInstance = new PromptTemplate({
template,
inputVariables: [],
partialVariables: {},
skipValidation: true // Skip validation during variable extraction
});
// Extract variables from the template
const variables = tempInstance.extractVariables(template);
// Now create the real instance with proper variables
return new PromptTemplate({
template,
inputVariables: variables
});
}
}
exports.PromptTemplate = PromptTemplate;
class ChatPromptTemplate {
constructor(messages) {
this.messages = messages.map(([role, template]) => ({
role,
template: typeof template === 'string'
? new PromptTemplate({ template, inputVariables: [] })
: template
}));
}
/**
* Format the chat prompt with the given values
*/
format(values) {
const formattedMessages = this.messages.map(({ role, template }) => ({
role,
content: typeof template === 'string'
? template
: template.format(values)
}));
return { messages: formattedMessages };
}
/**
* Create a chat prompt template from messages
*/
static fromMessages(messages) {
const templateMessages = messages.map(([role, template]) => {
const promptTemplate = PromptTemplate.fromTemplate(template);
return [role, promptTemplate];
});
return new ChatPromptTemplate(templateMessages);
}
}
exports.ChatPromptTemplate = ChatPromptTemplate;
/**
* Common prompt templates
*/
class PromptTemplates {
/**
* A few-shot learning prompt
*/
static fewShot(examples, suffix) {
const exampleStrings = examples.map(ex => `Input: ${ex.input}\nOutput: ${ex.output}`).join('\n\n');
const template = `${exampleStrings}\n\nInput: {input}\nOutput:`;
return PromptTemplate.fromTemplate(template);
}
}
exports.PromptTemplates = PromptTemplates;
/**
* A simple question-answering prompt
*/
PromptTemplates.QA = PromptTemplate.fromTemplate(`Answer the question based on the context below.
Context: {context}
Question: {question}
Answer:`);
/**
* A summarization prompt
*/
PromptTemplates.SUMMARIZE = PromptTemplate.fromTemplate(`Summarize the following text concisely:
{text}
Summary:`);
/**
* A chat conversation prompt
*/
PromptTemplates.CHAT = ChatPromptTemplate.fromMessages([
['system', 'You are a helpful assistant.'],
['human', '{input}']
]);
//# sourceMappingURL=prompt.js.map