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";
}
}