error handling
Browse files
src/lib/components/MonsterGenerator/MonsterGenerator.svelte
CHANGED
|
@@ -83,12 +83,49 @@ Assistant:`;
|
|
| 83 |
state.currentStep = 'complete';
|
| 84 |
} catch (err) {
|
| 85 |
console.error('Workflow error:', err);
|
| 86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
} finally {
|
| 88 |
state.isProcessing = false;
|
| 89 |
}
|
| 90 |
}
|
| 91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
async function captionImage() {
|
| 93 |
state.currentStep = 'captioning';
|
| 94 |
|
|
@@ -96,18 +133,22 @@ Assistant:`;
|
|
| 96 |
throw new Error('Caption service not available or no image provided');
|
| 97 |
}
|
| 98 |
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
}
|
| 112 |
|
| 113 |
async function generateMonsterConcept() {
|
|
@@ -121,21 +162,25 @@ Assistant:`;
|
|
| 121 |
|
| 122 |
console.log('Generating monster concept with prompt:', conceptPrompt);
|
| 123 |
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
}
|
| 140 |
}
|
| 141 |
|
|
@@ -150,21 +195,25 @@ Assistant:`;
|
|
| 150 |
|
| 151 |
console.log('Generating image prompt from concept');
|
| 152 |
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
}
|
| 169 |
}
|
| 170 |
|
|
@@ -175,30 +224,34 @@ Assistant:`;
|
|
| 175 |
throw new Error('Image generation service not available or no prompt');
|
| 176 |
}
|
| 177 |
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
}
|
| 203 |
}
|
| 204 |
|
|
|
|
| 83 |
state.currentStep = 'complete';
|
| 84 |
} catch (err) {
|
| 85 |
console.error('Workflow error:', err);
|
| 86 |
+
|
| 87 |
+
// Check for GPU quota error
|
| 88 |
+
if (err && typeof err === 'object' && 'message' in err) {
|
| 89 |
+
const errorMessage = String(err.message);
|
| 90 |
+
if (errorMessage.includes('exceeded your GPU quota') || errorMessage.includes('GPU quota')) {
|
| 91 |
+
state.error = 'GPU quota exceeded! You need to sign in with Hugging Face for free GPU time, or upgrade to Hugging Face Pro for more quota.';
|
| 92 |
+
} else {
|
| 93 |
+
state.error = errorMessage;
|
| 94 |
+
}
|
| 95 |
+
} else if (err instanceof Error) {
|
| 96 |
+
state.error = err.message;
|
| 97 |
+
} else {
|
| 98 |
+
state.error = 'An unknown error occurred';
|
| 99 |
+
}
|
| 100 |
} finally {
|
| 101 |
state.isProcessing = false;
|
| 102 |
}
|
| 103 |
}
|
| 104 |
|
| 105 |
+
function handleAPIError(error: any): never {
|
| 106 |
+
console.error('API Error:', error);
|
| 107 |
+
|
| 108 |
+
// Check if it's a GPU quota error
|
| 109 |
+
if (error && typeof error === 'object' && 'message' in error) {
|
| 110 |
+
const errorMessage = String(error.message);
|
| 111 |
+
if (errorMessage.includes('exceeded your GPU quota') || errorMessage.includes('GPU quota')) {
|
| 112 |
+
throw new Error('GPU quota exceeded! You need to sign in with Hugging Face for free GPU time, or upgrade to Hugging Face Pro for more quota.');
|
| 113 |
+
}
|
| 114 |
+
throw new Error(errorMessage);
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// Check if error has a different structure (like the status object from the logs)
|
| 118 |
+
if (error && typeof error === 'object' && 'type' in error && error.type === 'status') {
|
| 119 |
+
const statusError = error as any;
|
| 120 |
+
if (statusError.message && statusError.message.includes('GPU quota')) {
|
| 121 |
+
throw new Error('GPU quota exceeded! You need to sign in with Hugging Face for free GPU time, or upgrade to Hugging Face Pro for more quota.');
|
| 122 |
+
}
|
| 123 |
+
throw new Error(statusError.message || 'API request failed');
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
throw error;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
async function captionImage() {
|
| 130 |
state.currentStep = 'captioning';
|
| 131 |
|
|
|
|
| 133 |
throw new Error('Caption service not available or no image provided');
|
| 134 |
}
|
| 135 |
|
| 136 |
+
try {
|
| 137 |
+
const output = await joyCaptionClient.predict("/stream_chat", [
|
| 138 |
+
state.userImage,
|
| 139 |
+
"Descriptive" as CaptionType,
|
| 140 |
+
"very long" as CaptionLength,
|
| 141 |
+
[], // extra_options
|
| 142 |
+
"", // name_input
|
| 143 |
+
"" // custom_prompt
|
| 144 |
+
]);
|
| 145 |
+
|
| 146 |
+
const [prompt, caption] = output.data;
|
| 147 |
+
state.imageCaption = caption;
|
| 148 |
+
console.log('Caption generated:', caption);
|
| 149 |
+
} catch (error) {
|
| 150 |
+
handleAPIError(error);
|
| 151 |
+
}
|
| 152 |
}
|
| 153 |
|
| 154 |
async function generateMonsterConcept() {
|
|
|
|
| 162 |
|
| 163 |
console.log('Generating monster concept with prompt:', conceptPrompt);
|
| 164 |
|
| 165 |
+
try {
|
| 166 |
+
const output = await rwkvClient.predict(0, [
|
| 167 |
+
conceptPrompt,
|
| 168 |
+
300, // maxTokens
|
| 169 |
+
0.7, // temperature
|
| 170 |
+
0.8, // topP
|
| 171 |
+
0.1, // presencePenalty
|
| 172 |
+
0.1 // countPenalty
|
| 173 |
+
]);
|
| 174 |
+
|
| 175 |
+
console.log('RWKV output:', output);
|
| 176 |
+
state.monsterConcept = output.data[0];
|
| 177 |
+
console.log('Monster concept generated:', state.monsterConcept);
|
| 178 |
+
|
| 179 |
+
if (!state.monsterConcept || state.monsterConcept.trim() === '') {
|
| 180 |
+
throw new Error('Failed to generate monster concept - received empty response');
|
| 181 |
+
}
|
| 182 |
+
} catch (error) {
|
| 183 |
+
handleAPIError(error);
|
| 184 |
}
|
| 185 |
}
|
| 186 |
|
|
|
|
| 195 |
|
| 196 |
console.log('Generating image prompt from concept');
|
| 197 |
|
| 198 |
+
try {
|
| 199 |
+
const output = await rwkvClient.predict(0, [
|
| 200 |
+
promptGenerationPrompt,
|
| 201 |
+
300, // maxTokens
|
| 202 |
+
0.7, // temperature
|
| 203 |
+
0.8, // topP
|
| 204 |
+
0.1, // presencePenalty
|
| 205 |
+
0.1 // countPenalty
|
| 206 |
+
]);
|
| 207 |
+
|
| 208 |
+
console.log('Image prompt output:', output);
|
| 209 |
+
state.imagePrompt = output.data[0];
|
| 210 |
+
console.log('Image prompt generated:', state.imagePrompt);
|
| 211 |
+
|
| 212 |
+
if (!state.imagePrompt || state.imagePrompt.trim() === '') {
|
| 213 |
+
throw new Error('Failed to generate image prompt - received empty response');
|
| 214 |
+
}
|
| 215 |
+
} catch (error) {
|
| 216 |
+
handleAPIError(error);
|
| 217 |
}
|
| 218 |
}
|
| 219 |
|
|
|
|
| 224 |
throw new Error('Image generation service not available or no prompt');
|
| 225 |
}
|
| 226 |
|
| 227 |
+
try {
|
| 228 |
+
const output = await fluxClient.predict("/infer", [
|
| 229 |
+
`${state.imagePrompt}\nNow generate an Anime-style image of the monster in an idle pose with a white background. The monster should not be attacking or in motion. The full monster must be visible within the frame.`,
|
| 230 |
+
0, // seed
|
| 231 |
+
true, // randomizeSeed
|
| 232 |
+
1024, // width
|
| 233 |
+
1024, // height
|
| 234 |
+
4 // steps
|
| 235 |
+
]);
|
| 236 |
+
|
| 237 |
+
const [image, usedSeed] = output.data;
|
| 238 |
+
let url: string | undefined;
|
| 239 |
+
|
| 240 |
+
if (typeof image === "string") url = image;
|
| 241 |
+
else if (image && image.url) url = image.url;
|
| 242 |
+
else if (image && image.path) url = image.path;
|
| 243 |
+
|
| 244 |
+
if (url) {
|
| 245 |
+
state.monsterImage = {
|
| 246 |
+
imageUrl: url,
|
| 247 |
+
seed: usedSeed,
|
| 248 |
+
prompt: state.imagePrompt
|
| 249 |
+
};
|
| 250 |
+
} else {
|
| 251 |
+
throw new Error('Failed to generate monster image');
|
| 252 |
+
}
|
| 253 |
+
} catch (error) {
|
| 254 |
+
handleAPIError(error);
|
| 255 |
}
|
| 256 |
}
|
| 257 |
|