From de40b7fa7862783effcf4cf9a826c3d98a84c1f0 Mon Sep 17 00:00:00 2001
From: ali asaria <aliasaria@users.noreply.github.com>
Date: Mon, 3 Feb 2025 14:05:12 -0500
Subject: [PATCH] allow evals to stream output from a job

---
 .../Experiment/Eval/EvalJobsTable.tsx         | 19 ++++++++--
 .../Eval/ViewOutputModalStreaming.tsx         | 36 ++++++++++++++++++
 .../Train/ViewOutputModalStreaming.tsx        |  2 +-
 src/renderer/lib/transformerlab-api-sdk.ts    | 38 ++++++++++---------
 4 files changed, 72 insertions(+), 23 deletions(-)
 create mode 100644 src/renderer/components/Experiment/Eval/ViewOutputModalStreaming.tsx

diff --git a/src/renderer/components/Experiment/Eval/EvalJobsTable.tsx b/src/renderer/components/Experiment/Eval/EvalJobsTable.tsx
index ddf383c6..30af4408 100644
--- a/src/renderer/components/Experiment/Eval/EvalJobsTable.tsx
+++ b/src/renderer/components/Experiment/Eval/EvalJobsTable.tsx
@@ -7,15 +7,16 @@ import {
   Table,
   Typography,
 } from '@mui/joy';
-import React, { useState, useEffect } from 'react';
+import { useState, useEffect } from 'react';
 import useSWR from 'swr';
 import * as chatAPI from '../../../lib/transformerlab-api-sdk';
 import dayjs from 'dayjs';
+import ViewOutputModalStreaming from './ViewOutputModalStreaming';
 
 const fetcher = (url) => fetch(url).then((res) => res.json());
 
 const EvalJobsTable = () => {
-  const [state, setState] = useState(null);
+  const [viewOutputFromJob, setViewOutputFromJob] = useState(-1);
 
   const {
     data: jobs,
@@ -39,9 +40,13 @@ const EvalJobsTable = () => {
         flexDirection: 'column',
       }}
     >
+      <ViewOutputModalStreaming
+        jobId={viewOutputFromJob}
+        setJobId={setViewOutputFromJob}
+      />
       <Typography level="h2">Executions</Typography>
       <Sheet sx={{ overflowY: 'scroll' }}>
-        <Table>
+        <Table stickyHeader>
           <thead>
             <tr>
               <th width="50px">Id</th>
@@ -70,7 +75,13 @@ const EvalJobsTable = () => {
                 <td>{String(dayjs(job?.updated_at))}</td>
                 <td>
                   <ButtonGroup>
-                    <Button>View Output</Button>
+                    <Button
+                      onClick={() => {
+                        setViewOutputFromJob(job?.id);
+                      }}
+                    >
+                      View Output
+                    </Button>
                     <Button>Cancel</Button>
                   </ButtonGroup>
                 </td>
diff --git a/src/renderer/components/Experiment/Eval/ViewOutputModalStreaming.tsx b/src/renderer/components/Experiment/Eval/ViewOutputModalStreaming.tsx
new file mode 100644
index 00000000..6eed6f0d
--- /dev/null
+++ b/src/renderer/components/Experiment/Eval/ViewOutputModalStreaming.tsx
@@ -0,0 +1,36 @@
+import useSWR from 'swr';
+
+import { Box, Modal, ModalClose, ModalDialog, Typography } from '@mui/joy';
+
+import * as chatAPI from 'renderer/lib/transformerlab-api-sdk';
+import OutputTerminal from 'renderer/components/OutputTerminal';
+
+const fetcher = (url) => fetch(url).then((res) => res.json());
+
+export default function ViewOutputModalStreaming({ jobId, setJobId }) {
+  return (
+    <Modal open={jobId != -1} onClose={() => setJobId(-1)}>
+      <ModalDialog sx={{ width: '80vw', height: '80vh' }}>
+        <ModalClose />
+        <Typography level="title-lg">Output from job: {jobId}</Typography>
+        <Box
+          sx={{
+            height: '100%',
+            overflow: 'hidden',
+            border: '10px solid #444',
+            padding: '0rem 0 0 1rem',
+            backgroundColor: '#000',
+            width: '100%',
+          }}
+        >
+          <OutputTerminal
+            logEndpoint={chatAPI.Endpoints.Experiment.StreamOutputFromJob(
+              jobId
+            )}
+            lineAnimationDelay={5}
+          />
+        </Box>
+      </ModalDialog>
+    </Modal>
+  );
+}
diff --git a/src/renderer/components/Experiment/Train/ViewOutputModalStreaming.tsx b/src/renderer/components/Experiment/Train/ViewOutputModalStreaming.tsx
index 6eed6f0d..1ff4d3f5 100644
--- a/src/renderer/components/Experiment/Train/ViewOutputModalStreaming.tsx
+++ b/src/renderer/components/Experiment/Train/ViewOutputModalStreaming.tsx
@@ -24,7 +24,7 @@ export default function ViewOutputModalStreaming({ jobId, setJobId }) {
           }}
         >
           <OutputTerminal
-            logEndpoint={chatAPI.Endpoints.Experiment.StreamOutputFromJob(
+            logEndpoint={chatAPI.Endpoints.Experiment.StreamOutputFromTrainingJob(
               jobId
             )}
             lineAnimationDelay={5}
diff --git a/src/renderer/lib/transformerlab-api-sdk.ts b/src/renderer/lib/transformerlab-api-sdk.ts
index 412ce21e..dd16ede4 100644
--- a/src/renderer/lib/transformerlab-api-sdk.ts
+++ b/src/renderer/lib/transformerlab-api-sdk.ts
@@ -1253,9 +1253,9 @@ Endpoints.Experiment = {
   DeleteConversation: (experimentId: string, conversationId: string) =>
     FULL_PATH(
       'experiment/' +
-      experimentId +
-      '/conversations/delete?conversation_id=' +
-      conversationId
+        experimentId +
+        '/conversations/delete?conversation_id=' +
+        conversationId
     ),
   InstallPlugin: (experimentId: string, pluginId: string) =>
     API_URL() +
@@ -1280,10 +1280,10 @@ Endpoints.Experiment = {
   ) =>
     FULL_PATH(
       'experiment/' +
-      experimentId +
-      '/plugins/list?type=' +
-      type +
-      (filter ? '&filter=' + filter : '')
+        experimentId +
+        '/plugins/list?type=' +
+        type +
+        (filter ? '&filter=' + filter : '')
     ),
   ScriptListFiles: (experimentId: string, id: string) =>
     API_URL() + 'experiment/' + experimentId + '/plugins/' + id + '/list_files',
@@ -1336,8 +1336,10 @@ Endpoints.Experiment = {
     'plugins/delete_plugin?pluginId=' +
     pluginId,
   GetOutputFromJob: (jobId: string) => API_URL() + `train/job/${jobId}/output`,
-  StreamOutputFromJob: (jobId: string) =>
+  StreamOutputFromTrainingJob: (jobId: string) =>
     API_URL() + `train/job/${jobId}/stream_output`,
+  StreamOutputFromJob: (jobId: string) =>
+    API_URL() + `jobs/${jobId}/stream_output`,
 };
 
 Endpoints.Jobs = {
@@ -1557,16 +1559,16 @@ export async function activateWorker(
   try {
     response = await fetch(
       API_URL() +
-      'server/worker_start?model_name=' +
-      model +
-      '&adaptor=' +
-      adaptorName +
-      '&engine=' +
-      engine +
-      '&experiment_id=' +
-      experimentId +
-      '&parameters=' +
-      paramsJSON
+        'server/worker_start?model_name=' +
+        model +
+        '&adaptor=' +
+        adaptorName +
+        '&engine=' +
+        engine +
+        '&experiment_id=' +
+        experimentId +
+        '&parameters=' +
+        paramsJSON
     );
     const result = await response.json();
     return result;
-- 
GitLab