Skip to content

Commit

Permalink
Merge pull request #1070 from MahtabBukhari/Ticket-Editor-to-include-…
Browse files Browse the repository at this point in the history
…Hive-Chain-of-Thought-Relevant-to-Specific-Runtwo

Ticket editor to include hive chain of thought relevant to specific run
  • Loading branch information
humansinstitute authored Feb 12, 2025
2 parents 813a878 + 3734acb commit 02bae78
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 95 deletions.
11 changes: 8 additions & 3 deletions src/components/common/TicketEditor/StakworkLogsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,14 @@ interface Connection {
status: 'disconnected' | 'connected' | 'error';
}

const StakworkLogsPanel = ({ swwfLinks }: { swwfLinks: Record<string, string> }) => {
interface StakworkLogsPanelProps {
swwfLinks: Record<string, string>;
logs: LogEntry[];
setLogs: React.Dispatch<React.SetStateAction<LogEntry[]>>;
}

const StakworkLogsPanel = ({ swwfLinks, logs, setLogs }: StakworkLogsPanelProps) => {
const [collapsed, setCollapsed] = useState(true);
const [logs, setLogs] = useState<LogEntry[]>([]);
const [connections, setConnections] = useState<Connection[]>([]);
const { isEnabled: isVerboseLoggingEnabled } = useFeatureFlag('verbose_logging_sw');

Expand Down Expand Up @@ -172,7 +177,7 @@ const StakworkLogsPanel = ({ swwfLinks }: { swwfLinks: Record<string, string> })
}
});
};
}, [connections, swwfLinks, isVerboseLoggingEnabled]);
}, [connections, swwfLinks, isVerboseLoggingEnabled, setLogs]);

return (
<PanelWrapper collapsed={collapsed}>
Expand Down
104 changes: 13 additions & 91 deletions src/components/common/TicketEditor/TicketEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,19 @@ import { TicketStatus, Ticket, Author } from '../../../store/interface';
import { Toast } from '../../../people/widgetViews/workspace/interface';
import { uiStore } from '../../../store/ui';
import { Select, Option } from '../../../people/widgetViews/workspace/style.ts';
import { useDeleteConfirmationModal } from '../../../components/common/DeleteConfirmationModal/DeleteConfirmationModal.tsx';
import { useDeleteConfirmationModal } from '../DeleteConfirmationModal';
import { TicketTextAreaComp } from './TicketTextArea.tsx';

interface LogEntry {
timestamp: string;
projectId: string;
ticketUUID: string;
message: string;
}

interface TicketEditorProps {
ticketData: Ticket;
logs: LogEntry[];
index: number;
websocketSessionId: string;
draggableId: string;
Expand All @@ -44,20 +53,6 @@ interface TicketEditorProps {
workspaceUUID: string;
}

interface LogEntry {
timestamp: string;
projectId: string;
ticketUUID: string;
message: string;
}

interface Connection {
projectId: string;
ticketUUID: string;
websocket: WebSocket;
status: 'disconnected' | 'connected' | 'error';
}

const SwitcherContainer = styled.div`
display: flex;
background-color: white;
Expand Down Expand Up @@ -144,7 +139,7 @@ const EditorWrapper = styled.div`
const ChainOfThought = styled.div`
max-width: 100%;
margin: 12px auto 8px 5px;
padding: 10px 20px 0px 20px;
padding: 10px 20px 0 20px;
border-radius: 16px;
word-wrap: break-word;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
Expand All @@ -158,7 +153,8 @@ const TicketEditor = observer(
dragHandleProps,
swwfLink,
getPhaseTickets,
workspaceUUID
workspaceUUID,
logs
}: TicketEditorProps) => {
const [toasts, setToasts] = useState<Toast[]>([]);
const [versions, setVersions] = useState<number[]>([]);
Expand All @@ -173,8 +169,6 @@ const TicketEditor = observer(
const { main } = useStores();
const [isCreatingBounty, setIsCreatingBounty] = useState(false);
const [isOptionsMenuVisible, setIsOptionsMenuVisible] = useState(false);
const [logs, setLogs] = useState<LogEntry[]>([]);
const [connections, setConnections] = useState<Connection[]>([]);
const [lastLogLine, setLastLogLine] = useState('');
const ui = uiStore;
const { openDeleteConfirmation } = useDeleteConfirmationModal();
Expand Down Expand Up @@ -220,78 +214,6 @@ const TicketEditor = observer(
setIsButtonDisabled(!isChanged);
}, [ticketData, versionTicketData]);

useEffect(() => {
const connectToLogWebSocket = (projectId: string, ticketUUID: string) => {
const ws = new WebSocket('wss://jobs.stakwork.com/cable?channel=ProjectLogChannel');

ws.onopen = () => {
const command = {
command: 'subscribe',
identifier: JSON.stringify({ channel: 'ProjectLogChannel', id: projectId })
};
ws.send(JSON.stringify(command));
};

ws.onmessage = (event: any) => {
const data = JSON.parse(event.data);
if (data.type === 'ping') return;

const messageData = data?.message;
if (
messageData &&
(messageData.type === 'on_step_start' || messageData.type === 'on_step_complete')
) {
setLogs((prev: LogEntry[]) => [
{
timestamp: new Date().toISOString(),
projectId,
ticketUUID,
message: messageData.message
},
...prev
]);
}
};

ws.onerror = () => {
setConnections((prev: Connection[]) =>
prev.map((conn: Connection) =>
conn.projectId === projectId ? { ...conn, status: 'error' } : conn
)
);
};

ws.onclose = () => {
setConnections((prev: Connection[]) =>
prev.map((conn: Connection) =>
conn.projectId === projectId ? { ...conn, status: 'disconnected' } : conn
)
);
};

setConnections((prev: Connection[]) => [
...prev,
{ projectId, ticketUUID, websocket: ws, status: 'connected' }
]);
};

if (
ticketData.ticketUUID &&
swwfLink &&
!connections.some((conn: Connection) => conn.projectId === swwfLink)
) {
connectToLogWebSocket(swwfLink, ticketData.ticketUUID);
}

return () => {
connections.forEach((conn: Connection) => {
if (conn.projectId !== swwfLink) {
conn.websocket.close();
}
});
};
}, [connections, swwfLink, ticketData.ticketUUID]);

useEffect(() => {
if (logs.length > 0) {
setLastLogLine(logs[logs.length - 1]?.message || '');
Expand Down
11 changes: 10 additions & 1 deletion src/people/widgetViews/PhasePlannerView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ interface PhasePlannerParams {
phase_uuid: string;
}

interface LogEntry {
timestamp: string;
projectId: string;
ticketUUID: string;
message: string;
}

const PhasePlannerView: React.FC = observer(() => {
const { feature_uuid, phase_uuid } = useParams<PhasePlannerParams>();
const [featureData, setFeatureData] = useState<Feature | null>(null);
Expand All @@ -69,6 +76,7 @@ const PhasePlannerView: React.FC = observer(() => {
const [page, setPage] = useState<number>(1);
const [loading, setLoading] = useState(true);
const [totalBounties, setTotalBounties] = useState(0);
const [logs, setLogs] = useState<LogEntry[]>([]);
const selectedWidget = 'bounties';

const checkboxIdToSelectedMap: BountyStatus = useMemo(
Expand Down Expand Up @@ -663,6 +671,7 @@ const PhasePlannerView: React.FC = observer(() => {
<TicketEditor
index={index}
ticketData={ticket}
logs={logs}
websocketSessionId={websocketSessionId}
draggableId={ticket.uuid}
hasInteractiveChildren
Expand Down Expand Up @@ -719,7 +728,7 @@ const PhasePlannerView: React.FC = observer(() => {
</DisplayBounties>
</PhaseFlexContainer>
</FieldWrap>
<StakworkLogsPanel swwfLinks={swwfLinks} />
<StakworkLogsPanel swwfLinks={swwfLinks} logs={logs} setLogs={setLogs} />
</FeatureDataWrap>
{toastsEl}
</FeatureBody>
Expand Down

0 comments on commit 02bae78

Please sign in to comment.