修复agents历史记录跳转

This commit is contained in:
2025-10-11 13:00:52 +08:00
parent 6aefec3312
commit e7775ce8ed
8 changed files with 53 additions and 40 deletions

View File

@@ -58,6 +58,7 @@ export function AgentRunOutputViewer({
tabId,
className
}: AgentRunOutputViewerProps) {
const { t } = useTranslation();
const { updateTabTitle, updateTabStatus } = useTabState();
const [run, setRun] = useState<AgentRunWithMetrics | null>(null);
@@ -143,25 +144,17 @@ export function AgentRunOutputViewer({
const loadOutput = async (skipCache = false) => {
if (!run?.id) return;
console.log('[AgentRunOutputViewer] Loading output for run:', {
runId: run.id,
status: run.status,
sessionId: run.session_id,
skipCache
});
try {
// Check cache first if not skipping cache
if (!skipCache) {
const cached = getCachedOutput(run.id);
if (cached) {
console.log('[AgentRunOutputViewer] Found cached output');
const cachedJsonlLines = cached.output.split('\n').filter(line => line.trim());
setRawJsonlOutput(cachedJsonlLines);
setMessages(cached.messages);
// If cache is recent (less than 5 seconds old) and session isn't running, use cache only
if (Date.now() - cached.lastUpdated < 5000 && run.status !== 'running') {
console.log('[AgentRunOutputViewer] Using recent cache, skipping refresh');
return;
}
}
@@ -171,10 +164,8 @@ export function AgentRunOutputViewer({
// If we have a session_id, try to load from JSONL file first
if (run.session_id && run.session_id !== '') {
console.log('[AgentRunOutputViewer] Attempting to load from JSONL with session_id:', run.session_id);
try {
const history = await api.loadAgentSessionHistory(run.session_id);
console.log('[AgentRunOutputViewer] Successfully loaded JSONL history:', history.length, 'messages');
// Convert history to messages format
const loadedMessages: ClaudeStreamMessage[] = history.map(entry => ({
@@ -195,29 +186,22 @@ export function AgentRunOutputViewer({
// Set up live event listeners for running sessions
if (run.status === 'running') {
console.log('[AgentRunOutputViewer] Setting up live listeners for running session');
setupLiveEventListeners();
try {
await api.streamSessionOutput(run.id);
} catch (streamError) {
console.warn('[AgentRunOutputViewer] Failed to start streaming, will poll instead:', streamError);
}
}
return;
} catch (err) {
console.warn('[AgentRunOutputViewer] Failed to load from JSONL:', err);
console.warn('[AgentRunOutputViewer] Falling back to regular output method');
// Fallback path will be used if JSONL loading fails
}
} else {
console.log('[AgentRunOutputViewer] No session_id available, using fallback method');
}
// Fallback to the original method if JSONL loading fails or no session_id
console.log('[AgentRunOutputViewer] Using getSessionOutput fallback');
const rawOutput = await api.getSessionOutput(run.id);
console.log('[AgentRunOutputViewer] Received raw output:', rawOutput.length, 'characters');
// Parse JSONL output into messages
const jsonlLines = rawOutput.split('\n').filter(line => line.trim());
@@ -232,7 +216,6 @@ export function AgentRunOutputViewer({
console.error("[AgentRunOutputViewer] Failed to parse message:", err, line);
}
}
console.log('[AgentRunOutputViewer] Parsed', parsedMessages.length, 'messages from output');
setMessages(parsedMessages);
// Update cache
@@ -245,13 +228,11 @@ export function AgentRunOutputViewer({
// Set up live event listeners for running sessions
if (run.status === 'running') {
console.log('[AgentRunOutputViewer] Setting up live listeners for running session (fallback)');
setupLiveEventListeners();
try {
await api.streamSessionOutput(run.id);
} catch (streamError) {
console.warn('[AgentRunOutputViewer] Failed to start streaming (fallback), will poll instead:', streamError);
}
}
} catch (error) {
@@ -285,7 +266,6 @@ export function AgentRunOutputViewer({
try {
// Skip messages during initial load phase
if (isInitialLoadRef.current) {
console.log('[AgentRunOutputViewer] Skipping message during initial load');
return;
}
@@ -403,7 +383,6 @@ export function AgentRunOutputViewer({
const success = await api.killAgentSession(run.id);
if (success) {
console.log(`[AgentRunOutputViewer] Successfully stopped agent session ${run.id}`);
setToast({ message: 'Agent execution stopped', type: 'success' });
// Clean up listeners
@@ -431,7 +410,6 @@ export function AgentRunOutputViewer({
// Refresh the output to get updated status
await loadOutput(true);
} else {
console.warn(`[AgentRunOutputViewer] Failed to stop agent session ${run.id} - it may have already finished`);
setToast({ message: 'Failed to stop agent - it may have already finished', type: 'error' });
}
} catch (err) {
@@ -828,4 +806,4 @@ export function AgentRunOutputViewer({
);
}
export default AgentRunOutputViewer;
export default AgentRunOutputViewer;

View File

@@ -98,12 +98,19 @@ export const AgentRunsList: React.FC<AgentRunsListProps> = ({
};
const handleRunClick = (run: AgentRunWithMetrics) => {
if (!run.id) {
console.error('[AgentRunsList] Cannot open run - no ID available:', run);
return;
}
// If there's a callback, use it (for full-page navigation)
if (onRunClick) {
onRunClick(run);
} else if (run.id) {
} else {
// Otherwise, open in new tab
createAgentTab(run.id.toString(), run.agent_name);
const tabId = createAgentTab(run.id.toString(), run.agent_name);
window.dispatchEvent(new CustomEvent('switch-to-tabs', { detail: { tabId } }));
}
};
@@ -215,4 +222,4 @@ export const AgentRunsList: React.FC<AgentRunsListProps> = ({
</>
);
};
};

View File

@@ -226,9 +226,12 @@ const TabPanel: React.FC<TabPanelProps> = ({ tab, isActive }) => {
);
case 'agent':
if (!tab.agentRunId) {
console.error('[TabContent] No agentRunId in tab:', tab);
return <div className="p-4">{t('messages.noAgentRunIdSpecified')}</div>;
}
return (
<AgentRunOutputViewer
agentRunId={tab.agentRunId}
@@ -317,6 +320,10 @@ export const TabContent: React.FC = () => {
const { tabs, activeTabId, createChatTab, findTabBySessionId, createClaudeFileTab, createAgentExecutionTab, createCreateAgentTab, createImportAgentTab, closeTab, updateTab } = useTabState();
const [hasInitialized, setHasInitialized] = React.useState(false);
// Debug: Monitor activeTabId changes
useEffect(() => {
}, [activeTabId, tabs]);
// Auto redirect to home when no tabs (but not on initial load)
useEffect(() => {
if (hasInitialized && tabs.length === 0) {

View File

@@ -93,7 +93,6 @@ const WebviewPreviewComponent: React.FC<WebviewPreviewProps> = ({
// Debug: Log initial URL on mount
useEffect(() => {
console.log('[WebviewPreview] Component mounted with initialUrl:', initialUrl, 'isMaximized:', isMaximized);
}, []);
// Focus management for full screen mode
@@ -127,7 +126,6 @@ const WebviewPreviewComponent: React.FC<WebviewPreviewProps> = ({
const urlObj = new URL(url.startsWith('http') ? url : `https://${url}`);
const finalUrl = urlObj.href;
console.log('[WebviewPreview] Navigating to:', finalUrl);
setCurrentUrl(finalUrl);
setInputUrl(finalUrl);
setHasError(false);
@@ -152,12 +150,10 @@ const WebviewPreviewComponent: React.FC<WebviewPreviewProps> = ({
const handleGoBack = () => {
// In real implementation, this would call webview.goBack()
console.log("Go back");
};
const handleGoForward = () => {
// In real implementation, this would call webview.goForward()
console.log("Go forward");
};
const handleRefresh = () => {
@@ -354,4 +350,4 @@ const WebviewPreviewComponent: React.FC<WebviewPreviewProps> = ({
);
};
export const WebviewPreview = React.memo(WebviewPreviewComponent);
export const WebviewPreview = React.memo(WebviewPreviewComponent);