diff --git a/apps/agent-tars/package.json b/apps/agent-tars/package.json index c0c7f5f1a..6d22e3c55 100644 --- a/apps/agent-tars/package.json +++ b/apps/agent-tars/package.json @@ -18,6 +18,7 @@ "build": "rimraf dist out && npm run typecheck && npm run build:reporter && electron-vite build && electron-forge make", "test": "vitest run", "publish:mac": "npm run build:reporter && electron-vite build && electron-forge publish --arch=universal --platform=darwin", + "dev:reporter": "vite dev", "build:reporter": "vite build" }, "peerDependencies": { diff --git a/apps/agent-tars/src/main/ipcRoutes/action.ts b/apps/agent-tars/src/main/ipcRoutes/action.ts index 256d4c7cc..0724973b6 100644 --- a/apps/agent-tars/src/main/ipcRoutes/action.ts +++ b/apps/agent-tars/src/main/ipcRoutes/action.ts @@ -140,15 +140,20 @@ export const actionRoute = t.router({ 'utf-8', ); const artifacts = await parseArtifacts(messages); - const reportContent = reportHtmlTemplate.replace( - ' ', - '', - ); + const reportContent = reportHtmlTemplate + .replace( + ' ', + '', + ) + .replace( + /.*?<\/title>/, + `<title>${messages?.[0]?.content || 'Agent TARS'}`, + ); if (reportApiUrl) { const tempPath = path.join( diff --git a/apps/agent-tars/src/renderer/index.html b/apps/agent-tars/src/renderer/index.html index 0c32fc61e..1585b0887 100644 --- a/apps/agent-tars/src/renderer/index.html +++ b/apps/agent-tars/src/renderer/index.html @@ -2,7 +2,7 @@ - Omega + Agent TARS Omega Agent has finished.'); + this.eventManager.addEndEvent('> Agent TARS has finished.'); } } diff --git a/apps/agent-tars/src/renderer/src/agent/mockEvents.ts b/apps/agent-tars/src/renderer/src/agent/mockEvents.ts index 874c7a1ae..227f1395d 100644 --- a/apps/agent-tars/src/renderer/src/agent/mockEvents.ts +++ b/apps/agent-tars/src/renderer/src/agent/mockEvents.ts @@ -1951,7 +1951,7 @@ export const events = [ id: 'f65c6a4d-3bab-4246-a4b1-f45344133518', type: 'end', content: { - message: '> Omega Agent has finished.', + message: '> Agent TARS Agent has finished.', }, timestamp: 1741906222166, }, diff --git a/apps/agent-tars/src/renderer/src/components/ChatUI/MenuHeader.tsx b/apps/agent-tars/src/renderer/src/components/ChatUI/MenuHeader.tsx index 6e29c16cd..5a5f829a7 100644 --- a/apps/agent-tars/src/renderer/src/components/ChatUI/MenuHeader.tsx +++ b/apps/agent-tars/src/renderer/src/components/ChatUI/MenuHeader.tsx @@ -36,7 +36,7 @@ export function MenuHeader() {
- Omega + Agent TARS diff --git a/apps/agent-tars/src/renderer/src/components/ChatUI/Replay.tsx b/apps/agent-tars/src/renderer/src/components/ChatUI/Replay.tsx index f4173f8fd..5bf5585ff 100644 --- a/apps/agent-tars/src/renderer/src/components/ChatUI/Replay.tsx +++ b/apps/agent-tars/src/renderer/src/components/ChatUI/Replay.tsx @@ -6,6 +6,7 @@ import { ChatMessageUtil } from '@renderer/utils/ChatMessageUtils'; import { atom, useAtom } from 'jotai'; import { useState, useEffect, useRef } from 'react'; import { FiRotateCw, FiPause, FiPlay } from 'react-icons/fi'; +import { isReportHtmlMode } from '@renderer/constants'; type ButtonState = 'replay' | 'pause' | 'continue'; @@ -35,6 +36,9 @@ const BUTTON_CONFIGS: Record = { const replayAllMessages = atom([]); +// wait 3s to replay +const DEFAULT_COUNTDOWN = 3; + export function Replay() { const [allMessages, setAllMessages] = useAtom(replayAllMessages); const [, setEvents] = useAtom(eventsAtom); @@ -42,7 +46,9 @@ export function Replay() { const { addMessage, updateMessage, setMessages, messageEndRef, messages } = useAppChat(); const timerRef = useRef(); + const intervalRef = useRef(); const [buttonState, setButtonState] = useState('replay'); + const [countdown, setCountdown] = useState(DEFAULT_COUNTDOWN); const playbackRef = useRef<{ currentIndex: number; eventIndex: number; @@ -55,10 +61,37 @@ export function Replay() { } }; + const clearCountDownInterval = () => { + setCountdown(0); + if (intervalRef.current) { + clearInterval(intervalRef.current); + intervalRef.current = undefined; + } + }; + useEffect(() => { - return () => clearPlayTimer(); + return () => { + clearPlayTimer(); + clearCountDownInterval(); + }; }, []); + useEffect(() => { + if (isReportHtmlMode && allMessages.length) { + intervalRef.current = setInterval(() => { + setCountdown((prevCountdown) => { + if (prevCountdown > 1) { + return prevCountdown - 1; + } else { + clearCountDownInterval(); + handleTogglePlay(); + return 0; + } + }); + }, 1000); + } + }, [allMessages]); + useEffect(() => { if (allMessages.length === 0 && messages.length !== 0) { setAllMessages(messages); @@ -131,6 +164,7 @@ export function Replay() { }; const handleTogglePlay = () => { + clearCountDownInterval(); switch (buttonState) { case 'replay': case 'continue': @@ -146,15 +180,22 @@ export function Replay() { const currentConfig = BUTTON_CONFIGS[buttonState]; return ( - + > + {currentConfig.icon} + {currentConfig.label} + + {isReportHtmlMode && countdown > 0 && ( +

+ start replay in {countdown} seconds +

+ )} +
); } diff --git a/apps/agent-tars/src/renderer/src/components/LeftSidebar/TopBar.tsx b/apps/agent-tars/src/renderer/src/components/LeftSidebar/TopBar.tsx index 73605aad4..8145c740e 100644 --- a/apps/agent-tars/src/renderer/src/components/LeftSidebar/TopBar.tsx +++ b/apps/agent-tars/src/renderer/src/components/LeftSidebar/TopBar.tsx @@ -19,7 +19,7 @@ export function TopBar({ }: TopBarProps) { return (
- {!isCollapsed && Agent Tars} + {!isCollapsed && Agent TARS}
diff --git a/apps/agent-tars/vite.config.ts b/apps/agent-tars/vite.config.ts index 3a9c44771..4bf7548b1 100644 --- a/apps/agent-tars/vite.config.ts +++ b/apps/agent-tars/vite.config.ts @@ -5,7 +5,6 @@ import react from '@vitejs/plugin-react'; import { viteSingleFile } from 'vite-plugin-singlefile'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const workspaceDeps = ['@ui-tars/electron-ipc']; export default defineConfig( (async () => {