-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
custom_format.ts
101 lines (92 loc) · 3.17 KB
/
custom_format.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import type { InputValues } from "@langchain/core/utils/types";
import {
type ParsedFStringNode,
PromptTemplate,
type PromptTemplateInput,
TypedPromptInputValues,
} from "@langchain/core/prompts";
export type CustomFormatPromptTemplateInput<RunInput extends InputValues> =
Omit<PromptTemplateInput<RunInput, string>, "templateFormat"> & {
customParser: (template: string) => ParsedFStringNode[];
templateValidator?: (template: string, inputVariables: string[]) => boolean;
renderer: (template: string, values: InputValues) => string;
};
export class CustomFormatPromptTemplate<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
RunInput extends InputValues = any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
PartialVariableName extends string = any
> extends PromptTemplate<RunInput, PartialVariableName> {
static lc_name() {
return "CustomPromptTemplate";
}
lc_serializable = false;
templateValidator?: (template: string, inputVariables: string[]) => boolean;
renderer: (template: string, values: InputValues) => string;
constructor(input: CustomFormatPromptTemplateInput<RunInput>) {
super(input);
Object.assign(this, input);
if (this.validateTemplate && this.templateValidator !== undefined) {
let totalInputVariables: string[] = this.inputVariables;
if (this.partialVariables) {
totalInputVariables = totalInputVariables.concat(
Object.keys(this.partialVariables)
);
}
if (typeof this.template === "string") {
this.templateValidator(this.template, totalInputVariables);
} else {
throw new Error(
`Must pass in string as template. Received: ${this.template}`
);
}
}
}
/**
* Load prompt template from a template
*/
static fromTemplate<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
RunInput extends InputValues = Record<string, any>
>(
template: string,
{
customParser,
...rest
}: Omit<
CustomFormatPromptTemplateInput<RunInput>,
"template" | "inputVariables"
>
) {
const names = new Set<string>();
const nodes = customParser(template);
for (const node of nodes) {
if (node.type === "variable") {
names.add(node.name);
}
}
// eslint-disable-next-line @typescript-eslint/ban-types
return new this<RunInput extends Symbol ? never : RunInput>({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
inputVariables: [...names] as any[],
template,
customParser,
...rest,
});
}
/**
* Formats the prompt template with the provided values.
* @param values The values to be used to format the prompt template.
* @returns A promise that resolves to a string which is the formatted prompt.
*/
async format(values: TypedPromptInputValues<RunInput>): Promise<string> {
const allValues = await this.mergePartialAndUserVariables(values);
if (typeof this.template === "string") {
return this.renderer(this.template, allValues);
} else {
throw new Error(
`Must pass in string as template. Received: ${this.template}`
);
}
}
}