closr
Browse files
src/lib/components/MonsterGenerator/MonsterGenerator.svelte
CHANGED
@@ -20,24 +20,35 @@
|
|
20 |
});
|
21 |
|
22 |
// Prompt templates
|
23 |
-
const MONSTER_CONCEPT_PROMPT = (caption: string) => `User: Based on this
|
24 |
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
- Physical appearance and distinguishing features
|
27 |
- Special abilities or powers
|
28 |
- Personality traits
|
29 |
- Habitat or origin
|
30 |
|
31 |
-
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
const IMAGE_GENERATION_PROMPT = (concept: string) => `User: Convert this monster concept into a detailed image generation prompt:
|
36 |
"${concept}"
|
37 |
|
38 |
-
|
39 |
|
40 |
-
Assistant
|
41 |
|
42 |
async function handleImageSelected(file: File) {
|
43 |
if (!joyCaptionClient || !rwkvClient || !fluxClient) {
|
@@ -113,8 +124,8 @@ Assistant:`;
|
|
113 |
const output = await rwkvClient.predict(0, [
|
114 |
conceptPrompt,
|
115 |
300, // maxTokens
|
116 |
-
1.
|
117 |
-
0.
|
118 |
0.1, // presencePenalty
|
119 |
0.1 // countPenalty
|
120 |
]);
|
@@ -140,10 +151,10 @@ Assistant:`;
|
|
140 |
console.log('Generating image prompt from concept');
|
141 |
|
142 |
const output = await rwkvClient.predict(0, [
|
143 |
-
promptGenerationPrompt
|
144 |
-
|
145 |
-
0
|
146 |
-
0.
|
147 |
0.1, // presencePenalty
|
148 |
0.1 // countPenalty
|
149 |
]);
|
|
|
20 |
});
|
21 |
|
22 |
// Prompt templates
|
23 |
+
const MONSTER_CONCEPT_PROMPT = (caption: string) => `User: Based on this image caption: "${caption}"
|
24 |
|
25 |
+
Come up with a monster idea (in the vein of Pokémon) that incorporates properties of what the pictured object is.
|
26 |
+
Assess how unique the pictured object is. If the image is not very unique then it should result in weak & common monster.
|
27 |
+
Meanwhile if the image is very unique the monster should be unique and powerful.
|
28 |
+
|
29 |
+
Create a creature that reflects the essence, materials, function, and characteristics of the object. Consider:
|
30 |
+
- What the object is made of (metal, wood, fabric, etc.)
|
31 |
+
- How it functions or is used
|
32 |
+
- Its physical properties (hard, soft, hot, cold, etc.)
|
33 |
+
- Its cultural or symbolic meaning
|
34 |
+
- Its shape, texture, and visual characteristics
|
35 |
+
|
36 |
+
The monster should have unique strengths and weaknesses based on these properties.
|
37 |
+
|
38 |
+
Include:
|
39 |
- Physical appearance and distinguishing features
|
40 |
- Special abilities or powers
|
41 |
- Personality traits
|
42 |
- Habitat or origin
|
43 |
|
44 |
+
Assistant: **Monster Name:**`;
|
45 |
|
46 |
+
const IMAGE_GENERATION_PROMPT = (concept: string) => `User: Convert this monster concept into a clear and succinct image generation prompt:
|
|
|
|
|
47 |
"${concept}"
|
48 |
|
49 |
+
Describe the appearance of the monsters being sure to include all of its visual details, format the prompt as a single long sentence optimized for image generation.
|
50 |
|
51 |
+
Assistant: The`;
|
52 |
|
53 |
async function handleImageSelected(file: File) {
|
54 |
if (!joyCaptionClient || !rwkvClient || !fluxClient) {
|
|
|
124 |
const output = await rwkvClient.predict(0, [
|
125 |
conceptPrompt,
|
126 |
300, // maxTokens
|
127 |
+
1.0, // temperature
|
128 |
+
0.3, // topP
|
129 |
0.1, // presencePenalty
|
130 |
0.1 // countPenalty
|
131 |
]);
|
|
|
151 |
console.log('Generating image prompt from concept');
|
152 |
|
153 |
const output = await rwkvClient.predict(0, [
|
154 |
+
`${promptGenerationPrompt}\nNow generate an Anime-style image of the monster in an idle pose with a transparent background. The monster should not be attacking or in motion. The full monster must be visible within the frame.`,
|
155 |
+
300, // maxTokens
|
156 |
+
1.0, // temperature
|
157 |
+
0.3, // topP
|
158 |
0.1, // presencePenalty
|
159 |
0.1 // countPenalty
|
160 |
]);
|
structured_output.py
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# ruff: noqa: E501
|
2 |
+
|
3 |
+
import json
|
4 |
+
|
5 |
+
from pydantic import BaseModel
|
6 |
+
|
7 |
+
STRUCTURED_OUTPUT_FORMAT_INSTRUCTIONS = """The output should be formatted as a JSON instance that conforms to the JSON schema below.
|
8 |
+
|
9 |
+
As an example, for the schema {{"properties": {{"foo": {{"title": "Foo", "description": "a list of strings", "type": "array", "items": {{"type": "string"}}}}}}, "required": ["foo"]}}
|
10 |
+
the object {{"foo": ["bar", "baz"]}} is a well-formatted instance of the schema. The object {{"properties": {{"foo": ["bar", "baz"]}}}} is not well-formatted.
|
11 |
+
|
12 |
+
Here is the output schema:
|
13 |
+
```
|
14 |
+
{schema}
|
15 |
+
```"""
|
16 |
+
|
17 |
+
|
18 |
+
class StructuredOutputParser(BaseModel):
|
19 |
+
pydantic_class: type[BaseModel]
|
20 |
+
|
21 |
+
def get_schema(self, indent: int = 2) -> str:
|
22 |
+
# Copy schema to avoid altering original Pydantic schema.
|
23 |
+
schema = self.pydantic_class.model_json_schema()
|
24 |
+
# Iterate over fields to remove from the schema
|
25 |
+
for field_name in ["title", "type"]:
|
26 |
+
if field_name in schema:
|
27 |
+
schema.pop(field_name)
|
28 |
+
return json.dumps(schema, indent=indent, ensure_ascii=False)
|
29 |
+
|
30 |
+
def get_format_instructions(self) -> str:
|
31 |
+
schema_str = self.get_schema()
|
32 |
+
# Ensure json in context is well-formed with double quotes.
|
33 |
+
return STRUCTURED_OUTPUT_FORMAT_INSTRUCTIONS.format(schema=schema_str)
|
34 |
+
|
35 |
+
def parse(self, json_string: str) -> BaseModel:
|
36 |
+
return self.pydantic_class.model_validate_json(json_string)
|