feat(rah-light): remove RAHChat and related components

- Deleted src/components/agents/RAHChat.tsx
- Deleted src/components/agents/TerminalInput.tsx
- Deleted src/components/agents/TerminalMessage.tsx
- Deleted src/components/agents/hooks/useSSEChat.ts
- Deleted src/components/helpers/ReasoningTrace.tsx
- Deleted src/components/helpers/ToolDisplay.tsx
- Simplified WorkflowsPane to show MCP integration message (no chat)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
“BeeRad”
2026-01-29 15:30:05 +11:00
co-authored by Claude Opus 4.5
parent a398819e26
commit 2661be7c80
7 changed files with 19 additions and 1995 deletions
+19 -504
View File
@@ -1,13 +1,8 @@
"use client";
import { useState, useCallback, useEffect, useMemo } from 'react';
import RAHChat from '@/components/agents/RAHChat';
import { useState } from 'react';
import PaneHeader from './PaneHeader';
import { WorkflowsPaneProps, PaneType, AgentDelegation } from './types';
import { parseAndRenderContent } from '@/components/helpers/NodeLabelRenderer';
import type { ChatMessage } from '@/components/agents/hooks/useSSEChat';
type ViewMode = 'list' | 'detail' | 'summary';
import { WorkflowsPaneProps, AgentDelegation } from './types';
export default function WorkflowsPane({
slot,
@@ -21,57 +16,6 @@ export default function WorkflowsPane({
activeTabId = null,
activeDimension,
}: WorkflowsPaneProps) {
const [viewMode, setViewMode] = useState<ViewMode>('list');
const [selectedDelegationId, setSelectedDelegationId] = useState<string | null>(null);
const [delegationMessages, setDelegationMessages] = useState<Record<string, ChatMessage[]>>({});
const selectedDelegation = delegations.find(d => d.sessionId === selectedDelegationId);
const getDelegationMessages = useCallback((sessionId: string) => {
return delegationMessages[sessionId] || [];
}, [delegationMessages]);
const setDelegationMessagesFor = useCallback((sessionId: string) => {
return (updater: (prev: ChatMessage[]) => ChatMessage[]) => {
setDelegationMessages(prev => ({
...prev,
[sessionId]: updater(prev[sessionId] || [])
}));
};
}, []);
const handleSelectDelegation = (sessionId: string) => {
const delegation = delegations.find(d => d.sessionId === sessionId);
setSelectedDelegationId(sessionId);
// Show summary view for completed/failed with no messages
if (delegation &&
(delegation.status === 'completed' || delegation.status === 'failed') &&
getDelegationMessages(sessionId).length === 0) {
setViewMode('summary');
} else {
setViewMode('detail');
}
};
const handleDeleteDelegation = async (sessionId: string) => {
try {
await fetch(`/api/rah/delegations/${sessionId}`, { method: 'DELETE' });
} catch (error) {
console.error(`Failed to delete delegation ${sessionId}:`, error);
}
// The parent will handle removing from delegations list via SSE
};
const handleBack = () => {
setSelectedDelegationId(null);
setViewMode('list');
};
const handleTypeChange = (type: PaneType) => {
onPaneAction?.({ type: 'switch-pane-type', paneType: type });
};
return (
<div style={{
height: '100%',
@@ -83,82 +27,14 @@ export default function WorkflowsPane({
<PaneHeader slot={slot} onCollapse={onCollapse} onSwapPanes={onSwapPanes} />
<div style={{ flex: 1, minHeight: 0, overflow: 'hidden' }}>
{viewMode === 'list' && (
<WorkflowsListView
delegations={delegations}
onSelectDelegation={handleSelectDelegation}
onDeleteDelegation={handleDeleteDelegation}
onNodeClick={onNodeClick}
/>
)}
{viewMode === 'summary' && selectedDelegation && (
<DelegationSummaryView
delegation={selectedDelegation}
onBack={handleBack}
onNodeClick={onNodeClick}
/>
)}
{viewMode === 'detail' && selectedDelegation && (
<DelegationDetailView
delegation={selectedDelegation}
openTabsData={openTabsData}
activeTabId={activeTabId}
activeDimension={activeDimension}
onNodeClick={onNodeClick}
delegations={delegations}
messages={getDelegationMessages(selectedDelegation.sessionId)}
setMessages={setDelegationMessagesFor(selectedDelegation.sessionId)}
onBack={handleBack}
/>
)}
<WorkflowsListView />
</div>
<style jsx>{`
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
`}</style>
</div>
);
}
// Workflows list view
function WorkflowsListView({
delegations,
onSelectDelegation,
onDeleteDelegation,
onNodeClick
}: {
delegations: AgentDelegation[];
onSelectDelegation: (sessionId: string) => void;
onDeleteDelegation: (sessionId: string) => void;
onNodeClick?: (nodeId: number) => void;
}) {
const activeDelegations = delegations.filter(d => d.status === 'queued' || d.status === 'in_progress');
const completedDelegations = delegations.filter(d => d.status === 'completed' || d.status === 'failed');
const getStatusInfo = (delegation: AgentDelegation) => {
const isWiseRAH = delegation.agentType === 'wise-rah';
let color = '#6b6b6b';
let label = 'Queued';
if (delegation.status === 'in_progress') {
color = isWiseRAH ? '#8b5cf6' : '#22c55e';
label = 'Running';
} else if (delegation.status === 'completed') {
color = '#22c55e';
label = 'Done';
} else if (delegation.status === 'failed') {
color = '#ff6b6b';
label = 'Failed';
}
return { color, label };
};
// Workflows list view - simplified for rah-light (delegation system removed)
function WorkflowsListView() {
return (
<div style={{
height: '100%',
@@ -184,394 +60,33 @@ function WorkflowsListView({
}}>
Workflows
</span>
{activeDelegations.length > 0 && (
<span style={{
color: '#22c55e',
fontSize: '11px',
fontWeight: 500
}}>
{activeDelegations.length} running
</span>
)}
</div>
{/* List */}
{/* Content */}
<div style={{
flex: 1,
overflow: 'auto',
padding: '12px'
}}>
{delegations.length === 0 ? (
<div style={{
color: '#666',
fontSize: '12px',
textAlign: 'center',
padding: '40px 20px'
}}>
No workflows yet. Use Quick Capture or ask RA-H to run a workflow.
</div>
) : (
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
{activeDelegations.map((delegation) => {
const { color, label } = getStatusInfo(delegation);
return (
<WorkflowCard
key={delegation.sessionId}
delegation={delegation}
statusColor={color}
statusLabel={label}
onSelect={() => onSelectDelegation(delegation.sessionId)}
onDelete={() => onDeleteDelegation(delegation.sessionId)}
onNodeClick={onNodeClick}
/>
);
})}
{activeDelegations.length > 0 && completedDelegations.length > 0 && (
<div style={{
height: '1px',
background: '#1f1f1f',
margin: '8px 0'
}} />
)}
{completedDelegations.map((delegation) => {
const { color, label } = getStatusInfo(delegation);
return (
<WorkflowCard
key={delegation.sessionId}
delegation={delegation}
statusColor={color}
statusLabel={label}
onSelect={() => onSelectDelegation(delegation.sessionId)}
onDelete={() => onDeleteDelegation(delegation.sessionId)}
onNodeClick={onNodeClick}
/>
);
})}
</div>
)}
</div>
</div>
);
}
// Individual workflow card
function WorkflowCard({
delegation,
statusColor,
statusLabel,
onSelect,
onDelete,
onNodeClick
}: {
delegation: AgentDelegation;
statusColor: string;
statusLabel: string;
onSelect: () => void;
onDelete: () => void;
onNodeClick?: (nodeId: number) => void;
}) {
const isActive = delegation.status === 'in_progress' || delegation.status === 'queued';
return (
<div
onClick={onSelect}
style={{
padding: '14px 16px',
background: '#151515',
border: '1px solid #1f1f1f',
borderRadius: '8px',
cursor: 'pointer',
transition: 'all 0.15s ease',
position: 'relative'
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = '#1a1a1a';
e.currentTarget.style.borderColor = '#2a2a2a';
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = '#151515';
e.currentTarget.style.borderColor = '#1f1f1f';
}}
>
<div style={{
padding: '12px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: '8px',
marginBottom: '8px'
justifyContent: 'center',
gap: '16px'
}}>
<div style={{
width: '8px',
height: '8px',
borderRadius: '50%',
background: statusColor,
animation: isActive ? 'pulse 2s infinite' : 'none'
}} />
<span style={{
color: statusColor,
fontSize: '11px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.05em'
}}>
{statusLabel}
</span>
<span style={{
color: '#555',
fontSize: '11px',
marginLeft: 'auto'
}}>
{new Date(delegation.createdAt).toLocaleTimeString()}
</span>
<button
onClick={(e) => {
e.stopPropagation();
onDelete();
}}
style={{
background: 'none',
border: 'none',
color: '#444',
cursor: 'pointer',
padding: '2px 6px',
fontSize: '14px',
lineHeight: 1
}}
onMouseEnter={(e) => e.currentTarget.style.color = '#ff6b6b'}
onMouseLeave={(e) => e.currentTarget.style.color = '#444'}
>
×
</button>
</div>
<div style={{
color: '#e5e5e5',
fontSize: '12px',
lineHeight: '1.4',
overflow: 'hidden',
textOverflow: 'ellipsis',
display: '-webkit-box',
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical'
}}>
{delegation.task}
</div>
{delegation.summary && delegation.status === 'completed' && (
<div style={{
color: '#666',
fontSize: '11px',
marginTop: '8px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
}}>
{parseAndRenderContent(delegation.summary, onNodeClick)}
</div>
)}
</div>
);
}
// Summary view for completed delegations
function DelegationSummaryView({
delegation,
onBack,
onNodeClick
}: {
delegation: AgentDelegation;
onBack?: () => void;
onNodeClick?: (nodeId: number) => void;
}) {
const isSuccess = delegation.status === 'completed';
const statusColor = isSuccess ? '#22c55e' : '#ff6b6b';
const statusLabel = isSuccess ? 'Completed' : 'Failed';
return (
<div style={{
height: '100%',
display: 'flex',
flexDirection: 'column',
background: 'transparent',
padding: '24px'
}}>
<div style={{
display: 'flex',
alignItems: 'center',
gap: '12px',
marginBottom: '24px',
paddingBottom: '16px',
borderBottom: '1px solid #1a1a1a'
}}>
{onBack && (
<button
onClick={onBack}
style={{
background: 'none',
border: 'none',
color: '#666',
cursor: 'pointer',
padding: '4px',
display: 'flex',
alignItems: 'center',
fontSize: '14px'
}}
>
</button>
)}
<div style={{
width: '10px',
height: '10px',
borderRadius: '50%',
background: statusColor
}} />
<span style={{
color: statusColor,
fontSize: '12px',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.08em'
}}>
{statusLabel}
</span>
<span style={{
color: '#666',
fontSize: '11px',
marginLeft: 'auto'
}}>
{new Date(delegation.updatedAt).toLocaleString()}
</span>
</div>
<div style={{ marginBottom: '20px' }}>
<div style={{
color: '#666',
fontSize: '10px',
textTransform: 'uppercase',
letterSpacing: '0.1em',
marginBottom: '8px'
}}>
Task
</div>
<div style={{
color: '#e5e5e5',
fontSize: '13px',
lineHeight: '1.5'
}}>
{delegation.task}
</div>
</div>
{delegation.summary && (
<div style={{ flex: 1 }}>
<div style={{
color: '#666',
fontSize: '10px',
textTransform: 'uppercase',
letterSpacing: '0.1em',
marginBottom: '8px'
}}>
Result
</div>
<div style={{
color: isSuccess ? '#a8a8a8' : '#fca5a5',
fontSize: '13px',
lineHeight: '1.6',
whiteSpace: 'pre-wrap'
}}>
{parseAndRenderContent(delegation.summary || '', onNodeClick)}
</div>
</div>
)}
{!delegation.summary && (
<div style={{
color: '#666',
fontSize: '12px',
fontStyle: 'italic'
textAlign: 'center',
padding: '40px 20px',
maxWidth: '300px'
}}>
No details available
<p style={{ marginBottom: '16px' }}>
Workflows are available via MCP server integration.
</p>
<p style={{ color: '#555', fontSize: '11px' }}>
Connect your coding agent (Claude Code, Cursor, etc.) via MCP to run workflows like Integrate, Extract, and more.
</p>
</div>
)}
</div>
);
}
// Detail view with chat
function DelegationDetailView({
delegation,
openTabsData,
activeTabId,
activeDimension,
onNodeClick,
delegations,
messages,
setMessages,
onBack
}: {
delegation: AgentDelegation;
openTabsData: any[];
activeTabId: number | null;
activeDimension?: string | null;
onNodeClick?: (nodeId: number) => void;
delegations: AgentDelegation[];
messages: ChatMessage[];
setMessages: (updater: (prev: ChatMessage[]) => ChatMessage[]) => void;
onBack: () => void;
}) {
return (
<div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
<div style={{
padding: '8px 12px',
borderBottom: '1px solid #1a1a1a',
display: 'flex',
alignItems: 'center',
gap: '8px',
background: 'transparent'
}}>
<button
onClick={onBack}
style={{
background: 'none',
border: 'none',
color: '#666',
cursor: 'pointer',
padding: '4px 8px',
display: 'flex',
alignItems: 'center',
gap: '4px',
fontSize: '12px'
}}
onMouseEnter={(e) => e.currentTarget.style.color = '#a8a8a8'}
onMouseLeave={(e) => e.currentTarget.style.color = '#666'}
>
Workflows
</button>
<span style={{ color: '#555', fontSize: '11px' }}>|</span>
<span style={{
color: delegation.status === 'in_progress' ? '#22c55e' : '#666',
fontSize: '11px',
textTransform: 'uppercase'
}}>
{delegation.status === 'in_progress' ? 'Running' : delegation.status}
</span>
</div>
<div style={{ flex: 1, overflow: 'hidden', minHeight: 0 }}>
<RAHChat
openTabsData={openTabsData}
activeTabId={activeTabId}
activeDimension={activeDimension}
onNodeClick={onNodeClick}
delegations={delegations}
messages={messages}
setMessages={setMessages}
mode="easy"
delegationMode={true}
delegationSessionId={delegation.sessionId}
/>
</div>
</div>
);