Merge branch 'main' into 621-bug-react-warning-confirmbuttondisabled-prop-passed-to-dom-element

This commit is contained in:
Wendong-Fan 2025-11-13 20:08:44 +08:00 committed by GitHub
commit a5e35d6f03
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 716 additions and 145 deletions

View file

@ -1180,57 +1180,57 @@ async function createWindow() {
// Handle localStorage based on installation state
if (needsInstallation) {
log.info('Installation needed - clearing auth storage to force carousel state');
// Clear the persisted auth storage file to force fresh initialization with carousel
// Main window uses partition 'persist:main_window', so data is in Partitions/main_window
const partitionPath = path.join(app.getPath('userData'), 'Partitions', 'main_window');
const localStoragePath = path.join(partitionPath, 'Local Storage');
const leveldbPath = path.join(localStoragePath, 'leveldb');
try {
// Delete the localStorage database to force fresh init
if (fs.existsSync(leveldbPath)) {
log.info('Removing localStorage database to force fresh state...');
fs.rmSync(leveldbPath, { recursive: true, force: true });
log.info('Successfully cleared localStorage');
}
} catch (error) {
log.error('Error clearing localStorage:', error);
}
log.info('Installation needed - resetting initState to carousel while preserving auth data');
// Instead of deleting the entire localStorage, we'll update only the initState
// This preserves login information while resetting the initialization flow
// Set up the injection for when page loads
win.webContents.once('dom-ready', () => {
if (!win || win.isDestroyed()) {
log.warn('Window destroyed before DOM ready - skipping localStorage injection');
return;
}
log.info('DOM ready - creating auth-storage with carousel state');
log.info('DOM ready - updating initState to carousel while preserving auth data');
win.webContents.executeJavaScript(`
(function() {
try {
// Create fresh auth storage with carousel state
const newAuthStorage = {
state: {
token: null,
username: null,
email: null,
user_id: null,
appearance: 'light',
language: 'system',
isFirstLaunch: true,
modelType: 'cloud',
cloud_model_type: 'gpt-4.1',
initState: 'carousel',
share_token: null,
workerListData: {}
},
version: 0
};
localStorage.setItem('auth-storage', JSON.stringify(newAuthStorage));
console.log('[ELECTRON PRE-INJECT] Created fresh auth-storage with carousel state');
const authStorage = localStorage.getItem('auth-storage');
if (authStorage) {
// Preserve existing auth data, only update initState
const parsed = JSON.parse(authStorage);
const updatedStorage = {
...parsed,
state: {
...parsed.state,
initState: 'carousel'
}
};
localStorage.setItem('auth-storage', JSON.stringify(updatedStorage));
console.log('[ELECTRON PRE-INJECT] Updated initState to carousel, preserved auth data');
} else {
// No existing storage, create new one with carousel state
const newAuthStorage = {
state: {
token: null,
username: null,
email: null,
user_id: null,
appearance: 'light',
language: 'system',
isFirstLaunch: true,
modelType: 'cloud',
cloud_model_type: 'gpt-4.1',
initState: 'carousel',
share_token: null,
workerListData: {}
},
version: 0
};
localStorage.setItem('auth-storage', JSON.stringify(newAuthStorage));
console.log('[ELECTRON PRE-INJECT] Created fresh auth-storage with carousel state');
}
} catch (e) {
console.error('[ELECTRON PRE-INJECT] Failed to create storage:', e);
console.error('[ELECTRON PRE-INJECT] Failed to update storage:', e);
}
})();
`).catch(err => {
@ -1282,9 +1282,9 @@ async function createWindow() {
}
})();
`).then(needsReload => {
if (needsReload) {
if (needsReload && win && !win.isDestroyed()) {
log.info('Reloading window after localStorage update');
win!.reload();
win.reload();
}
}).catch(err => {
log.error('Failed to inject script:', err);

View file

@ -102,7 +102,6 @@ export default function ChatBox(): JSX.Element {
const task = chatStore.tasks[_taskId];
const isTaskBusy = (
// running or paused counts as busy
// TODO: Bug where when replay end hasMessages = false & status = running
(task.status === 'running' && !task.hasMessages) || task.status === 'pause' ||
// splitting phase: has to_sub_tasks not confirmed OR skeleton computing
task.messages.some(m => m.step === 'to_sub_tasks' && !m.isConfirm) ||
@ -111,6 +110,10 @@ export default function ChatBox(): JSX.Element {
(!!task.messages.find(m => m.step === 'to_sub_tasks' && !m.isConfirm) && task.status === 'pending')
);
//Fixes bug where doesn't matter the SSE order or final state of the chatStore
const isReplayChatStore = chatStore.tasks[_taskId as string]?.type === "replay";
const queueTask = isTaskBusy && !isReplayChatStore;
console.log(`Current task is ${isTaskBusy} with ${task}`);
if (textareaRef.current) textareaRef.current.style.height = "60px";
@ -152,7 +155,7 @@ export default function ChatBox(): JSX.Element {
}
} else {
// If current task is busy (splitting/confirm/running), queue the new message instead of sending immediately
if (isTaskBusy) {
if (queueTask) {
const project_id = projectStore.activeProjectId;
// Queue the message locally; do not send to backend yet.
const currentAttaches = JSON.parse(JSON.stringify(task.attaches)) || [];

View file

@ -332,7 +332,7 @@ export function Node({ id, data }: NodeProps) {
? `${agentMap[data.type]?.borderColor} z-50`
: "border-worker-border-default z-10"
} transition-all duration-300 ease-in-out ${
data.agent?.tasks.length === 0 && "opacity-30"
(data.agent?.tasks?.length ?? 0) === 0 && "opacity-30"
}`}
>
<div
@ -451,13 +451,15 @@ export function Node({ id, data }: NodeProps) {
)}
</div>
)}
{data.type === "document_agent" && (
<div className="overflow-hidden w-full h-[180px] rounded-sm relative">
<div className="absolute left-0 top-0 scale-[0.3] w-[500px] h-[500px] origin-top-left">
<Folder data={data.agent as Agent} />
{data.type === "document_agent" &&
data?.agent?.tasks &&
data.agent.tasks.length > 0 && (
<div className="overflow-hidden w-full h-[180px] rounded-sm relative">
<div className="absolute left-0 top-0 scale-[0.3] w-[500px] h-[500px] origin-top-left">
<Folder data={data.agent as Agent} />
</div>
</div>
</div>
)}
)}
{data.type === "developer_agent" &&
data?.agent?.tasks &&

View file

@ -1,3 +1,5 @@
import { ChatStore } from "@/store/chatStore";
import { ProjectStore } from "@/store/projectStore";
import { NavigateFunction } from "react-router-dom";
/**
@ -11,7 +13,7 @@ import { NavigateFunction } from "react-router-dom";
* @param historyId - The history ID for the replay
*/
export const replayProject = async (
projectStore: any,
projectStore: ProjectStore,
navigate: NavigateFunction,
projectId: string,
question: string,
@ -36,8 +38,8 @@ export const replayProject = async (
* @param navigate - The navigate function from useNavigate hook
*/
export const replayActiveTask = async (
chatStore: any,
projectStore: any,
chatStore: ChatStore,
projectStore: ProjectStore,
navigate: NavigateFunction
) => {
const taskId = chatStore.activeTaskId as string;
@ -57,9 +59,10 @@ export const replayActiveTask = async (
if (project && project.chatStores) {
Object.entries(project.chatStores).forEach(([chatStoreId, chatStoreData]: [string, any]) => {
const timestamp = project.chatStoreTimestamps[chatStoreId] || 0;
if (chatStoreData.tasks) {
Object.values(chatStoreData.tasks).forEach((task: any) => {
const chatState = chatStoreData.getState();
if (chatState.tasks) {
Object.values(chatState.tasks).forEach((task: any) => {
// Check messages for user content
if (task.messages && task.messages.length > 0) {
const userMessage = task.messages.find((msg: any) => msg.role === 'user');
@ -68,33 +71,6 @@ export const replayActiveTask = async (
earliestTimestamp = timestamp;
}
}
// Check task info for original questions
if (task.taskInfo && task.taskInfo.length > 0) {
task.taskInfo.forEach((info: any) => {
if (info.content && timestamp < earliestTimestamp) {
question = info.content;
earliestTimestamp = timestamp;
}
});
}
// Check agent logs for original task content
if (task.taskAssigning) {
task.taskAssigning.forEach((agent: any) => {
if (agent.log) {
agent.log.forEach((logEntry: any) => {
if (logEntry.data && logEntry.data.message) {
const match = logEntry.data.message.match(/==============================\n(.*?)\n==============================/s);
if (match && match[1] && timestamp < earliestTimestamp) {
question = match[1].trim();
earliestTimestamp = timestamp;
}
}
});
}
});
}
});
}
});
@ -103,6 +79,7 @@ export const replayActiveTask = async (
// Fallback to current task's first message if no question found
if (!question && chatStore.tasks[taskId] && chatStore.tasks[taskId].messages[0]) {
question = chatStore.tasks[taskId].messages[0].content;
console.log("[REPLAY] question fall back to ", question);
}
const historyId = projectStore.getHistoryId(projectId);

View file

@ -196,7 +196,8 @@ const projectStore = create<ProjectStore>()((set, get) => ({
queuedMessages: [], // Initialize empty queued messages array
metadata: {
status: 'active',
historyId: historyId
historyId: historyId,
tags: type === ProjectType.REPLAY ? ["replay"] : []
}
};
@ -472,27 +473,34 @@ const projectStore = create<ProjectStore>()((set, get) => ({
}
console.log(`[ProjectStore] Created replay project ${replayProjectId} for ${taskIds.length} tasks`);
// For each taskId, create a chat store within the project and call replay
taskIds.forEach(async (taskId, index) => {
console.log(`[ProjectStore] Creating replay for task ${index + 1}/${taskIds.length}: ${taskId}`);
// Create a new chat store for this task
const chatId = createChatStore(replayProjectId, `Task ${taskId}`);
if (chatId) {
const project = get().projects[replayProjectId];
const chatStore = project.chatStores[chatId];
if (chatStore) {
// Call replay on the chat store with the taskId, question, and 0 delay
await chatStore.getState().replay(taskId, question, 0.2);
console.log(`[ProjectStore] Started replay for task ${taskId}`);
(async () => {
for (let index = 0; index < taskIds.length; index++) {
const taskId = taskIds[index];
console.log(`[ProjectStore] Creating replay for task ${index + 1}/${taskIds.length}: ${taskId}`);
// Create a new chat store for this task
const chatId = createChatStore(replayProjectId, `Task ${taskId}`);
if (chatId) {
const project = get().projects[replayProjectId];
const chatStore = project.chatStores[chatId];
if (chatStore) {
// Call replay on the chat store with the taskId, question, and 0 delay
try {
await chatStore.getState().replay(taskId, question, 0.2);
console.log(`[ProjectStore] Started replay for task ${taskId}`);
} catch (error) {
console.error(`[ProjectStore] Failed to replay task ${taskId}:`, error);
}
}
}
}
});
console.log(`[ProjectStore] Completed replay setup for ${taskIds.length} tasks`);
console.log(`[ProjectStore] Completed replay setup for ${taskIds.length} tasks`);
})();
return replayProjectId;
},

View file

@ -13,26 +13,7 @@ import '../../../src/store/chatStore'
import { useProjectStore } from '../../../src/store/projectStore'
import useChatStoreAdapter from '../../../src/hooks/useChatStoreAdapter'
import { mockFetchEventSource } from '../../mocks/sse.mock'
// Helper function for sequential SSE events
const createSSESequence = (events: Array<{ event: any; delay: number }>) => {
return async (onMessage: (data: any) => void) => {
for (let i = 0; i < events.length; i++) {
const { event, delay } = events[i]
await new Promise<void>((resolve) => {
setTimeout(() => {
console.log(`Sending SSE Event ${i + 1}:`, event.step);
onMessage({
data: JSON.stringify(event)
})
resolve()
}, delay)
})
}
}
}
import { mockFetchEventSource, createSSESequence } from '../../mocks/sse.mock'
// Mock electron IPC
(global as any).ipcRenderer = {

View file

@ -13,27 +13,8 @@ import '../../../src/store/chatStore'
import { useProjectStore } from '../../../src/store/projectStore'
import useChatStoreAdapter from '../../../src/hooks/useChatStoreAdapter'
import { mockFetchEventSource } from '../../mocks/sse.mock'
import { replayProject } from '../../../src/lib'
// Helper function for sequential SSE events
const createSSESequence = (events: Array<{ event: any; delay: number }>) => {
return async (onMessage: (data: any) => void) => {
for (let i = 0; i < events.length; i++) {
const { event, delay } = events[i]
await new Promise<void>((resolve) => {
setTimeout(() => {
console.log(`Sending SSE Event ${i + 1}:`, event.step);
onMessage({
data: JSON.stringify(event)
})
resolve()
}, delay)
})
}
}
}
import { createSSESequence, issue619SseSequence, mockFetchEventSource } from '../../mocks/sse.mock'
import { replayProject, replayActiveTask } from '../../../src/lib'
// Mock navigate function
const mockNavigate = vi.fn() as any
@ -523,4 +504,304 @@ describe('Integration Test: Replay Functionality', () => {
console.log('Both tasks ran independently with separate chatStores')
}, { timeout: 3000 })
})
})
//https://github.com/eigent-ai/eigent/issues/619 - Two task boxes
describe('Issue #619 - Duplicate Task Boxes after replay', () => {
beforeEach(() => {
vi.clearAllMocks();
const { result } = renderHook(() => useProjectStore());
//Reset projectStore
result.current.getAllProjects().forEach(project => {
result.current.removeProject(project.id)
})
})
afterEach(() => {
vi.clearAllMocks()
})
it("should create a separate chatStore for each replay", async () => {
const { result, rerender } = renderHook(() => useChatStoreAdapter())
let sseCallCount = 0
// Step 0: First simulate a replay mechanism to set up the scenario
const replaySequence = createSSESequence([
{
event: {
step: 'confirmed',
data: { question: 'Previous calendar task replay' }
},
delay: 50
},
{
event: {
step: 'to_sub_tasks',
data: {
summary_task: 'Calendar Replay|Previous calendar interaction',
sub_tasks: [
{ id: 'replay-cal-1', content: 'Check calendar access', status: 'completed' },
{ id: 'replay-cal-2', content: 'Fetch meeting data', status: 'completed' },
],
},
},
delay: 100
},
{
event: {
step: "end",
data: "--- Previous Calendar Task Replay Complete ---\nFound 3 upcoming meetings"
},
delay: 150
}
])
// Mock SSE stream with controlled events - delay setup until after task IDs are available
mockFetchEventSource.mockImplementation(async (url: string, options: any) => {
sseCallCount++
console.log(`SSE Call #${sseCallCount} initiated`)
if (options.onmessage) {
// First simulate replay of previous event to establish context
if (sseCallCount === 1 && url.includes('/api/chat/steps/playback/')) {
console.log('Simulating replay mechanism for previous calendar task')
await replaySequence(options.onmessage)
return
}
// Now send the new task events with actual task IDs
const immediateSequence = createSSESequence(issue619SseSequence)
await immediateSequence(options.onmessage)
}
})
// Simulate the replay mechanism first
console.log('Starting replay simulation to establish context...')
await act(async () => {
await replayProject(
result.current.projectStore,
mockNavigate,
generateUniqueId(),
'Previous calendar task replay',
'calendar-replay-history'
)
rerender()
})
// Wait for replay to complete and verify it's established
await waitFor(() => {
rerender()
const { projectStore } = result.current
const projects = projectStore.getAllProjects()
const replayProject = projects.find((p: any) => p.name.includes('Replay Project'))
expect(replayProject).toBeDefined()
console.log('Replay mechanism completed - context established')
}, { timeout: 1000 })
// Get initial state
const { chatStore: initialChatStore, projectStore } = result.current
const projectId = projectStore.activeProjectId as string
const initiatorTaskId = initialChatStore.activeTaskId
// Verify initial queue is empty
expect(projectStore.getProjectById(projectId)?.queuedMessages).toEqual([])
// Step 1: Start first task
await act(async () => {
const userMessage = 'Please help me check Google Calendar when is the next meeting, what kind of meeting it is, and who is attending the meeting.'
await initialChatStore.startTask(initiatorTaskId, undefined, undefined, undefined, userMessage)
rerender()
})
// Wait for task to start and reach 'to_sub_tasks' phase (task becomes busy)
await waitFor(() => {
rerender()
const { chatStore, projectStore } = result.current
const taskId = chatStore.activeTaskId
const task = chatStore.tasks[taskId]
// Task should have subtasks (making it busy)
expect(task.summaryTask).toBe('Task|Please help me check Google Calendar when is the next meeting, what kind of meeting it is, and who is attending the meeting.')
console.log("Task info is ", task.taskInfo);
//Bcz of newTaskInfo { id: '', content: '', status: '' } we have 2 items
expect(task.taskInfo).toHaveLength(2)
console.log("Task reached to_sub_tasks phase - now busy")
}, { timeout: 1500 })
//Waitfor end sse
await waitFor(() => {
rerender()
const { chatStore: finalChatStore, projectStore: finalProjectStore } = result.current;
const finalTaskId = finalChatStore.activeTaskId;
const finalTask = finalChatStore.tasks[finalTaskId];
expect(finalTask.status).toBe('finished');
}, { timeout: 10000 });
// Step 7: Verify final state
const { chatStore: finalChatStore, projectStore: finalProjectStore } = result.current
const finalProject = finalProjectStore.getProjectById(projectId)
// Verify task completed successfully
const finalTaskId = finalChatStore.activeTaskId
const finalTask = finalChatStore.tasks[finalTaskId]
expect(finalTask.status).toBe('finished')
expect(finalTask.summaryTask).toBe('Task|Please help me check Google Calendar when is the next meeting, what kind of meeting it is, and who is attending the meeting.')
console.log("Test completed - queue management verified: one task processed, one remains")
})
it("should have correct first question on replayActiveTask", async () => {
const { result, rerender } = renderHook(() => useChatStoreAdapter())
const projectStoreResult = renderHook(() => useProjectStore())
let sseCallCount = 0
const originalUserMessage = 'Please help me check Google Calendar when is the next meeting, what kind of meeting it is, and who is attending the meeting.'
// Step 1: Create initial task with specific user message
const initialSequence = createSSESequence([
{
event: {
step: 'confirmed',
data: { question: originalUserMessage }
},
delay: 100
},
{
event: {
step: 'to_sub_tasks',
data: {
summary_task: 'Calendar Task|Check upcoming Google Calendar meetings',
sub_tasks: [
{ id: 'cal-1', content: 'Access Google Calendar', status: 'completed' },
{ id: 'cal-2', content: 'Fetch meeting details', status: 'completed' },
],
},
},
delay: 200
},
{
event: {
step: "end",
data: "--- Calendar Task Complete ---\nFound your next meeting: Team Standup at 2:00 PM"
},
delay: 300
}
])
// Step 2: Setup replay sequence that should have same first question
const replaySequence = createSSESequence([
{
event: {
step: 'confirmed',
data: { question: "Fall Back question" }
},
delay: 100
},
{
event: {
step: 'to_sub_tasks',
data: {
summary_task: 'Calendar Task Replay|Replaying calendar meeting check',
sub_tasks: [
{ id: 'replay-cal-1', content: 'Access Google Calendar (replay)', status: 'completed' },
{ id: 'replay-cal-2', content: 'Fetch meeting details (replay)', status: 'completed' },
],
},
},
delay: 200
},
{
event: {
step: "end",
data: "--- Calendar Task Replay Complete ---\nReplayed: Found your next meeting"
},
delay: 300
}
])
// Mock SSE to handle both initial task and replay
mockFetchEventSource.mockImplementation(async (url: string, options: any) => {
sseCallCount++
console.log(`SSE Call #${sseCallCount}: ${url}`)
if (options.onmessage) {
if (sseCallCount === 1) {
// First call: initial task
console.log('Processing initial task events')
await initialSequence(options.onmessage)
} else if (url.includes('/api/chat/steps/playback/')) {
// Subsequent calls: replay
console.log('Processing replay events')
await replaySequence(options.onmessage)
}
}
})
// Step 3: Start initial task
await act(async () => {
const { chatStore } = result.current
const taskId = chatStore.activeTaskId
await chatStore.startTask(taskId, undefined, undefined, undefined, originalUserMessage)
rerender()
})
// Wait for initial task to complete
await waitFor(() => {
rerender()
const { chatStore } = result.current
const taskId = chatStore.activeTaskId
const task = chatStore.tasks[taskId]
expect(task.status).toBe('finished')
expect(task.messages[0].content).toBe(originalUserMessage)
console.log('Initial task completed with user message:', task.messages[0].content)
}, { timeout: 2000 })
// Step 4: Get the completed chatStore for replay
const { chatStore: completedChatStore, projectStore } = result.current
const completedTaskId = completedChatStore.activeTaskId
const completedTask = completedChatStore.tasks[completedTaskId]
// Verify we have the correct initial state
expect(completedTask.messages[0].content).toBe(originalUserMessage)
expect(completedTask.status).toBe('finished')
// Step 5: Call replayActiveTask using the completed chatStore
await act(async () => {
await replayActiveTask(completedChatStore, projectStore, mockNavigate)
rerender()
})
// Step 6: Wait for replay to complete and verify first question matches
await waitFor(() => {
rerender()
const { projectStore: updatedProjectStore } = result.current
const projects = updatedProjectStore.getAllProjects()
// Find the replay project
const replayProject = projects.find((p: any) => p.name.includes('Replay Project'))
expect(replayProject).toBeDefined()
// Get the replay chatStore
const replayChatStores = updatedProjectStore.getAllChatStores(replayProject!.id)
expect(replayChatStores.length).toBeGreaterThan(1)
const replayChatStore = replayChatStores[1].chatStore // Skip the empty initial one
const replayTaskId = replayChatStore.getState().activeTaskId
const replayTask = replayChatStore.getState().tasks[replayTaskId]
// THE MAIN TEST: First question in replay should match original user message
expect(replayTask).toBeDefined()
expect(replayTask.messages[0].content).toBe(originalUserMessage)
expect(replayTask.type).toBe('replay')
console.log('✅ Replay first question matches original:', replayTask.messages[0].content)
console.log('✅ Original user message:', originalUserMessage)
console.log('✅ Test passed: replayActiveTask preserves correct first question')
}, { timeout: 3000 })
// Verify navigation was called for replay
expect(mockNavigate).toHaveBeenCalledWith("/")
})
})

View file

@ -5,4 +5,323 @@ export const mockFetchEventSource = vi.fn()
vi.mock('@microsoft/fetch-event-source', () => ({
fetchEventSource: (...args: any[]) => mockFetchEventSource(...args),
}))
}))
// Helper function for sequential SSE events
export const createSSESequence = (events: Array<{ event: any; delay: number }>) => {
return async (onMessage: (data: any) => void) => {
for (let i = 0; i < events.length; i++) {
const { event, delay } = events[i]
await new Promise<void>((resolve) => {
setTimeout(() => {
console.log(`Sending SSE Event ${i + 1}:`, event.step);
onMessage({
data: JSON.stringify(event)
})
resolve()
}, delay)
})
}
}
}
// https://github.com/eigent-ai/eigent/issues/619 - Two task boxes
export const issue619SseSequence = [
{
event: {
step: 'confirmed',
data: { question: 'Please help me check Google Calendar when is the next meeting, what kind of meeting it is, and who is attending the meeting.' }
},
delay: 100
},
{
event: {
step: 'to_sub_tasks',
data: {
summary_task: 'Task|Please help me check Google Calendar when is the next meeting, what kind of meeting it is, and who is attending the meeting.',
sub_tasks: [
{
id: '1762503273000-2985.1',
content: 'Retrieve the details of the next scheduled event on the user\'s Google Calendar, including the start time, title of the meeting, and the list of all participants\' names and email addresses. Format the result as a JSON object with the keys: \'start_time\', \'meeting_title\', and \'participants\', where \'participants\' is an array of objects each with \'name\' and \'email\'.',
state: 'FAILED',
subtasks: []
}
]
}
},
delay: 100
},
{
event: {
step: 'deactivate_agent',
data: {
agent_name: 'question_confirm_agent',
agent_id: '3f9fff03-e95a-4ad6-a3d4-6bdd73b639c4',
process_task_id: '',
message: 'yes',
tokens: 357
}
},
delay: 100
},
{
event: {
step: 'create_agent',
data: {
agent_name: 'task_agent',
agent_id: '17cef41b-5158-40e8-b1e2-0a88777dddb4',
tools: []
}
},
delay: 100
},
{
event: {
step: 'create_agent',
data: {
agent_name: 'search_agent',
agent_id: 'c249ac7b-6745-4832-a5c1-3238f9176434',
tools: ['Search Toolkit', 'Browser Toolkit', 'Human Toolkit', 'Note Taking Toolkit', 'Terminal Toolkit']
}
},
delay: 100
},
{
event: {
step: 'deactivate_toolkit',
data: {
agent_name: 'search_agent',
process_task_id: '',
toolkit_name: 'Browser Toolkit',
method_name: 'register agent',
message: 'null'
}
},
delay: 100
},
{
event: {
step: 'create_agent',
data: {
agent_name: 'document_agent',
agent_id: 'e861cc5b-976b-41f0-a298-9c3e921ffaf5',
tools: ['File Toolkit', 'Pptx Toolkit', 'Human Toolkit', 'Mark It Down Toolkit', 'Excel Toolkit', 'Note Taking Toolkit', 'Terminal Toolkit', 'Google Drive Mcp Toolkit']
}
},
delay: 100
},
{
event: {
step: 'deactivate_toolkit',
data: {
agent_name: 'multi_modal_agent',
process_task_id: '',
toolkit_name: 'Open Ai Image Toolkit',
method_name: 'get openai credentials',
message: '[object Object]'
}
},
delay: 100
},
{
event: {
step: 'activate_toolkit',
data: {
agent_name: 'search_agent',
process_task_id: '',
toolkit_name: 'Browser Toolkit',
method_name: 'register agent',
message: 'ChatAgent(Search Agent, RoleType.ASSISTANT, gpt-5)'
}
},
delay: 100
},
{
event: {
step: 'create_agent',
data: {
agent_name: 'mcp_agent',
agent_id: 'd23a70fe-5c90-47bd-9170-f50defcd352a',
tools: []
}
},
delay: 100
},
{
event: {
step: 'activate_toolkit',
data: {
agent_name: 'search_agent',
process_task_id: '',
toolkit_name: 'Browser Toolkit',
method_name: 'register agent',
message: 'ChatAgent(Search Agent, RoleType.ASSISTANT, gpt-5)'
}
},
delay: 100
},
{
event: {
step: 'activate_agent',
data: {
agent_name: 'question_confirm_agent',
process_task_id: '',
agent_id: '3f9fff03-e95a-4ad6-a3d4-6bdd73b639c4',
message: '=== Previous Conversation ===\nPrevious Task: Please help me check Google Calendar when is the next meeting, what kind of meeting it is, and who is attending the meeting.\n\n\nUser Query: Please help me check Google Calendar when is the next meeting, what kind of meeting it is, and who is attending the meeting.\n\nDetermine if this user query is a complex task or a simple question.\n\nComplex task (answer "yes"): Requires tools, code execution, file operations, multi-step planning, or creating/modifying content\n- Examples: "create a file", "search for X", "implement feature Y", "write code", "analyze data", "build something"\n\nSimple question (answer "no"): Can be answered directly with knowledge or conversation history, no action needed\n- Examples: greetings ("hello", "hi"), fact queries ("what is X?"), clarifications ("what did you mean?"), status checks ("how are you?")\n\nAnswer only "yes" or "no". Do not provide any explanation.\n\nIs this a complex task? (yes/no):'
}
},
delay: 100
},
{
event: {
step: 'create_agent',
data: {
agent_name: 'coordinator_agent',
agent_id: '97326e19-91aa-4f9e-95ac-dbc1d92d3756',
tools: []
}
},
delay: 100
},
{
event: {
step: 'create_agent',
data: {
agent_name: 'new_worker_agent',
agent_id: '62eca7d0-ed56-4101-bd20-9c929d31590e',
tools: []
}
},
delay: 100
},
{
event: {
step: 'activate_toolkit',
data: {
agent_name: 'search_agent',
process_task_id: '',
toolkit_name: 'Browser Toolkit',
method_name: 'register agent',
message: 'ChatAgent(Search Agent, RoleType.ASSISTANT, gpt-4.1)'
}
},
delay: 100
},
{
event: {
step: 'create_agent',
data: {
agent_name: 'developer_agent',
agent_id: 'd7514c96-3414-4220-9a99-c08cbabc86b5',
tools: ['Human Toolkit', 'Terminal Toolkit', 'Note Taking Toolkit', 'Web Deploy Toolkit']
}
},
delay: 100
},
{
event: {
step: 'activate_toolkit',
data: {
agent_name: 'multi_modal_agent',
process_task_id: '',
toolkit_name: 'Open Ai Image Toolkit',
method_name: 'get openai credentials',
message: '[object Object]'
}
},
delay: 100
},
{
event: {
step: 'create_agent',
data: {
agent_name: 'multi_modal_agent',
agent_id: '2682c381-3560-4584-96c6-985a5395c85d',
tools: ['Video Downloader Toolkit', 'Audio Analysis Toolkit', 'Image Analysis Toolkit', 'Open Ai Image Toolkit', 'Human Toolkit', 'Terminal Toolkit', 'Note Taking Toolkit', 'Search Toolkit']
}
},
delay: 100
},
{
event: {
step: 'deactivate_toolkit',
data: {
agent_name: 'search_agent',
process_task_id: '',
toolkit_name: 'Browser Toolkit',
method_name: 'register agent',
message: 'null'
}
},
delay: 100
},
{
event: {
step: 'create_agent',
data: {
agent_name: 'Google calendar agent ',
agent_id: '729ebd9b-4eef-4f4a-83b8-0289bef302c5',
tools: ['Google Calendar Toolkit']
}
},
delay: 1100
},
{
event: {
step: 'activate_toolkit',
data: {
agent_name: 'search_agent',
process_task_id: '',
toolkit_name: 'Browser Toolkit',
method_name: 'register agent',
message: 'ChatAgent(Search Agent, RoleType.ASSISTANT, gpt-4.1)'
}
},
delay: 1100
},
{
event: {
step: 'deactivate_toolkit',
data: {
agent_name: 'Google calendar agent ',
process_task_id: '1762502461718-31.1',
toolkit_name: 'Google Calendar Toolkit',
method_name: 'get calendar details',
message: 'Failed to retrieve calendar details'
}
},
delay: 1100
},
{
event: {
step: 'deactivate_toolkit',
data: {
agent_name: 'Google calendar agent ',
process_task_id: '1762502461718-31.1',
toolkit_name: 'Google Calendar Toolkit',
method_name: 'get events',
message: '{"error": "Failed to retrieve events: timed out"}'
}
},
delay: 1100
},
{
event: {
step: 'to_sub_tasks',
data: {
summary_task: 'Task|Please help me check Google Calendar when is the next meeting, what kind of meeting it is, and who is attending the meeting.',
sub_tasks: []
}
},
delay: 1100
},
{
event: {
step: 'end',
data: ''
},
delay: 1100
}
];