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
121
122
123
124
125
126
|
import { ClientUtils } from "../../../../../../ClientUtils";
import { Networking } from "../../../../../Network";
import { gptImageCall, gptAPICall, GPTCallType } from "../../../../../apis/gpt/GPT";
import { Col } from "../DocCreatorMenu";
import { TemplateFieldSize, TemplateFieldType } from "../TemplateBackend";
import { TemplateField, ViewType } from "../TemplateFieldTypes/TemplateField";
import { Template } from "../Template";
export class TemplateMenuAIUtils {
public static generateGPTImage = async (prompt: string): Promise<string | undefined> => {
try {
const res = await gptImageCall(prompt);
if (res) {
const result = (await Networking.PostToServer('/uploadRemoteImage', { sources: res })) as Upload.FileInformation[];
const source = ClientUtils.prepend(result[0].accessPaths.agnostic.client);
return source;
}
} catch (e) {
console.log(e);
}
};
public static renderGPTImageCall = async (template: Template, col: Col, fieldNumber: number): Promise<boolean> => {
const generateAndLoadImage = async (id: number, prompt: string) => {
const url = await this.generateGPTImage(prompt);
// eslint-disable-next-line
var field: TemplateField = template.getFieldByID(id);
field.setContent(url ?? '', ViewType.IMG);
field = template.getFieldByID(id);
field.setTitle(col.title);
};
const fieldContent: string = template.compiledContent;
try {
const sysPrompt =
`#${Math.random() * 100}: Your job is to create a prompt for an AI image generator to help it generate an image based on existing content in a template and a user prompt. Your prompt should focus heavily on visual elements to help the image generator; avoid unecessary info that might distract it. ONLY INCLUDE THE PROMPT, NO OTHER TEXT OR EXPLANATION. The existing content is as follows: ` +
fieldContent +
' **** The user prompt is: ' +
col.desc;
const prompt = await gptAPICall(sysPrompt, GPTCallType.COMPLETEPROMPT);
await generateAndLoadImage(fieldNumber, prompt);
} catch (e) {
console.log(e);
}
return true;
};
public static renderGPTTextCall = async (template: Template, col: Col, fieldNum: number | undefined): Promise<boolean> => {
const wordLimit = (size: TemplateFieldSize) => {
switch (size) {
case TemplateFieldSize.TINY:
return 2;
case TemplateFieldSize.SMALL:
return 5;
case TemplateFieldSize.MEDIUM:
return 20;
case TemplateFieldSize.LARGE:
return 50;
case TemplateFieldSize.HUGE:
return 100;
default:
return 10;
}
};
const textAssignment = `--- title: ${col.title}, prompt: ${col.desc}, word limit: ${wordLimit(col.sizes[0])} words, assigned field: ${fieldNum} ---`;
const fieldContent: string = template.compiledContent;
try {
const prompt = fieldContent + textAssignment;
const res = await gptAPICall(`${Math.random() * 100000}: ${prompt}`, GPTCallType.FILL);
if (res) {
const assignments: { [title: string]: { number: string; content: string } } = JSON.parse(res);
Object.entries(assignments).forEach(([, /* title */ info]) => {
const field: TemplateField = template.getFieldByID(Number(info.number));
field.setContent(info.content ?? '', ViewType.TEXT);
field.setTitle(col.title);
});
}
} catch (err) {
console.log(err);
}
return true;
};
/**
* Populates a preset template framework with content from a datavizbox or any AI-generated content.
* @param template the preloaded template framework being filled in
* @param assignments a list of template field numbers (from top to bottom) and their assigned columns from the linked dataviz
* @returns a doc containing the fully rendered template
*/
public static applyGPTContentToTemplate = async (template: Template, assignments: { [field: string]: Col }): Promise<Template | undefined> => {
const GPTTextCalls = Object.entries(assignments).filter(([, col]) => col.type === TemplateFieldType.TEXT && col.AIGenerated);
const GPTIMGCalls = Object.entries(assignments).filter(([, col]) => col.type === TemplateFieldType.VISUAL && col.AIGenerated);
if (GPTTextCalls.length) {
const promises = GPTTextCalls.map(([id, col]) => {
return TemplateMenuAIUtils.renderGPTTextCall(template, col, Number(id));
});
await Promise.all(promises);
}
if (GPTIMGCalls.length) {
const promises = GPTIMGCalls.map(async ([id, col]) => {
return TemplateMenuAIUtils.renderGPTImageCall(template, col, Number(id));
});
await Promise.all(promises);
}
return template;
};
}
|