File size: 2,873 Bytes
564e576
 
 
719022a
564e576
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f6440ab
719022a
 
564e576
 
 
 
 
f6440ab
 
564e576
 
719022a
 
564e576
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f6440ab
564e576
 
 
 
 
 
 
 
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
import type { BackendTool } from "..";
import { uploadFile } from "../../files/uploadFile";
import { MessageUpdateType } from "$lib/types/MessageUpdate";
import { callSpace, getIpToken, type GradioImage } from "../utils";

type ImageGenerationInput = [
	number /* number (numeric value between 1 and 8) in 'Number of Images' Slider component */,
	number /* number in 'Image Height' Number component */,
	number /* number in 'Image Width' Number component */,
	string /* prompt */,
	number /* seed random */
];
type ImageGenerationOutput = [{ image: GradioImage }[]];

const imageGeneration: BackendTool = {
	name: "image_generation",
	displayName: "Image Generation",
	description: "Use this tool to generate an image from a prompt.",
	isOnByDefault: true,
	parameterDefinitions: {
		prompt: {
			description:
				"A prompt to generate an image from. Describe the image visually in simple terms, separate terms with a comma.",
			type: "string",
			required: true,
		},
		numberOfImages: {
			description: "Number of images to generate, between 1 and 8.",
			type: "number",
			required: false,
			default: 1,
		},
		width: {
			description: "Width of the generated image.",
			type: "number",
			required: false,
			default: 1024,
		},
		height: {
			description: "Height of the generated image.",
			type: "number",
			required: false,
			default: 1024,
		},
	},
	async *call({ prompt, numberOfImages, width, height }, { conv, ip, username }) {
		const ipToken = await getIpToken(ip, username);

		const outputs = await callSpace<ImageGenerationInput, ImageGenerationOutput>(
			"ByteDance/Hyper-SDXL-1Step-T2I",
			"/process_image",
			[
				Number(numberOfImages), // number (numeric value between 1 and 8) in 'Number of Images' Slider component
				Number(height), // number in 'Image Height' Number component
				Number(width), // number in 'Image Width' Number component
				String(prompt), // prompt
				Math.floor(Math.random() * 1000), // seed random
			],
			ipToken
		);
		const imageBlobs = await Promise.all(
			outputs[0].map((output) =>
				fetch(output.image.url)
					.then((res) => res.blob())
					.then(
						(blob) =>
							new File([blob], `${prompt}.${blob.type.split("/")[1] ?? "png"}`, { type: blob.type })
					)
					.then((file) => uploadFile(file, conv))
			)
		);

		for (const image of imageBlobs) {
			yield {
				type: MessageUpdateType.File,
				name: image.name,
				sha: image.value,
				mime: image.mime,
			};
		}

		return {
			outputs: [
				{
					imageGeneration: `An image has been generated for the following prompt: "${prompt}". Answer as if the user can already see the image. Do not try to insert the image or to add space for it. The user can already see the image. Do not try to describe the image as you the model cannot see it. Be concise.`,
				},
			],
			display: false,
		};
	},
};

export default imageGeneration;