-
Notifications
You must be signed in to change notification settings - Fork 412
Expand file tree
/
Copy pathtypechat.ts
More file actions
101 lines (78 loc) · 2.85 KB
/
typechat.ts
File metadata and controls
101 lines (78 loc) · 2.85 KB
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 { Result, error } from "./result";
import { TypeChatLanguageModel } from "./model";
import { TypeChatJsonValidator, createJsonValidator } from "./validate";
interface TypeChatJsonTranslator<T extends object> {
model: TypeChatLanguageModel;
validator: TypeChatJsonValidator<T>;
attemptRepair: boolean;
stripNulls: boolean;
createRequestPrompt: (naturalLanguageRequest: string) => string;
createRepairPrompt: (validationError: string) => string;
translate: (naturalLanguageRequest: string) => Promise<Result<T>>;
}
function createJsonTranslator<T extends object>(
model: TypeChatLanguageModel,
schema: string,
typeName: string
): TypeChatJsonTranslator<T> {
const validator = createJsonValidator<T>(schema, typeName);
const translator: TypeChatJsonTranslator<T> = {
model,
validator,
attemptRepair: true,
stripNulls: false,
createRequestPrompt(naturalLanguageRequest) {
return `
You are a service that translates user requests into JSON objects of type "${this.validator.typeName}" according to the following TypeScript definitions:
\`\`\`
${this.validator.schema}
\`\`\`
The following is a user request:
"""
${naturalLanguageRequest}
"""
The following is the user request translated into a JSON object with 2 spaces of indentation and no properties with the value undefined:
`;
},
createRepairPrompt(validationError) {
return `
The JSON object is invalid for the following reason:
"""
${validationError}
"""
The following is a revised JSON object:
`;
},
async translate(naturalLanguageRequest) {
let prompt = this.createRequestPrompt(naturalLanguageRequest);
let attemptRepair = this.attemptRepair;
while (true) {
const response = await this.model.complete(prompt);
if (!response.success) {
return response;
}
const aiResponseText = response.data;
const startIndex = aiResponseText.indexOf("{");
const endIndex = aiResponseText.lastIndexOf("}");
if (startIndex == -1 || endIndex == -1 || startIndex >= endIndex) {
// invalid JSON, return error
}
const parsedJsonText = aiResponseText.slice(startIndex, endIndex + 1);
const validation = this.validator.validate(parsedJsonText);
if (validation.success) {
return validation;
}
if (!attemptRepair) {
return error(
`JSON validation failed: ${validation.message}\n${parsedJsonText}`
);
}
prompt += `${aiResponseText}\n${this.createRepairPrompt(
validation.message
)}`;
attemptRepair = false;
}
},
};
return translator;
}