private async getJobOutput()

in app/lib/server/processors/ApiJobExecutor.ts [369:461]


  private async getJobOutput(
    apiJobId: string,
    credentials: any
  ): Promise<string> {
    try {
      console.log(`📥 Fetching job output for ${apiJobId}`);
      const hfToken = credentials?.huggingfaceToken;

      if (!hfToken) {
        throw new Error(
          "Hugging Face token is required for fetching job output"
        );
      }
      // Use authenticated username from credentials or 'anonymous' as fallback
      const username = getEffectiveUsername(credentials);

      // Construct URL with username from credentials
      const logsUrl = `${HUGGINGFACE_API.BASE_URL.replace(
        "/api/jobs/",
        `/api/jobs/${username}`
      )}/${apiJobId}/logs`;

      console.log(`🔗 Using logs URL with username: ${logsUrl}`);

      const outputResponse = await fetch(logsUrl, {
        headers: {
          Authorization: `Bearer ${hfToken}`,
        },
      });

      if (!outputResponse.ok) {
        console.warn(`⚠️ Could not fetch job output: ${outputResponse.status}`);
        return "Job completed but output not available";
      }

      // Get the readable stream
      const reader = outputResponse.body?.getReader();
      if (!reader) {
        return "Job completed but output not available";
      }

      const decoder = new TextDecoder();
      let rawStream = "";
      let parsedOutput = "";

      try {
        while (true) {
          const { done, value } = await reader.read();

          if (done) {
            break;
          }

          // Decode the chunk and add to raw stream
          const chunk = decoder.decode(value, { stream: true });
          rawStream += chunk;

          // Optional: Log progress for debugging
          console.log(`📄 Received chunk: ${chunk.length} characters`);
        }

        // Final decode to handle any remaining bytes
        rawStream += decoder.decode();

        // Parse the SSE data format
        const lines = rawStream.split("\n");
        for (const line of lines) {
          if (line.startsWith("data: ")) {
            try {
              const jsonData = line.substring(6); // Remove 'data: ' prefix
              const parsed = JSON.parse(jsonData);
              if (parsed.data) {
                parsedOutput += parsed.data + "\n";
              }
            } catch (parseError) {
              console.warn(`⚠️ Could not parse SSE line: ${line}`);
            }
          }
        }

        console.log(
          `✅ Stream complete. Parsed output: ${parsedOutput.length} characters`
        );
        return parsedOutput.trim(); // Remove trailing newline
      } finally {
        // Always release the reader
        reader.releaseLock();
      }
    } catch (error) {
      console.error("❌ Error fetching job output:", error);
      return "Job completed but output could not be retrieved";
    }
  }