victor HF Staff commited on
Commit
96a764f
·
1 Parent(s): fe50e62

refactor: Stream raw AI response and signal type via header

Browse files
Files changed (1) hide show
  1. server.js +26 -62
server.js CHANGED
@@ -467,6 +467,13 @@ ONLY output the changes in this format. Do NOT output the full HTML file again.`
467
  let completeResponse = "";
468
 
469
  try {
 
 
 
 
 
 
 
470
  const chatCompletion = client.chatCompletionStream({
471
  model: MODEL_ID,
472
  provider: "fireworks-ai", // Ensure provider is correct if needed
@@ -475,70 +482,27 @@ ONLY output the changes in this format. Do NOT output the full HTML file again.`
475
  // temperature: 0.7, // Adjust temperature if needed
476
  });
477
 
478
- // --- Conditional Response Handling ---
479
- if (isFollowUp) {
480
- // **Accumulate response, then parse and apply diffs**
481
- for await (const value of chatCompletion) {
482
- const chunk = value.choices[0]?.delta?.content;
483
- if (chunk) {
484
- completeResponse += chunk;
485
- }
486
- // Optional: Add a timeout or check response length to prevent infinite loops
487
- if (completeResponse.length > 50000) { // Example limit
488
- console.error("AI response exceeded length limit during accumulation.");
489
- throw new Error("AI response too long during accumulation.");
490
- }
491
- }
492
-
493
- // Check if the response seems truncated (didn't finish properly)
494
- // This is heuristic - might need refinement
495
- if (!chatCompletion?.controller?.signal?.aborted && !completeResponse.trim()) {
496
- console.warn("AI stream finished but response is empty.");
497
- // Return original HTML as maybe no changes were needed or AI failed silently.
498
- return res.status(200).type('text/html').send(html);
499
- }
500
-
501
-
502
- console.log("--- AI Raw Diff Response ---");
503
- console.log(completeResponse);
504
- console.log("--------------------------");
505
-
506
-
507
- // Apply the diffs
508
- console.log("[Diff Apply] Attempting to apply diffs...");
509
- const modifiedHtml = applyDiffs(html, completeResponse);
510
- console.log("[Diff Apply] Diffs applied successfully.");
511
- res.status(200).type('text/html').send(modifiedHtml); // Send the fully modified HTML
512
-
513
- } else {
514
- // **Stream response directly (Initial Request)**
515
- console.log("[AI Request] Starting direct stream for initial request.");
516
- res.setHeader("Content-Type", "text/html"); // Send as HTML
517
- res.setHeader("Cache-Control", "no-cache");
518
- res.setHeader("Connection", "keep-alive");
519
-
520
- for await (const value of chatCompletion) {
521
- const chunk = value.choices[0]?.delta?.content;
522
- if (chunk) {
523
- res.write(chunk);
524
- completeResponse += chunk; // Still useful for checking completion
525
- }
526
  }
 
527
 
528
- // Basic check if the streamed response looks like HTML
529
- if (!completeResponse.trim().toLowerCase().includes("</html>")) {
530
- console.warn("[AI Request] Streamed response might be incomplete or not valid HTML.");
531
- // Client side might handle this, but good to log.
532
- } else {
533
- console.log("[AI Request] Stream finished successfully.");
534
- }
535
 
536
- res.end(); // End the stream
537
- }
538
 
539
  } catch (error) {
540
- console.error("Error during AI interaction or diff application:", error);
541
- // If we haven't sent a response yet (likely in diff mode or before stream start)
542
  if (!res.headersSent) {
543
  // Check if it's an AbortError which might happen if the client disconnects
544
  if (error.name === 'AbortError') {
@@ -549,14 +513,14 @@ ONLY output the changes in this format. Do NOT output the full HTML file again.`
549
  res.status(500).send({
550
  ok: false,
551
  // Provide a more user-friendly message, but keep details for logs
 
552
  message: `Error processing AI request: ${error.message}. You might need to start a new conversation by refreshing the page.`,
553
  });
554
- } else if (!isFollowUp && !res.writableEnded) {
555
  // If streaming failed mid-stream and stream hasn't been ended yet
556
- console.error("Error occurred mid-stream.");
557
  res.end(); // End the stream abruptly if error occurs during streaming
558
  }
559
- // If diff application failed, error was already sent by applyDiffs throwing.
560
  // If streaming failed *after* res.end() was called (unlikely but possible), do nothing more.
561
  }
562
  });
 
467
  let completeResponse = "";
468
 
469
  try {
470
+ // Set response type header *before* starting the stream
471
+ res.setHeader("Content-Type", "text/plain; charset=utf-8"); // Stream raw text
472
+ res.setHeader("Cache-Control", "no-cache");
473
+ res.setHeader("Connection", "keep-alive");
474
+ res.setHeader("X-Response-Type", isFollowUp ? "diff" : "full"); // Signal type to client
475
+ console.log(`[AI Request] Set X-Response-Type: ${isFollowUp ? 'diff' : 'full'}`);
476
+
477
  const chatCompletion = client.chatCompletionStream({
478
  model: MODEL_ID,
479
  provider: "fireworks-ai", // Ensure provider is correct if needed
 
482
  // temperature: 0.7, // Adjust temperature if needed
483
  });
484
 
485
+ // --- Unified Streaming Logic ---
486
+ console.log("[AI Request] Starting stream to client...");
487
+ for await (const value of chatCompletion) {
488
+ const chunk = value.choices[0]?.delta?.content;
489
+ if (chunk) {
490
+ res.write(chunk); // Stream raw AI response chunk
491
+ completeResponse += chunk; // Accumulate for logging completion
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
492
  }
493
+ }
494
 
495
+ console.log("[AI Request] Stream finished.");
496
+ // Log the complete raw response for debugging if needed
497
+ // console.log("--- AI Raw Full Response ---");
498
+ // console.log(completeResponse);
499
+ // console.log("--------------------------");
 
 
500
 
501
+ res.end(); // End the stream
 
502
 
503
  } catch (error) {
504
+ console.error("Error during AI interaction:", error); // Removed "or diff application"
505
+ // If we haven't sent headers/started streaming yet
506
  if (!res.headersSent) {
507
  // Check if it's an AbortError which might happen if the client disconnects
508
  if (error.name === 'AbortError') {
 
513
  res.status(500).send({
514
  ok: false,
515
  // Provide a more user-friendly message, but keep details for logs
516
+ // Provide a more user-friendly message, but keep details for logs
517
  message: `Error processing AI request: ${error.message}. You might need to start a new conversation by refreshing the page.`,
518
  });
519
+ } else if (!res.writableEnded) {
520
  // If streaming failed mid-stream and stream hasn't been ended yet
521
+ console.error("Error occurred mid-stream. Ending response.");
522
  res.end(); // End the stream abruptly if error occurs during streaming
523
  }
 
524
  // If streaming failed *after* res.end() was called (unlikely but possible), do nothing more.
525
  }
526
  });