<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged generative-ui</title>
<link>https://coderlegion.com/tag/generative-ui</link>
<description>Powered by Question2Answer</description>
<item>
<title>Asynchronous AI Processing Architecture: Building Non-Blocking User Experiences for Long-Running AI</title>
<link>https://coderlegion.com/5198/asynchronous-processing-architecture-building-blocking-user-experiences-long-running</link>
<description>&lt;p&gt;&lt;strong&gt;How to handle AI image generation requests that take 5-15+ seconds without blocking your users or consuming server resources?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=4815719919148397727&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-challenge&quot;&gt;The Challenge&lt;/h3&gt;
&lt;p&gt;AI-powered applications face a fundamental user experience challenge: modern AI tasks like image generation, video processing, or complex language model operations often require 5-30 seconds to complete. Traditional synchronous request-response patterns create several problems:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Connection Timeouts&lt;/strong&gt;: HTTP requests timing out during long AI processing, leaving users with error messages instead of results.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resource Blocking&lt;/strong&gt;: Server connections remain open during processing, consuming valuable server resources and limiting concurrent user capacity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Poor User Experience&lt;/strong&gt;: Users stare at loading screens without progress indicators or the ability to navigate elsewhere while waiting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scalability Issues&lt;/strong&gt;: Each processing request ties up a server connection, severely limiting the number of concurrent users your application can handle.&lt;/p&gt;
&lt;h3 id=&quot;the-async-architecture-solution&quot;&gt;The Async Architecture Solution&lt;/h3&gt;
&lt;p&gt;The solution is an asynchronous, prediction-based architecture that decouples AI task submission from result delivery. This approach immediately returns control to the user while processing happens in the background.&lt;/p&gt;
&lt;p&gt;The core workflow consists of three distinct phases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Immediate Submission&lt;/strong&gt;: User submits request → Server validates and creates AI task → Returns task ID instantly&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Background Processing&lt;/strong&gt;: AI service processes task → Sends webhook notification when complete&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Result Delivery&lt;/strong&gt;: Frontend polls for status updates → Displays result when ready&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;architecture-components&quot;&gt;Architecture Components&lt;/h3&gt;
&lt;h4 id=&quot;1-non-blocking-api-endpoint&quot;&gt;1. Non-Blocking API Endpoint&lt;/h4&gt;
&lt;p&gt;The primary endpoint handles task submission without waiting for AI completion:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;export async function POST(request: NextRequest): Promise&amp;lt;NextResponse&amp;lt;APIResponse&amp;gt;&amp;gt; {
  try {
    // 1. Validate input parameters
    const validationResult = schema.safeParse(formData);
    if (!validationResult.success) {
      return await createErrorResponse({ errorCode: EValidationErrorCode.INVALID_PARAMETER });
    }

    // 2. Authentication and rate limiting checks
    const session = await auth();
    const throttleResult = await checkAnonymousUserRequestLimit({ userIdentifier });
    if (!throttleResult.success) {
      return await createErrorResponse({ errorCode: throttleResult.errorCode });
    }

    // 3. Create async AI prediction task
    const webhookUrl = `${process.env.API_BASE_URL}/api/webhooks/replicate`;
    const result = await generateJerseyEffectAsync({
      payload: validatedData,
      requestId: generateRequestId(),
      webhookUrl,
    });

    // 4. Store prediction status in KV store with TTL
    await PredictionStatusManager.createPrediction(result.data.predictionId, {
      status: 'starting',
      requestId: result.data.requestId,
      userId: session?.user?.uuid,
      payload,
      createdAt: Date.now(),
    });

    // 5. Launch concurrent background tasks (non-blocking)
    const backgroundTasks = [
      reserveUserCredits({ userUuid, predictionId, creditsAmount }),
      createUserWorkRecord({ userUuid, payload, predictionId }),
    ];
    
    // Execute background tasks without waiting
    Promise.allSettled(backgroundTasks);

    // 6. Return immediately with prediction ID
    return NextResponse.json({
      success: true,
      message: 'Prediction created successfully',
      data: {
        predictionId: result.data.predictionId,
        requestId: result.data.requestId,
        status: 'starting',
        estimatedTime: result.data.estimatedTime,
      },
    });

  } catch (error) {
    return await createErrorResponse({ errorCode: ECommonErrorCode.INTERNAL_SERVER_ERROR });
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;2-intelligent-status-management&quot;&gt;2. Intelligent Status Management&lt;/h4&gt;
&lt;p&gt;A centralized status manager handles prediction state across the entire lifecycle:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;export class PredictionStatusManager {
  // Store prediction with initial status
  static async createPrediction(predictionId: string, data: PredictionData) {
    await putKV(`prediction:${predictionId}`, {
      ...data,
      status: 'starting',
      createdAt: Date.now(),
    }, { expirationTtl: 3600 }); // 1 hour TTL
  }

  // Update status during processing
  static async markAsProcessing(predictionId: string) {
    const current = await this.getPredictionStatus(predictionId);
    if (current.success &amp;amp;&amp;amp; current.data) {
      await putKV(`prediction:${predictionId}`, {
        ...current.data,
        status: 'processing',
        updatedAt: Date.now(),
      });
    }
  }

  // Mark completion with results
  static async markAsSucceeded(predictionId: string, imageUrl: string, filePath: string, duration?: number) {
    const current = await this.getPredictionStatus(predictionId);
    if (current.success &amp;amp;&amp;amp; current.data) {
      await putKV(`prediction:${predictionId}`, {
        ...current.data,
        status: 'succeeded',
        result: {
          imageUrl,
          filePath,
          generationTime: duration,
        },
        completedAt: Date.now(),
      });
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;3-webhook-processing-pipeline&quot;&gt;3. Webhook Processing Pipeline&lt;/h4&gt;
&lt;p&gt;The webhook endpoint handles AI service completion notifications with comprehensive error handling:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;export async function POST(request: NextRequest): Promise&amp;lt;NextResponse&amp;lt;APIResponse&amp;gt;&amp;gt; {
  performanceMonitor.start('webhook-total');
  
  try {
    // 1. Security verification (prevent replay attacks)
    const body = await request.text();
    const verification = await verifyWebhookRequest(request, body, {
      secret: process.env.REPLICATE_WEBHOOK_SECRET,
      checkTimestamp: true,
    });

    if (!verification.valid) {
      return await createErrorResponse({ errorCode: ECommonErrorCode.SERVICE_UNAVAILABLE });
    }

    // 2. Parse webhook event
    const event: ReplicateWebhookEvent = JSON.parse(body);
    console.log(' Webhook received:', { id: event.id, status: event.status });

    // 3. Route to appropriate handler
    switch (event.status) {
      case 'starting':
      case 'processing':
        await PredictionStatusManager.markAsProcessing(event.id);
        break;

      case 'succeeded':
        await handleSuccessfulPrediction(event.id, event);
        break;

      case 'failed':
      case 'canceled':
        await handleFailedPrediction(event.id, event.error || 'Task canceled');
        break;
    }

    return NextResponse.json({ success: true, processed: true });

  } catch (error) {
    console.error('❌ Webhook processing error:', error);
    return await createErrorResponse({ errorCode: ECommonErrorCode.INTERNAL_SERVER_ERROR });
  }
}

async function handleSuccessfulPrediction(predictionId: string, event: ReplicateWebhookEvent) {
  // 1. Extract result URL from AI service response
  const imageUrl = Array.isArray(event.output) ? event.output[0] : event.output;
  
  // 2. Download and store result to permanent storage
  const imageResponse = await fetch(imageUrl);
  const imageBuffer = await imageResponse.arrayBuffer();
  
  const uploadResult = await uploadFile({
    path: 'jerseys',
    fileName: `${Date.now()}-${predictionId}.png`,
    file: imageBuffer,
    contentType: 'image/png',
  });

  const finalImageUrl = generatePublicUrl(uploadResult.filePath);

  // 3. Update status with final result
  await PredictionStatusManager.markAsSucceeded(
    predictionId,
    finalImageUrl,
    uploadResult.filePath,
    event.metrics?.predict_time * 1000
  );

  // 4. Update user records and confirm billing
  await updateUserWorkStatus(predictionId, {
    workResult: finalImageUrl,
    generationStatus: 'completed',
    generationDuration: event.metrics?.predict_time * 1000,
  });

  await confirmCreditDeduction({ userUuid, predictionId, actualCreditsUsed });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;4-concurrent-background-processing&quot;&gt;4. Concurrent Background Processing&lt;/h4&gt;
&lt;p&gt;The architecture maximizes efficiency by running multiple operations concurrently without blocking the main response:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;// After successful prediction creation, launch background tasks
const concurrentTasks: Promise&amp;lt;void&amp;gt;[] = [];

// Credit reservation task (for paid users)
if (hasPaid &amp;amp;&amp;amp; userUuid &amp;amp;&amp;amp; requiredCredits &amp;gt; 0) {
  const creditReserveTask = (async () =&amp;gt; {
    const reserveResult = await reserveUserCredits({
      userUuid,
      predictionId,
      creditsAmount: requiredCredits,
      taskType: 'text_to_image',
      taskDescription: `Jersey generation: ${JSON.stringify(payload).substring(0, 100)}`,
    });
    
    if (!reserveResult.success) {
      console.error('❌ Credit reservation failed:', reserveResult.message);
    }
  })();
  
  concurrentTasks.push(creditReserveTask);
}

// User work record creation task
if (userUuid) {
  const createWorkTask = (async () =&amp;gt; {
    await createUserWorkRecord({
      userUuid,
      payload,
      requestId,
      predictionId,
      isAnonymous: !isAuthenticated,
    });
  })();
  
  concurrentTasks.push(createWorkTask);
}

// Execute all tasks concurrently without waiting for results
if (concurrentTasks.length &amp;gt; 0) {
  Promise.allSettled(concurrentTasks).then((results) =&amp;gt; {
    console.log(' Background tasks completed:', {
      total: results.length,
      fulfilled: results.filter(r =&amp;gt; r.status === 'fulfilled').length,
      rejected: results.filter(r =&amp;gt; r.status === 'rejected').length,
    });
  });
}

// Return immediately to user
return NextResponse.json({ success: true, data: { predictionId, status: 'starting' } });
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;frontend-integration-pattern&quot;&gt;Frontend Integration Pattern&lt;/h3&gt;
&lt;p&gt;The client-side implementation uses intelligent polling with exponential backoff:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;async function pollPredictionStatus(predictionId: string) {
  const delays = [1000, 2000, 5000, 10000]; // 1s → 2s → 5s → 10s
  let attemptIndex = 0;
  
  while (attemptIndex &amp;lt; 60) { // Maximum 10 minutes polling
    try {
      const response = await fetch(`/api/predictions/${predictionId}/status`);
      const result = await response.json();
      
      if (result.data.status === 'succeeded') {
        displayResult(result.data.result.imageUrl);
        return;
      } else if (result.data.status === 'failed') {
        displayError(result.data.error);
        return;
      }
      
      // Continue polling with progressive delays
      const delay = delays[Math.min(attemptIndex, delays.length - 1)];
      await new Promise(resolve =&amp;gt; setTimeout(resolve, delay));
      attemptIndex++;
      
    } catch (error) {
      console.error('Polling error:', error);
      await new Promise(resolve =&amp;gt; setTimeout(resolve, 2000));
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;monitoring-and-debugging&quot;&gt;Monitoring and Debugging&lt;/h3&gt;
&lt;p&gt;Async architectures require comprehensive monitoring to maintain reliability:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;// Performance monitoring integration
export class PerformanceMonitor {
  static start(operation: string, metadata?: Record&amp;lt;string, any&amp;gt;) {
    console.log(` Starting ${operation}`, metadata);
    return Date.now();
  }
  
  static end(operation: string, startTime: number) {
    const duration = Date.now() - startTime;
    console.log(`✅ Completed ${operation} in ${duration}ms`);
    
    // Send metrics to monitoring service in production
    if (process.env.NODE_ENV === 'production') {
      sendMetric(`operation.${operation}.duration`, duration);
      sendMetric(`operation.${operation}.count`, 1);
    }
    
    return duration;
  }
}

// Status debugging endpoint
export async function GET(request: NextRequest) {
  const predictionId = request.nextUrl.searchParams.get('predictionId');
  
  if (!predictionId) {
    return NextResponse.json({ error: 'Missing predictionId' }, { status: 400 });
  }
  
  const status = await PredictionStatusManager.getPredictionStatus(predictionId);
  
  return NextResponse.json({
    prediction: status.data,
    debug: {
      kvTtl: await getKV(`prediction:${predictionId}:ttl`),
      queueStatus: await checkReplicateQueue(),
      systemHealth: await checkSystemHealth(),
    }
  });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;architecture-benefits&quot;&gt;Architecture Benefits&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Immediate User Feedback&lt;/strong&gt;: Users receive instant confirmation that their request is being processed, eliminating the anxiety of waiting without feedback.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resource Efficiency&lt;/strong&gt;: Server connections are freed immediately after task submission, allowing the same server to handle hundreds of concurrent users.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fault Tolerance&lt;/strong&gt;: Webhook retries and status persistence ensure results are delivered even if temporary network issues occur.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scalable Processing&lt;/strong&gt;: AI processing happens on specialized services while your API servers remain available for new requests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Progressive Enhancement&lt;/strong&gt;: Frontend can provide real-time status updates, estimated completion times, and allow users to continue using the application while waiting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Robust Error Recovery&lt;/strong&gt;: Failed predictions automatically trigger credit refunds and user notifications, while webhook retry mechanisms ensure eventual consistency even during temporary outages.&lt;/p&gt;
&lt;h3 id=&quot;production-performance&quot;&gt;Production Performance&lt;/h3&gt;
&lt;p&gt;This architecture has been successfully deployed at &lt;a rel=&quot;nofollow&quot; href=&quot;https://fastjrsy.com/&quot;&gt;Fastjrsy&lt;/a&gt;, an &lt;a rel=&quot;nofollow&quot; href=&quot;https://fastjrsy.com/&quot;&gt;AI jersey design generator&lt;/a&gt; that processes thousands of image generation requests daily. Key performance metrics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Response Time&lt;/strong&gt;: API endpoints respond in under 200ms&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Throughput&lt;/strong&gt;: Handles 50+ concurrent prediction requests per second&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Completion Rate&lt;/strong&gt;: 99.2% of predictions complete successfully&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Average Processing Time&lt;/strong&gt;: Under 5 seconds for speed mode, under 8 seconds for quality mode, 15 seconds for scene generation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;User Retention&lt;/strong&gt;: 40% reduction in page abandonment during generation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The architecture scales efficiently across Cloudflare's global edge network, providing consistent performance regardless of user location or current load.&lt;/p&gt;
&lt;p&gt;This async processing pattern transforms long-running AI operations from user experience blockers into smooth, progressive interactions that maintain user engagement and system efficiency at scale.&lt;/p&gt;
</description>
<category>Full-stack Dev</category>
<guid isPermaLink="true">https://coderlegion.com/5198/asynchronous-processing-architecture-building-blocking-user-experiences-long-running</guid>
<pubDate>Fri, 05 Sep 2025 09:32:32 +0000</pubDate>
</item>
<item>
<title>Building you first AI Agent for a Task Organizer with Still.js and Groq</title>
<link>https://coderlegion.com/4153/building-you-first-ai-agent-for-a-task-organizer-with-still-js-and-groq</link>
<description>&lt;p&gt;AI is now widely used for solving various problems, especially in the tech industry and among software developers. This article explores a specific use case of AI, focusing on certain key aspects while keeping the end-user in mind.&lt;/p&gt;
&lt;p&gt;In summary, the task organizer is a software tool designed to help users manage tasks over various timeframes. While powerful Project/Task Management solutions like Motion and ClickUp exist, here we’ll demonstrate the capabilities of &lt;a rel=&quot;nofollow&quot; href=&quot;https://still-js.github.io/stilljs-site/&quot;&gt;Still.js&lt;/a&gt; by discussing and building a small PoC covering a specific and tiny aspect. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI Agent vs Agentic AI&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;According to google AI Overview &quot;AI agents are specialized tools designed for specific, well-defined tasks, while Agentic AI represents a broader concept of autonomous, goal-driven systems that adapt to changing situations, and coordinate actions with minimal human oversight&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;From Generative AI to Generative UI&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This concept involves generating UI dynamically based on user prompt. Different prompts produce different UI components. In our case, we’ll handle it using a client-side approach.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How our Agent will it work essentially?&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The user will write a text with the tasks he'll do, specifying what, how and when&lt;/li&gt;
&lt;li&gt;Content is submitted to the Agent/LLM, which generates task(s)&lt;/li&gt;
&lt;li&gt;UI parses LLM response and decides, how/what predefined component to render/present&lt;/li&gt;
&lt;li&gt;User can then ask the agent to mark tasks as completed.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Different points of the design systems are addressed in here, for the implementation there is a “&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.youtube.com/watch?v=x_gTiJKemcA&quot;&gt;&lt;strong&gt;hands-on youtube video&lt;/strong&gt;&lt;/a&gt;” where a tiny implementation is built from scratch. Bellow is the design system depicting an overview of the solution.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=7353457250242215388&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;We’ll consider essentially 3 main parts, the &lt;strong&gt;AI provider&lt;/strong&gt;, a &lt;strong&gt;custom Backend API&lt;/strong&gt;, and &lt;strong&gt;the UI&lt;/strong&gt; which we describe as follow:&lt;/p&gt;
&lt;p&gt;AI Provider supplies intelligent capabilities&lt;/p&gt;
&lt;p&gt;Backend provides a robust and secure integration with the AI, also serves the Frontend&lt;/p&gt;
&lt;p&gt;Frontend handles user input and displays the AI's results.&lt;/p&gt;
&lt;p&gt;In this use case, Still.js features like runtime form generation and centralized form validation are leveraged to manage task completion. The structure includes three components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Home (main component),&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TaskDay (group of tasks),&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Task (individual tasks). Tasks report back to the Home component as form, enabling them to be marked as completed.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://groq.com/&quot;&gt;Groq infrastructure&lt;/a&gt; is what we'll use for LLM, however other AI providers like Google Gemini, ChatGPT, Copilot, LLaMa, or even offline/on-prem options like Ollama could also be used. &lt;/p&gt;
&lt;p&gt;Prompts are sent from the &lt;a rel=&quot;nofollow&quot; href=&quot;https://still-js.github.io/stilljs-site/&quot;&gt;Still.js&lt;/a&gt; enabled UI to the AI engine via chat, mainly as text, but it could support voice or audio.&lt;/p&gt;
&lt;p&gt;In production, long-term memory for LLMs or agents often requires connecting to external sources like vector databases, highlighting the need for a strong backend. &lt;strong&gt;Our agent will have a short-term memory which will be handle as the bellow design&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=7679427318248826750&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Tool use and workflow management are key in Agentic AI, enabling both agency (thinking) and predictability (acting). For some tasks, a robust backend better supports these capabilities. &lt;strong&gt;The agent we'll build has moderate predictability&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In the demo, we’re connecting the UI straight to the AI engine for the sake of the size of the hands-on video tutorial, however this is also a valid scenario when using ephemeral API token&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Are you still here? Less talking, more doing, &lt;a rel=&quot;nofollow&quot; href=&quot;https://youtu.be/x_gTiJKemcA&quot;&gt;&lt;strong&gt;click here&lt;/strong&gt;&lt;/a&gt; and follow the tutorial to build your first AI Agent.&lt;/p&gt;
&lt;p&gt;See you there &lt;/p&gt;
</description>
<category>Java</category>
<guid isPermaLink="true">https://coderlegion.com/4153/building-you-first-ai-agent-for-a-task-organizer-with-still-js-and-groq</guid>
<pubDate>Sat, 19 Jul 2025 16:07:28 +0000</pubDate>
</item>
</channel>
</rss>