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

type ImageGenerationInput = [string, string, number, boolean, number, number, number, number];
type ImageGenerationOutput = [GradioImage, unknown];

const imageGeneration: BackendTool = {
	name: "image_generation",
	displayName: "Image Generation",
	description: "Use this tool to generate an image from a prompt.",
	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,
		},
		negativePrompt: {
			description:
				"A prompt for things that should not be in the image. Simple terms, separate terms with a comma.",
			type: "string",
			required: false,
			default: "",
		},
		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, negativePrompt, width, height }, { conv, ip, username }) {
		const ipToken = await getIpToken(ip, username);

		const outputs = await callSpace<ImageGenerationInput, ImageGenerationOutput>(
			"stabilityai/stable-diffusion-3-medium",
			"/infer",
			[
				String(prompt), // prompt
				String(negativePrompt), // negative prompt
				Math.floor(Math.random() * 1000), // seed random
				true, // randomize seed
				Number(width), // number in 'Image Width' Number component
				Number(height), // number in 'Image Height' Number component
				5, // guidance scale
				28, // steps
			],
			ipToken
		);
		const image = await fetch(outputs[0].url)
			.then((res) => res.blob())
			.then(
				(blob) =>
					new File([blob], `${prompt}.${blob.type.split("/")[1] ?? "png"}`, { type: blob.type })
			)
			.then((file) => uploadFile(file, conv));

		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;