fullWebsiteCheckermain.tsx1 match
227headers: {
228"User-Agent": userAgent,
229"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
230"Accept-Language": "en-US,en;q=0.5",
231"Referer": "https://www.google.com/",
46transform: scaleX(1);
47transform-origin: center;
48background-image: linear-gradient(45deg, #ff6b6b, #feca57, #48dbfb, #ff9ff3);
49background-clip: text;
50background-size: 300% 300%;
5function App() {
6const [prompt, setPrompt] = useState("");
7const [imageData, setImageData] = useState("");
8const [loading, setLoading] = useState(false);
9const [error, setError] = useState("");
14setLoading(true);
15setError("");
16setImageData("");
17try {
18const response = await fetch("/generate", {
29}
30
31// Ensure we have a valid base64 image with data URI prefix
32const fullBase64Image = data.image.startsWith('data:image')
33? data.image
34: `data:image/png;base64,${data.image}`;
35
36setImageData(fullBase64Image);
37console.log("Image data received:", fullBase64Image.slice(0, 100) + "...");
38} catch (error) {
39console.error("Error generating image:", error);
40setError(error.message || "Failed to generate image");
41} finally {
42setLoading(false);
50return (
51<div className="container">
52<h1>Image Generation</h1>
53<form onSubmit={handleSubmit}>
54<input
56value={prompt}
57onChange={handleInputChange}
58placeholder="Describe the image you want to generate..."
59className="input"
60/>
61<button type="submit" className="submit-btn" disabled={loading}>
62{loading ? "Generating..." : "Generate Image"}
63</button>
64</form>
65{loading && <p className="loading">Generating image, please wait...</p>}
66{error && <p className="error">Error: {error}</p>}
67{imageData && (
68<div className="image-container">
69<h2>Generated Image:</h2>
70<img
71src={imageData}
72alt="Generated image"
73className="generated-image"
74onError={(e) => {
75console.error("Image failed to load", e);
76setError("Failed to render image");
77}}
78/>
91}
9293// Utility function to validate and adjust image dimensions
94function validateImageDimensions(width: number, height: number): {
95width: number,
96height: number,
137export default async function server(request: Request): Promise<Response> {
138const url = new URL(request.url);
139const imagePrompt = url.searchParams.get('image');
140
141// Parse width and height with advanced validation
148height: safeHeight,
149warnings
150} = validateImageDimensions(rawWidth, rawHeight);
151152if (url.pathname === "/generate" && request.method === "POST") {
164console.log("Received prompt:", prompt);
165166const togetherApiUrl = "https://api.together.xyz/v1/images/generations";
167console.log("Sending request to Together AI API:", togetherApiUrl);
168194console.log("Together AI API full response:", JSON.stringify(result, null, 2));
195196// Robust extraction of base64 image data
197let imageBase64;
198if (result.data && Array.isArray(result.data) && result.data.length > 0) {
199imageBase64 = result.data[0].b64_json || result.data[0];
200} else if (result.b64_json) {
201imageBase64 = result.b64_json;
202} else if (result.data && result.data.b64_json) {
203imageBase64 = result.data.b64_json;
204} else {
205console.error("Unexpected response structure:", result);
206throw new Error("No image found in API response");
207}
208209// Ensure imageBase64 is a string and trim any whitespace
210imageBase64 = (typeof imageBase64 === 'string' ? imageBase64 : JSON.stringify(imageBase64)).trim();
211212console.log("Extracted image base64 (first 100 chars):", imageBase64.slice(0, 100));
213214// Include warnings in the response if any
215return new Response(JSON.stringify({
216image: imageBase64,
217warnings: warnings.length > 0 ? warnings : undefined
218}), {
220});
221} catch (error) {
222console.error("Error generating image:", error.message);
223console.error("Full error details:", error);
224return new Response(JSON.stringify({ error: error.message || "Failed to generate image" }), {
225status: 500,
226headers: { "Content-Type": "application/json" },
229}
230231// Handle direct image generation from URL query
232if (imagePrompt) {
233const apiKey = Deno.env.get("TOGETHER_API_KEY");
234if (!apiKey) {
237238try {
239const togetherApiUrl = "https://api.together.xyz/v1/images/generations";
240const response = await fetch(togetherApiUrl, {
241method: "POST",
246body: JSON.stringify({
247model: "black-forest-labs/FLUX.1-schnell",
248prompt: imagePrompt,
249width: safeWidth,
250height: safeHeight,
260261const result = await response.json();
262let imageBase64;
263if (result.data && Array.isArray(result.data) && result.data.length > 0) {
264imageBase64 = result.data[0].b64_json || result.data[0];
265} else if (result.b64_json) {
266imageBase64 = result.b64_json;
267} else if (result.data && result.data.b64_json) {
268imageBase64 = result.data.b64_json;
269} else {
270throw new Error("No image found in API response");
271}
272273// Ensure imageBase64 is a string and trim any whitespace
274imageBase64 = (typeof imageBase64 === 'string' ? imageBase64 : JSON.stringify(imageBase64)).trim();
275276// If the request accepts HTML, return a full HTML page with the image
277if (request.headers.get('Accept')?.includes('text/html')) {
278return new Response(`
280<html>
281<head>
282<title>Generated Image</title>
283<style>
284body {
291font-family: Arial, sans-serif;
292}
293.image-container {
294text-align: center;
295}
306</head>
307<body>
308<div class="image-container">
309<img src="data:image/png;base64,${imageBase64}" alt="Generated image for: ${imagePrompt}" width="${safeWidth}" height="${safeHeight}">
310${warnings.length > 0 ? `
311<div class="warning">
312<p>⚠️ Image dimensions adjusted:</p>
313<ul>
314${warnings.map(warning => `<li>${warning}</li>`).join('')}
324}
325326// Otherwise, return the base64 image directly
327return new Response(imageBase64, {
328headers: {
329'Content-Type': 'image/png',
330'X-Image-Warnings': warnings.length > 0 ? JSON.stringify(warnings) : ''
331}
332});
345<meta charset="UTF-8">
346<meta name="viewport" content="width=device-width, initial-scale=1.0">
347<title>Image Generation</title>
348<style>${css}</style>
349</head>
408cursor: not-allowed;
409}
410.image-container {
411margin-top: 20px;
412}
413.generated-image {
414max-width: 100%;
415height: auto;
1Example usage:
23https://your-val.val.run?image=a%20beautiful%20sunset (uses default 1024x768)
4https://your-val.val.run?image=a%20beautiful%20sunset&width=512&height=512 (uses 512x512)
5https://your-val.val.run?image=a%20beautiful%20sunset&width=4096&height=4096 (will cap at 2048x2048)
67This uses together.ai api and generates the image using the black-forest-labs/FLUX.1-schnell model which is very fast.
89You will need to set the environment var TOGETHER_API_KEY to your key.
Storyweavermain.tsx28 matches
24parts: []
25});
26const [imagePreview, setImagePreview] = useState<string | null>(null);
27const [isLoading, setIsLoading] = useState(false);
28const [error, setError] = useState<string | null>(null);
29const fileInputRef = useRef<HTMLInputElement>(null);
3031const handleImageUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
32const file = event.target.files?.[0];
33if (file) {
34const reader = new FileReader();
35reader.onloadend = () => {
36setImagePreview(reader.result as string);
37};
38reader.readAsDataURL(file);
42try {
43const formData = new FormData();
44formData.append('image', file);
45formData.append('previousStory', JSON.stringify(storyParts.parts));
46
62title: cleanText(result.chapterTitle),
63content: cleanText(result.story),
64imageBase64: result.imageBase64
65}
66]
67}));
68setImagePreview(null);
69}
70} catch (error) {
89type="file"
90ref={fileInputRef}
91onChange={handleImageUpload}
92accept="image/*"
93style={{display: 'none'}}
94/>
115<div key={index} className="story-section">
116<h3>Chapter {index + 1}: {part.title}</h3>
117{part.imageBase64 && (
118<div className="story-image">
119<img
120src={part.imageBase64}
121alt={`Illustration for Chapter ${index + 1}`}
122/>
155if (request.method === 'POST' && new URL(request.url).pathname === '/generate-story') {
156const formData = await request.formData();
157const imageFile = formData.get('image') as File;
158const previousStoryStr = formData.get('previousStory') as string || '[]';
159const previousStory = JSON.parse(previousStoryStr);
160161if (!imageFile) {
162return new Response(JSON.stringify({ error: 'No image uploaded' }), { status: 400 });
163}
164165const arrayBuffer = await imageFile.arrayBuffer();
166const base64Image = btoa(
167new Uint8Array(arrayBuffer).reduce((data, byte) => data + String.fromCharCode(byte), '')
168);
172173try {
174const imageAnalysis = await withTimeout(openai.chat.completions.create({
175model: "gpt-4o",
176messages: [
180{
181type: "text",
182text: "Describe this image briefly, focusing on the main characters and key elements. Be concise."
183},
184{
185type: "image_url",
186image_url: { url: `data:image/jpeg;base64,${base64Image}` }
187}
188]
192}), 15000); // 15 seconds timeout
193194const imageDescription = imageAnalysis.choices[0].message.content || "A magical drawing";
195
196// Optimize previous story context
204{
205role: "system",
206content: "You are a children's storyteller. Continue the story or start a new one based on the image. Use 3 short, simple sentences. Be exciting and brief. Provide a chapter title."
207},
208{
209role: "user",
210content: `Image: ${imageDescription}\n${previousStoryContext}\n\nCreate a chapter title and a 3-sentence story continuation.`
211}
212],
235chapterTitle: chapterTitle,
236story: storyContent,
237imageBase64: `data:image/jpeg;base64,${base64Image}`
238}), {
239headers: { 'Content-Type': 'application/json' }
243console.error('Story generation error:', error);
244return new Response(JSON.stringify({
245error: 'Story generation timed out. Please try again with a simpler image or shorter previous story.'
246}), {
247status: 500,
325}
326327.story-image {
328max-width: 100%;
329margin-bottom: 15px;
332}
333334.story-image img {
335max-width: 100%;
336max-height: 300px;
343}
344345.image-preview {
346display: none;
347}
blob_adminREADME.md1 match
3This is a lightweight Blob Admin interface to view and debug your Blob data.
45
67Versions 0-17 of this val were done with Hono and server-rendering.
blob_adminmain.tsx3 matches
440{profile && (
441<div className="flex items-center space-x-4">
442<img src={profile.profileImageUrl} alt="Profile" className="w-8 h-8 rounded-full" />
443<span>{profile.username}</span>
444<a href="/auth/logout" className="text-blue-400 hover:text-blue-300">Logout</a>
583alt="Blob content"
584className="max-w-full h-auto"
585onError={() => console.error("Error loading image")}
586/>
587</div>
635<li>Create public shareable links for blobs</li>
636<li>View and manage public folder</li>
637<li>Preview images directly in the interface</li>
638</ul>
639</div>
blob_adminREADME.md1 match
3This is a lightweight Blob Admin interface to view and debug your Blob data.
45
67Versions 0-17 of this val were done with Hono and server-rendering.
blob_adminmain.tsx3 matches
439{profile && (
440<div className="flex items-center space-x-4">
441<img src={profile.profileImageUrl} alt="Profile" className="w-8 h-8 rounded-full" />
442<span>{profile.username}</span>
443<a href="/auth/logout" className="text-blue-400 hover:text-blue-300">Logout</a>
582alt="Blob content"
583className="max-w-full h-auto"
584onError={() => console.error("Error loading image")}
585/>
586</div>
634<li>Create public shareable links for blobs</li>
635<li>View and manage public folder</li>
636<li>Preview images directly in the interface</li>
637</ul>
638</div>