-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
memory.ts
120 lines (111 loc) · 4.12 KB
/
memory.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* Type alias for a record where the keys are strings and the values can
* be any type. This is used to represent the input values for a Chain.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type InputValues = Record<string, any>;
/**
* Type alias for a record where the keys are strings and the values can
* be any type. This is used to represent the output values from a Chain.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type OutputValues = Record<string, any>;
/**
* Type alias for a record where the keys are strings and the values can
* be any type. This is used to represent the memory variables in a Chain.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type MemoryVariables = Record<string, any>;
/**
* Abstract base class for memory in LangChain's Chains. Memory refers to
* the state in Chains. It can be used to store information about past
* executions of a Chain and inject that information into the inputs of
* future executions of the Chain.
*/
export abstract class BaseMemory {
abstract get memoryKeys(): string[];
/**
* Abstract method that should take an object of input values and return a
* Promise that resolves with an object of memory variables. The
* implementation of this method should load the memory variables from the
* provided input values.
* @param values An object of input values.
* @returns Promise that resolves with an object of memory variables.
*/
abstract loadMemoryVariables(values: InputValues): Promise<MemoryVariables>;
/**
* Abstract method that should take two objects, one of input values and
* one of output values, and return a Promise that resolves when the
* context has been saved. The implementation of this method should save
* the context based on the provided input and output values.
* @param inputValues An object of input values.
* @param outputValues An object of output values.
* @returns Promise that resolves when the context has been saved.
*/
abstract saveContext(
inputValues: InputValues,
outputValues: OutputValues
): Promise<void>;
}
const getValue = (values: InputValues | OutputValues, key?: string) => {
if (key !== undefined) {
return values[key];
}
const keys = Object.keys(values);
if (keys.length === 1) {
return values[keys[0]];
}
};
/**
* This function is used by memory classes to select the input value
* to use for the memory. If there is only one input value, it is used.
* If there are multiple input values, the inputKey must be specified.
*/
export const getInputValue = (inputValues: InputValues, inputKey?: string) => {
const value = getValue(inputValues, inputKey);
if (!value) {
const keys = Object.keys(inputValues);
throw new Error(
`input values have ${keys.length} keys, you must specify an input key or pass only 1 key as input`
);
}
return value;
};
/**
* This function is used by memory classes to select the output value
* to use for the memory. If there is only one output value, it is used.
* If there are multiple output values, the outputKey must be specified.
* If no outputKey is specified, an error is thrown.
*/
export const getOutputValue = (
outputValues: OutputValues,
outputKey?: string
) => {
const value = getValue(outputValues, outputKey);
if (!value) {
const keys = Object.keys(outputValues);
throw new Error(
`output values have ${keys.length} keys, you must specify an output key or pass only 1 key as output`
);
}
return value;
};
/**
* Function used by memory classes to get the key of the prompt input,
* excluding any keys that are memory variables or the "stop" key. If
* there is not exactly one prompt input key, an error is thrown.
*/
export function getPromptInputKey(
inputs: Record<string, unknown>,
memoryVariables: string[]
): string {
const promptInputKeys = Object.keys(inputs).filter(
(key) => !memoryVariables.includes(key) && key !== "stop"
);
if (promptInputKeys.length !== 1) {
throw new Error(
`One input key expected, but got ${promptInputKeys.length}`
);
}
return promptInputKeys[0];
}