From 5d6692bb9bdc38bfe907d4318d78191b24a8264d Mon Sep 17 00:00:00 2001 From: Sun Tao <2605127667@qq.com> Date: Tue, 13 Jan 2026 18:16:04 +0800 Subject: [PATCH 01/63] update --- backend/app/utils/agent.py | 2 ++ backend/app/utils/toolkit/hybrid_browser_toolkit.py | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index 61afc359..1f1280fa 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -867,6 +867,8 @@ def search_agent(options: Chat): "browser_enter", "browser_visit_page", "browser_scroll", + "browser_sheet_read", + "browser_sheet_input", # "browser_get_som_screenshot", ], ) diff --git a/backend/app/utils/toolkit/hybrid_browser_toolkit.py b/backend/app/utils/toolkit/hybrid_browser_toolkit.py index f39cb900..0b814f5a 100644 --- a/backend/app/utils/toolkit/hybrid_browser_toolkit.py +++ b/backend/app/utils/toolkit/hybrid_browser_toolkit.py @@ -2,6 +2,7 @@ import os import asyncio import json from typing import Any, Dict, List, Optional +from typing_extensions import TypedDict import websockets import websockets.exceptions @@ -19,6 +20,12 @@ from utils import traceroot_wrapper as traceroot logger = traceroot.get_logger("hybrid_browser_toolkit") +class SheetCell(TypedDict): + row: int + col: int + text: str + + class WebSocketBrowserWrapper(BaseWebSocketBrowserWrapper): def __init__(self, config: Optional[Dict[str, Any]] = None): """Initialize wrapper.""" @@ -343,6 +350,12 @@ class HybridBrowserToolkit(BaseHybridBrowserToolkit, AbstractToolkit): full_visual_mode=self._full_visual_mode, ) + return cloned_toolkit + + async def browser_sheet_input(self, *, cells: List[SheetCell]) -> Dict[str, Any]: + # Use typing_extensions.TypedDict for Pydantic <3.12 compatibility. + return await super().browser_sheet_input(cells=cells) + @classmethod def toolkit_name(cls) -> str: return "Browser Toolkit" From 47cf1be181620c3c68aeffdb4d2a79e5ad5f493f Mon Sep 17 00:00:00 2001 From: a7m-1st Date: Fri, 16 Jan 2026 17:00:21 +0300 Subject: [PATCH 02/63] enhance: cleanup env on close session --- backend/app/service/task.py | 27 ++++++++++++ backend/app/utils/toolkit/terminal_toolkit.py | 43 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/backend/app/service/task.py b/backend/app/service/task.py index 7f2e379d..b3f509dc 100644 --- a/backend/app/service/task.py +++ b/backend/app/service/task.py @@ -270,6 +270,8 @@ class TaskLock: last_accessed: datetime background_tasks: set[asyncio.Task] """Track all background tasks for cleanup""" + registered_toolkits: list[Any] + """Track toolkits for cleanup (e.g., TerminalToolkit venvs)""" # Context management fields conversation_history: List[Dict[str, Any]] @@ -290,6 +292,7 @@ class TaskLock: self.created_at = datetime.now() self.last_accessed = datetime.now() self.background_tasks = set() + self.registered_toolkits = [] # Initialize context management fields self.conversation_history = [] @@ -339,8 +342,32 @@ class TaskLock: except asyncio.CancelledError: pass self.background_tasks.clear() + + # Clean up registered toolkits (e.g., remove TerminalToolkit venvs) + for toolkit in self.registered_toolkits: + try: + if hasattr(toolkit, 'cleanup'): + toolkit.cleanup() + logger.info("Toolkit cleanup completed", extra={"task_id": self.id, "toolkit": type(toolkit).__name__}) + except Exception as e: + logger.warning(f"Failed to cleanup toolkit: {e}", extra={"task_id": self.id, "toolkit": type(toolkit).__name__}) + self.registered_toolkits.clear() + logger.info("Task lock cleanup completed", extra={"task_id": self.id}) + def register_toolkit(self, toolkit: Any) -> None: + """Register a toolkit for cleanup when task ends. + + This is used to track toolkits that create resources (like venvs) that + should be cleaned up when the task is complete. + """ + self.registered_toolkits.append(toolkit) + logger.debug("Toolkit registered for cleanup", extra={ + "task_id": self.id, + "toolkit": type(toolkit).__name__, + "total_registered": len(self.registered_toolkits) + }) + def add_conversation(self, role: str, content: str | dict): """Add a conversation entry to history""" logger.debug("Adding conversation entry", extra={"task_id": self.id, "role": role, "content_length": len(str(content))}) diff --git a/backend/app/utils/toolkit/terminal_toolkit.py b/backend/app/utils/toolkit/terminal_toolkit.py index 7eff1ccd..2be82317 100644 --- a/backend/app/utils/toolkit/terminal_toolkit.py +++ b/backend/app/utils/toolkit/terminal_toolkit.py @@ -73,6 +73,16 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): "openpyxl", ], ) + + # Auto-register with TaskLock for cleanup when task ends + from app.service.task import get_task_lock_if_exists + task_lock = get_task_lock_if_exists(api_task_id) + if task_lock: + task_lock.register_toolkit(self) + logger.info("TerminalToolkit registered for cleanup", extra={ + "api_task_id": api_task_id, + "working_directory": working_directory + }) def _write_to_log(self, log_file: str, content: str) -> None: r"""Write content to log file with optional ANSI stripping. @@ -175,6 +185,39 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): return result + def cleanup(self, remove_venv: bool = True): + """Clean up all active sessions and optionally remove the virtual environment. + + Args: + remove_venv: If True, removes the .venv or .initial_env folder created + by this toolkit. Defaults to True to prevent disk bloat. + """ + # First call parent cleanup to kill all shell sessions + super().cleanup() + + if remove_venv: + import shutil + + # Remove cloned env (.venv) if it exists + if self.cloned_env_path and os.path.exists(self.cloned_env_path): + try: + shutil.rmtree(self.cloned_env_path) + logger.info(f"Removed cloned venv: {self.cloned_env_path}", extra={ + "api_task_id": self.api_task_id + }) + except Exception as e: + logger.warning(f"Failed to remove cloned venv {self.cloned_env_path}: {e}") + + # Remove initial env (.initial_env) if it exists + if self.initial_env_path and os.path.exists(self.initial_env_path): + try: + shutil.rmtree(self.initial_env_path) + logger.info(f"Removed initial env: {self.initial_env_path}", extra={ + "api_task_id": self.api_task_id + }) + except Exception as e: + logger.warning(f"Failed to remove initial env {self.initial_env_path}: {e}") + @classmethod def shutdown(cls): if cls._thread_pool: From a2b0a04bd8d770d29c3238c0d7bad4cade4805db Mon Sep 17 00:00:00 2001 From: a7m-1st Date: Fri, 16 Jan 2026 18:30:24 +0300 Subject: [PATCH 03/63] enhance: delete tasklock on timeout --- backend/app/controller/chat_controller.py | 41 ++++++++++++++++++----- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/backend/app/controller/chat_controller.py b/backend/app/controller/chat_controller.py index b7fc7826..fdf9e13b 100644 --- a/backend/app/controller/chat_controller.py +++ b/backend/app/controller/chat_controller.py @@ -23,6 +23,7 @@ from app.service.task import ( get_or_create_task_lock, get_task_lock, set_current_task_id, + delete_task_lock ) from app.component.environment import set_user_env_path from app.utils.workforce import Workforce @@ -37,15 +38,16 @@ chat_logger = traceroot.get_logger("chat_controller") # SSE timeout configuration (10 minutes in seconds) SSE_TIMEOUT_SECONDS = 10 * 60 - -async def timeout_stream_wrapper(stream_generator, timeout_seconds: int = SSE_TIMEOUT_SECONDS): +async def timeout_stream_wrapper(stream_generator, timeout_seconds: int = SSE_TIMEOUT_SECONDS, task_lock = None): """ Wraps a stream generator with timeout handling. Closes the SSE connection if no data is received within the timeout period. + Triggers cleanup if timeout occurs to prevent resource leaks. """ last_data_time = time.time() generator = stream_generator.__aiter__() + cleanup_triggered = False try: while True: @@ -57,18 +59,39 @@ async def timeout_stream_wrapper(stream_generator, timeout_seconds: int = SSE_TI last_data_time = time.time() yield data except asyncio.TimeoutError: - chat_logger.warning(f"SSE timeout: No data received for {timeout_seconds} seconds, closing connection") - # yield sse_json("error", {"message": "Connection timeout: No data received for 10 minutes"}) - # TODO: Temporary change: suppress error signal to frontend on timeout. Needs proper fix later. + chat_logger.warning(f"SSE TIMEOUT: No data received for {timeout_seconds} seconds") + + # Trigger cleanup to prevent resource leaks + if task_lock: + try: + task_lock.status = Status.done + await delete_task_lock(task_lock.id) + cleanup_triggered = True + except Exception as cleanup_error: + chat_logger.error(f"[TIMEOUT-CLEANUP] Failed to cleanup task lock: {cleanup_error}", exc_info=True) break except StopAsyncIteration: break except asyncio.CancelledError: - chat_logger.info("Stream cancelled") + chat_logger.info("[STREAM-CANCELLED] Stream cancelled, triggering cleanup") + # Trigger cleanup on cancellation + if task_lock and not cleanup_triggered: + try: + task_lock.status = Status.done + await delete_task_lock(task_lock.id) + except Exception as cleanup_error: + chat_logger.error(f"[STREAM-CANCELLED] Failed to cleanup: {cleanup_error}") raise except Exception as e: - chat_logger.error(f"Error in stream wrapper: {e}", exc_info=True) + chat_logger.error(f"[STREAM-ERROR] Unexpected error in stream wrapper: {e}", exc_info=True) + # Trigger cleanup on unexpected errors + if task_lock and not cleanup_triggered: + try: + task_lock.status = Status.done + await delete_task_lock(task_lock.id) + except Exception as cleanup_error: + chat_logger.error(f"[STREAM-ERROR] Failed to cleanup: {cleanup_error}") raise @@ -124,7 +147,7 @@ async def post(data: Chat, request: Request): extra={"project_id": data.project_id, "task_id": data.task_id, "log_dir": str(camel_log)}, ) return StreamingResponse( - timeout_stream_wrapper(step_solve(data, request, task_lock)), media_type="text/event-stream" + timeout_stream_wrapper(step_solve(data, request, task_lock), task_lock=task_lock), media_type="text/event-stream" ) @@ -315,5 +338,5 @@ def skip_task(project_id: str): return Response(status_code=201) except Exception as e: - chat_logger.error(f"[STOP-BUTTON] ❌ Error skipping task for project_id: {project_id}: {e}") + chat_logger.error(f"[STOP-BUTTON] Error skipping task for project_id: {project_id}: {e}") raise UserException(code.error, f"Failed to skip task: {str(e)}") From 2e1fdeac829749b9f844bb9c55d97b9b299b3bc1 Mon Sep 17 00:00:00 2001 From: georgepanther3 Date: Sat, 17 Jan 2026 21:10:54 +0200 Subject: [PATCH 04/63] Add Linux support --- electron-builder.json | 5 +++++ package.json | 1 + scripts/preinstall-deps.js | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/electron-builder.json b/electron-builder.json index 61000693..ef5630cb 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -77,6 +77,11 @@ } ] }, + "linux": { + "icon": "build/icon.png", + "target": ["AppImage"], + "category": "Development" + }, "nsis": { "oneClick": false, "perMachine": false, diff --git a/package.json b/package.json index 1adb63d4..b0858bdf 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "build:mac": "npm run preinstall-deps && npm run clean-symlinks && npm run compile-babel && tsc && vite build && electron-builder --mac", "build:mac:test": "npm run preinstall-deps && npm run clean-symlinks && npm run compile-babel && tsc && vite build && electron-builder --mac && npm run test-signing", "build:win": "npm run preinstall-deps && npm run compile-babel && tsc && vite build && electron-builder --win", + "build:linux": "npm run preinstall-deps && npm run compile-babel && tsc && vite build && electron-builder --linux", "build:all": "npm run preinstall-deps && npm run compile-babel && tsc && vite build && electron-builder --mac --win", "preview": "vite preview", "pretest": "vite build --mode=test", diff --git a/scripts/preinstall-deps.js b/scripts/preinstall-deps.js index 4862b1bb..2e0c3af5 100644 --- a/scripts/preinstall-deps.js +++ b/scripts/preinstall-deps.js @@ -382,6 +382,26 @@ async function installUv() { await tar.extract({ file: tempFilename, cwd: BIN_DIR }); } + // Handle nested directory from tarball if needed + if (!isWindows) { + const nestedDir = fs.readdirSync(BIN_DIR).find(f => + fs.statSync(path.join(BIN_DIR, f)).isDirectory() && f.startsWith('uv-') + ); + if (nestedDir) { + const nestedUvPath = path.join(BIN_DIR, nestedDir, 'uv'); + const targetPath = path.join(BIN_DIR, 'uv'); + if (fs.existsSync(nestedUvPath)) { + console.log(` Found uv in ${nestedDir}, moving...`); + if (fs.existsSync(targetPath)) fs.unlinkSync(targetPath); + fs.renameSync(nestedUvPath, targetPath); + // Clean up directory + try { + fs.rmSync(path.join(BIN_DIR, nestedDir), { recursive: true, force: true }); + } catch (e) { console.log(' Warning: Failed to cleanup nested dir'); } + } + } + } + const extractedUvPath = path.join(BIN_DIR, isWindows ? 'uv.exe' : 'uv'); if (fs.existsSync(extractedUvPath)) { if (!isWindows && extractedUvPath !== uvPath) { From 5b53ec5020f96fc1d47da5566aefbc38aac5f002 Mon Sep 17 00:00:00 2001 From: georgepanther3 Date: Sat, 17 Jan 2026 21:43:30 +0200 Subject: [PATCH 05/63] Configure GitHub Actions for Linux release builds --- .github/workflows/build.yml | 29 ++++++++++++++++++++++++++++- package.json | 2 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a52d762f..0a290420 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,6 +31,8 @@ jobs: arch: x64 - os: windows-latest arch: x64 + - os: ubuntu-latest + arch: x64 steps: - name: Checkout Code @@ -82,6 +84,17 @@ jobs: VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} + # Step for Linux builds + - name: Build Release Files (Linux) + if: runner.os == 'Linux' + run: npm run build:linux + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} + VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} + VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} + VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} + - name: Upload Artifact uses: actions/upload-artifact@v6 with: @@ -97,7 +110,7 @@ jobs: steps: - name: Create directories run: | - mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 + mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 release/linux-x64 # Download all artifacts with correct names - name: Download mac-x64 artifact @@ -118,6 +131,12 @@ jobs: name: release-windows-latest-x64 path: temp-win-x64 + - name: Download linux-x64 artifact + uses: actions/download-artifact@v7 + with: + name: release-ubuntu-latest-x64 + path: temp-linux-x64 + # Move files to final release directory, removing any nested release/ directory - name: Move files to clean folders shell: bash @@ -143,6 +162,13 @@ jobs: mv temp-win-x64/* release/win-x64/ || true fi + # linux-x64 + if [ -d "temp-linux-x64/release" ]; then + mv temp-linux-x64/release/* release/linux-x64/ || true + else + mv temp-linux-x64/* release/linux-x64/ || true + fi + - name: Rename duplicate files run: | mv release/mac-x64/latest-mac.yml release/mac-x64/latest-x64-mac.yml || true @@ -157,5 +183,6 @@ jobs: release/mac-x64/* release/mac-arm64/* release/win-x64/* + release/linux-x64/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/package.json b/package.json index b0858bdf..cc3e67ae 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "build:mac": "npm run preinstall-deps && npm run clean-symlinks && npm run compile-babel && tsc && vite build && electron-builder --mac", "build:mac:test": "npm run preinstall-deps && npm run clean-symlinks && npm run compile-babel && tsc && vite build && electron-builder --mac && npm run test-signing", "build:win": "npm run preinstall-deps && npm run compile-babel && tsc && vite build && electron-builder --win", - "build:linux": "npm run preinstall-deps && npm run compile-babel && tsc && vite build && electron-builder --linux", + "build:linux": "npm run preinstall-deps && npm run clean-symlinks && npm run compile-babel && tsc && vite build && electron-builder --linux", "build:all": "npm run preinstall-deps && npm run compile-babel && tsc && vite build && electron-builder --mac --win", "preview": "vite preview", "pretest": "vite build --mode=test", From 344d408e61e763a96f3265319b6fe5e4a8762765 Mon Sep 17 00:00:00 2001 From: puzhen <1303385763@qq.com> Date: Sat, 17 Jan 2026 22:35:03 +0000 Subject: [PATCH 06/63] enhance stealth electron --- electron/main/index.ts | 34 ++++++++++++++++++ electron/main/webview.ts | 74 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/electron/main/index.ts b/electron/main/index.ts index 611d5fcd..11456e8a 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -112,6 +112,31 @@ app.commandLine.appendSwitch('max_old_space_size', '4096'); app.commandLine.appendSwitch('enable-features', 'MemoryPressureReduction'); app.commandLine.appendSwitch('renderer-process-limit', '8'); +// ==================== Anti-fingerprint settings ==================== +// Disable automation controlled indicator to avoid detection +app.commandLine.appendSwitch( + 'disable-blink-features', + 'AutomationControlled' +); + +// Override User Agent to remove Electron/eigent identifiers +// Dynamically generate User Agent based on actual platform +const getPlatformUA = () => { + const chromeVersion = '131.0.0.0'; + switch (process.platform) { + case 'darwin': + return `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`; + case 'win32': + return `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`; + case 'linux': + return `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`; + default: + return `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`; + } +}; +const normalUserAgent = getPlatformUA(); +app.userAgentFallback = normalUserAgent; + // ==================== protocol privileges ==================== // Register custom protocol privileges before app ready protocol.registerSchemesAsPrivileged([ @@ -1827,6 +1852,15 @@ app.whenReady().then(async () => { } } + // ==================== Anti-fingerprint: Set User Agent for all sessions ==================== + // Use the same dynamic User Agent as app.userAgentFallback + session.defaultSession.setUserAgent(normalUserAgent); + // Also set for the user_login partition used by webviews + session.fromPartition('persist:user_login').setUserAgent(normalUserAgent); + // And for main_window partition + session.fromPartition('persist:main_window').setUserAgent(normalUserAgent); + log.info('[ANTI-FINGERPRINT] User Agent set for all sessions'); + // ==================== download handle ==================== session.defaultSession.on('will-download', (event, item, webContents) => { item.once('done', (event, state) => { diff --git a/electron/main/webview.ts b/electron/main/webview.ts index 8fae65a6..17dac070 100644 --- a/electron/main/webview.ts +++ b/electron/main/webview.ts @@ -72,13 +72,85 @@ export class WebViewManager { backgroundThrottling: true, offscreen: false, sandbox: true, - disableBlinkFeatures: 'Accelerated2dCanvas', + disableBlinkFeatures: 'Accelerated2dCanvas,AutomationControlled', enableBlinkFeatures: 'IdleDetection', autoplayPolicy: 'document-user-activation-required', }, }) view.webContents.on('did-finish-load', () => { + // Inject stealth script to avoid bot detection view.webContents.executeJavaScript(` + // Hide webdriver property + Object.defineProperty(navigator, 'webdriver', { + get: () => undefined, + configurable: true + }); + + // Override plugins + Object.defineProperty(navigator, 'plugins', { + get: () => ({ + length: 3, + 0: { name: 'Chrome PDF Plugin', description: 'Portable Document Format', filename: 'internal-pdf-viewer' }, + 1: { name: 'Chrome PDF Viewer', description: '', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai' }, + 2: { name: 'Native Client', description: '', filename: 'internal-nacl-plugin' }, + item: function(index) { return this[index] || null; }, + namedItem: function(name) { + for (let i = 0; i < this.length; i++) { + if (this[i].name === name) return this[i]; + } + return null; + }, + refresh: function() {} + }), + configurable: true + }); + + // Override languages + Object.defineProperty(navigator, 'languages', { + get: () => ['en-US', 'en'], + configurable: true + }); + + // Override hardwareConcurrency + Object.defineProperty(navigator, 'hardwareConcurrency', { + get: () => 8, + configurable: true + }); + + // Override deviceMemory + Object.defineProperty(navigator, 'deviceMemory', { + get: () => 8, + configurable: true + }); + + // Fix WebGL vendor/renderer + const getParameter = WebGLRenderingContext.prototype.getParameter; + WebGLRenderingContext.prototype.getParameter = function(parameter) { + if (parameter === 37445) return 'Intel Inc.'; + if (parameter === 37446) return 'Intel(R) Iris(TM) Graphics 6100'; + return getParameter.call(this, parameter); + }; + + // Override chrome runtime + if (!window.chrome) window.chrome = {}; + window.chrome.runtime = { + onConnect: undefined, + onMessage: undefined + }; + + // Hide automation variables + const automationVars = ['__webdriver_evaluate', '__selenium_evaluate', '__webdriver_script_fn', + '__driver_evaluate', '__fxdriver_evaluate', '__driver_unwrapped', 'domAutomation', 'domAutomationController']; + automationVars.forEach(v => { + Object.defineProperty(window, v, { + get: () => undefined, + set: () => {}, + configurable: true, + enumerable: false + }); + }); + + // Mouse event handler window.addEventListener('mousedown', (e) => { if (!(e.target instanceof HTMLButtonElement || e.target instanceof HTMLInputElement)) { e.preventDefault(); From 6011e6bb44d05f5901a65df429ac6c103f9dfc39 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 18 Jan 2026 08:17:07 +0000 Subject: [PATCH 07/63] Refactor TopBar to expose hidden menu actions Moved "Report Bug", "Refer Friends", and "Settings" from a nested DropdownMenu to direct icon buttons in the TopBar. This improves discoverability and accessibility of these functions. - Removed DropdownMenu and related components from TopBar - Added direct buttons with Tooltips for Report Bug, Refer Friends, and Settings - Preserved existing visibility logic (e.g. Report Bug only visible when task is active) --- src/components/TopBar/index.tsx | 62 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/components/TopBar/index.tsx b/src/components/TopBar/index.tsx index 71ada441..b9695bf8 100644 --- a/src/components/TopBar/index.tsx +++ b/src/components/TopBar/index.tsx @@ -14,17 +14,10 @@ import { ChevronLeft, House, Share, - MoreHorizontal, } from "lucide-react"; import "./index.css"; import folderIcon from "@/assets/Folder.svg"; import { Button } from "@/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; import { useLocation, useNavigate } from "react-router-dom"; import { useSidebarStore } from "@/store/sidebarStore"; import useChatStoreAdapter from "@/hooks/useChatStoreAdapter"; @@ -344,37 +337,42 @@ function HeaderWin() { )} - - + {chatStore.activeTaskId && chatStore.tasks[chatStore.activeTaskId as string] && ( + - - - {chatStore.activeTaskId && chatStore.tasks[chatStore.activeTaskId as string] && ( - - - {t("layout.report-bug")} - - )} - - gift-icon - {t("layout.refer-friends")} - - navigate("/history?tab=settings")} className="cursor-pointer"> - - {t("layout.settings")} - - - + + )} + + + + + + )} {location.pathname === "/history" && ( From 0c8c5ef35df6c926b1b9c594bd8ec7c1bd0fa718 Mon Sep 17 00:00:00 2001 From: Caiodiv Date: Sun, 18 Jan 2026 13:48:34 -0300 Subject: [PATCH 10/63] Add READMME_PT-BR in server folder to brazilian guys --- server/README_PT-BR.md | 111 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 server/README_PT-BR.md diff --git a/server/README_PT-BR.md b/server/README_PT-BR.md new file mode 100644 index 00000000..8b5ef99f --- /dev/null +++ b/server/README_PT-BR.md @@ -0,0 +1,111 @@ +### Propósito +`server/` fornece um backend local (FastAPI + PostgreSQL) para alcançar separação completa entre ambientes locais e na nuvem. Após implantar este serviço, dados sensíveis como registro de usuários, configurações de provedores de modelos, configurações de ferramentas e histórico de bate-papo são armazenados em sua máquina e não são enviados para nossa nuvem, a menos que você configure explicitamente serviços externos (por exemplo, provedores de modelos na nuvem ou servidores MCP remotos). + +### Serviços Fornecidos (Módulos Principais) +- Usuários e Contas + - `POST /register`: Registro por email + senha (apenas banco de dados local) + - `POST /login`: Login com email + senha; retorna um token emitido localmente + - `GET/PUT /user`, `/user/profile`, `/user/privacy`, `/user/current_credits`, `/user/stat`, etc. +- Provedores de Modelos (armazenar configurações de acesso a modelos locais/na nuvem) + - `GET /providers`, `POST /provider`, `PUT /provider/{id}`, `DELETE /provider/{id}` + - `POST /provider/prefer`: Definir um provedor preferido (frontend/backend priorizará) +- Centro de Configuração (armazenar segredos/parâmetros necessários para ferramentas/capacidades) + - `GET /configs`, `POST /configs`, `PUT /configs/{id}`, `DELETE /configs/{id}`, `GET /config/info` +- Chat e Dados + - Histórico, snapshots, compartilhamento, etc. em `app/controller/chat/`, todos persistidos no banco de dados local +- Gerenciamento de MCP (importar servidores MCP locais/remotos) + - `GET /mcps`, `POST /mcp/install`, `POST /mcp/import/{Local|Remote}`, etc. + +Nota: Todos os dados acima são armazenados no volume PostgreSQL local no Docker (veja "Persistência de Dados" abaixo). Se você configurar modelos externos ou MCP remoto, as solicitações vão para os serviços de terceiros que você especificar. + +--- + +### Início Rápido (Docker) + +#### Pré-requisitos +- **Docker Desktop**: Instalado e em execução +- **Python**: 3.10.* (3.10.15 recomendado) +- **Node.js**: >=18.0.0 <23.0.0 + +#### Etapas de Configuração + +1) Inicie os serviços +```bash +cd server +# Copie .env.example para .env (ou crie .env de acordo com .env.example) +cp .env.example .env +docker compose up -d +``` + +2) Inicie o Frontend (Modo Local) +- No diretório raiz do projeto, crie ou modifique `.env.development` para ativar o modo local e apontar para o backend local: +```bash +VITE_BASE_URL=/api +VITE_USE_LOCAL_PROXY=true +VITE_PROXY_URL=http://localhost:3001 +``` +- Inicie a aplicação frontend: +```bash +npm install +npm run dev +``` + +### Abra a documentação da API +- `http://localhost:3001/docs` (Interface do Swagger) + +### Portas +- API: Host `3001` → Contêiner `5678` +- PostgreSQL: Host `5432` → Contêiner `5432` + +### Persistência de Dados +- Os dados do banco de dados são armazenados no volume Docker `server_postgres_data` em `/var/lib/postgresql/data` dentro do contêiner +- As migrações de banco de dados são executadas automaticamente na inicialização do contêiner (veja `start.sh` → `alembic upgrade head`) + +### Comandos Comuns +```bash +# Listar contêineres em execução +docker ps + +# Parar/Iniciar contêiner da API (manter DB) +docker stop eigent_api +docker start eigent_api + +# Parar/Iniciar tudo (API + DB) +docker compose stop +docker compose start + +# Exibir logs +docker logs -f eigent_api | cat +docker logs -f eigent_postgres | cat +``` + +--- + +### Modo Desenvolvedor (Opcional) +Você pode executar a API localmente com hot-reload enquanto mantém o banco de dados no Docker: +```bash +# Parar API no contêiner, manter DB +docker stop eigent_api + +# Inicializar banco de dados (primeira execução ou quando o esquema do BD muda) +cd server +uv run alembic upgrade head + +# Executar localmente (fornecer string de conexão do BD) +export database_url=postgresql://postgres:123456@localhost:5432/eigent +uv run uvicorn main:api --reload --port 3001 --host 0.0.0.0 +``` + +--- + +### Outros +- Documentação da API: `http://localhost:3001/docs` +- Logs de tempo de execução: `/app/runtime/log/app.log` no contêiner +- i18n (para desenvolvedores) +```bash +uv run pybabel extract -F babel.cfg -o messages.pot . +uv run pybabel init -i messages.pot -d lang -l zh_CN +uv run pybabel compile -d lang -l zh_CN +``` + +Para um ambiente completamente offline, use apenas modelos locais e servidores MCP locais, e evite configurar quaisquer Provedores externos ou endereços MCP remotos. From 2c80781d68e537ea94ddb25cb4df29a2d68b56bb Mon Sep 17 00:00:00 2001 From: Caiodiv Date: Sun, 18 Jan 2026 13:59:43 -0300 Subject: [PATCH 11/63] Fix server link to README_PT-BR.md --- README_PT-BR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_PT-BR.md b/README_PT-BR.md index 6b04ee6e..923662b4 100644 --- a/README_PT-BR.md +++ b/README_PT-BR.md @@ -88,7 +88,7 @@ Construído sobre o aclamado projeto open source da [CAMEL-AI][camel-site], noss A forma recomendada de executar o Eigent — totalmente independente, com controle completo sobre seus dados, sem necessidade de conta em nuvem. -👉 **[Guia Completo de Implantação Local](./server/README_EN.md)** +👉 **[Guia Completo de Implantação Local](./server/README_PT-BR.md)** Esta configuração inclui: - Servidor backend local com API completa From 8afd5efbb071a79582a940b2644bc9fdc8cfe22c Mon Sep 17 00:00:00 2001 From: Sun Tao <2605127667@qq.com> Date: Mon, 19 Jan 2026 15:00:20 +0800 Subject: [PATCH 12/63] Update Dockerfile --- server/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/Dockerfile b/server/Dockerfile index b0969036..2ed82ad0 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -4,8 +4,8 @@ FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim # Install the project into `/app` WORKDIR /app -# Enable bytecode compilation -ENV UV_COMPILE_BYTECODE=1 +# Disable bytecode compilation to avoid EMFILE during build on low nofile limits +ENV UV_COMPILE_BYTECODE=0 # Copy from the cache instead of linking since it's a mounted volume ENV UV_LINK_MODE=copy @@ -58,4 +58,4 @@ ENTRYPOINT [] EXPOSE 5678 # Use the start script -CMD ["/app/start.sh"] \ No newline at end of file +CMD ["/app/start.sh"] From 22e78ba573e5c3fd4d22e523647f62c976a4af12 Mon Sep 17 00:00:00 2001 From: Sun Tao <2605127667@qq.com> Date: Mon, 19 Jan 2026 15:55:23 +0800 Subject: [PATCH 13/63] add retry --- server/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/Dockerfile b/server/Dockerfile index 2ed82ad0..a185a6c5 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -15,10 +15,10 @@ ENV UV_PYTHON_INSTALL_MIRROR=https://registry.npmmirror.com/-/binary/python-buil ARG database_url ENV database_url=$database_url -RUN apt-get update && apt-get install -y \ - gcc \ - python3-dev \ - && rm -rf /var/lib/apt/lists/* +RUN apt-get update -o Acquire::Retries=3 && apt-get install -y --no-install-recommends \ + gcc \ + python3-dev \ + && rm -rf /var/lib/apt/lists/* # Copy dependency files first COPY server/pyproject.toml server/uv.lock ./ From bd75c227032fb736cb3344c94bdb8b4f53563a36 Mon Sep 17 00:00:00 2001 From: Xavier Date: Mon, 19 Jan 2026 18:10:05 +0800 Subject: [PATCH 14/63] chore(deps): bump electron stack and jsdom, reduce deprecated warnings --- package.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 1adb63d4..19a92882 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "csv-parser": "^3.2.0", "dompurify": "^3.2.7", "electron-log": "^5.4.0", - "electron-updater": "^6.3.9", + "electron-updater": "^6.7.3", "embla-carousel-autoplay": "^8.6.0", "embla-carousel-react": "^8.6.0", "framer-motion": "^12.17.0", @@ -114,11 +114,11 @@ "@vitejs/plugin-react": "^4.3.3", "@vitest/coverage-v8": "^2.1.9", "autoprefixer": "^10.4.20", - "electron": "^33.2.0", - "electron-builder": "^24.13.3", + "electron": "^33.4.11", + "electron-builder": "^26.4.0", "electron-devtools-installer": "^4.0.0", "i18next": "^25.4.2", - "jsdom": "^26.1.0", + "jsdom": "^27.4.0", "postcss": "^8.4.49", "postcss-import": "^16.1.0", "react": "^18.3.1", @@ -132,6 +132,9 @@ "vite-plugin-electron-renderer": "^0.14.6", "vitest": "^2.1.5" }, + "overrides": { + "glob": "^10.4.5" + }, "pnpm": { "neverBuiltDependencies": [] }, From d1d491ac92ecfe01c680972f6bd307a1c96765b3 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 05:03:16 +0800 Subject: [PATCH 15/63] minor update --- package.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 19a92882..bb3e7f2d 100644 --- a/package.json +++ b/package.json @@ -136,9 +136,12 @@ "glob": "^10.4.5" }, "pnpm": { - "neverBuiltDependencies": [] + "neverBuiltDependencies": [], + "overrides": { + "glob": "^10.4.5" + } }, "engines": { - "node": ">=18.0.0 <23.0.0" + "node": ">=20.0.0 <23.0.0" } } From 1ff0432e47b5670c371e7b4bf0636902cb173780 Mon Sep 17 00:00:00 2001 From: puzhen <1303385763@qq.com> Date: Mon, 19 Jan 2026 21:05:57 +0000 Subject: [PATCH 16/63] update to clone env --- backend/app/controller/chat_controller.py | 25 +++- backend/app/service/chat_service.py | 132 ++++++++++++++++-- backend/app/utils/agent.py | 10 +- backend/app/utils/toolkit/terminal_toolkit.py | 41 ++++-- backend/app/utils/workforce.py | 52 ++++++- 5 files changed, 230 insertions(+), 30 deletions(-) diff --git a/backend/app/controller/chat_controller.py b/backend/app/controller/chat_controller.py index b00fda92..de44fdc2 100644 --- a/backend/app/controller/chat_controller.py +++ b/backend/app/controller/chat_controller.py @@ -74,10 +74,23 @@ async def timeout_stream_wrapper(stream_generator, timeout_seconds: int = SSE_TI @router.post("/chat", name="start chat") @traceroot.trace() async def post(data: Chat, request: Request): + # === TIMING: Request received === + request_start_time = time.time() chat_logger.info( - "Starting new chat session", extra={"project_id": data.project_id, "task_id": data.task_id, "user": data.email} + "⏱️ [TIMING] Request received", + extra={"project_id": data.project_id, "task_id": data.task_id, "user": data.email, "timestamp": request_start_time} ) + + task_lock_start = time.time() task_lock = get_or_create_task_lock(data.project_id) + task_lock_time = (time.time() - task_lock_start) * 1000 + chat_logger.info(f"⏱️ [TIMING] task_lock created in {task_lock_time:.2f}ms") + + # Store request start time in task_lock for downstream timing + task_lock.request_start_time = request_start_time + + # === TIMING: Environment setup === + env_setup_start = time.time() # Set user-specific environment path for this thread set_user_env_path(data.env_path) @@ -96,6 +109,9 @@ async def post(data: Chat, request: Request): os.environ[key] = value chat_logger.info(f"Set search config: {key}", extra={"project_id": data.project_id}) + env_setup_time = (time.time() - env_setup_start) * 1000 + chat_logger.info(f"⏱️ [TIMING] Environment setup completed in {env_setup_time:.2f}ms") + email_sanitized = re.sub(r'[\\/*?:"<>|\s]', "_", data.email.split("@")[0]).strip(".") camel_log = ( Path.home() @@ -115,11 +131,16 @@ async def post(data: Chat, request: Request): # Set the initial current_task_id in task_lock set_current_task_id(data.project_id, data.task_id) + # === TIMING: Queue operation === + queue_start = time.time() # Put initial action in queue to start processing await task_lock.put_queue(ActionImproveData(data=data.question, new_task_id=data.task_id)) + queue_time = (time.time() - queue_start) * 1000 + chat_logger.info(f"⏱️ [TIMING] Question queued in {queue_time:.2f}ms") + total_controller_time = (time.time() - request_start_time) * 1000 chat_logger.info( - "Chat session initialized, starting streaming response", + f"⏱️ [TIMING] Controller total time: {total_controller_time:.2f}ms (task_lock: {task_lock_time:.2f}ms, env: {env_setup_time:.2f}ms, queue: {queue_time:.2f}ms)", extra={"project_id": data.project_id, "task_id": data.task_id, "log_dir": str(camel_log)}, ) return StreamingResponse( diff --git a/backend/app/service/chat_service.py b/backend/app/service/chat_service.py index 63b85dc7..71f5d427 100644 --- a/backend/app/service/chat_service.py +++ b/backend/app/service/chat_service.py @@ -237,12 +237,13 @@ def build_context_for_workforce(task_lock: TaskLock, options: Chat) -> str: @sync_step @traceroot.trace() async def step_solve(options: Chat, request: Request, task_lock: TaskLock): - # if True: - # import faulthandler + import time as time_module - # faulthandler.enable() - # for second in [5, 10, 20, 30, 60, 120, 240]: - # faulthandler.dump_traceback_later(second) + # === TIMING: step_solve started === + step_solve_start = time_module.time() + request_start_time = getattr(task_lock, 'request_start_time', step_solve_start) + time_since_request = (step_solve_start - request_start_time) * 1000 + logger.info(f"⏱️ [TIMING] step_solve started, {time_since_request:.2f}ms since request received") start_event_loop = True @@ -303,7 +304,11 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): logger.info(f"[LIFECYCLE] Breaking out of step_solve loop due to client disconnect") break try: + # === TIMING: Waiting for queue item === + queue_wait_start = time_module.time() item = await task_lock.get_queue() + queue_wait_time = (time_module.time() - queue_wait_start) * 1000 + logger.info(f"⏱️ [TIMING] Got item from queue in {queue_wait_time:.2f}ms, action={item.action}") except Exception as e: logger.error("Error getting item from queue", extra={"project_id": options.project_id, "task_id": options.task_id, "error": str(e)}, exc_info=True) # Continue waiting instead of breaking on queue error @@ -339,15 +344,25 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): }) continue + # === TIMING: Complexity determination === + complexity_start = time_module.time() + time_since_request_to_complexity = (complexity_start - request_start_time) * 1000 + logger.info(f"⏱️ [TIMING] Starting complexity check, {time_since_request_to_complexity:.2f}ms since request") + # Simplified logic: attachments mean workforce, otherwise let agent decide is_complex_task: bool if len(options.attaches) > 0: # Questions with attachments always need workforce is_complex_task = True logger.info(f"[NEW-QUESTION] Has attachments, treating as complex task") + complexity_time = (time_module.time() - complexity_start) * 1000 + logger.info(f"⏱️ [TIMING] Complexity check (has attachments) completed in {complexity_time:.2f}ms") else: logger.info(f"[NEW-QUESTION] Calling question_confirm to determine complexity") + question_confirm_start = time_module.time() is_complex_task = await question_confirm(question_agent, question, task_lock) + question_confirm_time = (time_module.time() - question_confirm_start) * 1000 + logger.info(f"⏱️ [TIMING] question_confirm completed in {question_confirm_time:.2f}ms, is_complex={is_complex_task}") logger.info(f"[NEW-QUESTION] question_confirm result: is_complex={is_complex_task}") if not is_complex_task: @@ -386,6 +401,11 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): except Exception as e: logger.error(f"Error cleaning up folder: {e}") else: + # === TIMING: Complex task processing === + complex_task_start = time_module.time() + time_since_request_to_complex = (complex_task_start - request_start_time) * 1000 + logger.info(f"⏱️ [TIMING] Complex task processing started, {time_since_request_to_complex:.2f}ms since request") + logger.info(f"[NEW-QUESTION] 🔧 Complex task, creating workforce and decomposing") # Update the sync_step with new task_id if hasattr(item, 'new_task_id') and item.new_task_id: @@ -397,8 +417,12 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): logger.info(f"[NEW-QUESTION] Sending 'confirmed' SSE to frontend") yield sse_json("confirmed", {"question": question}) + # === TIMING: Context building === + context_build_start = time_module.time() logger.info(f"[NEW-QUESTION] Building context for coordinator") context_for_coordinator = build_context_for_workforce(task_lock, options) + context_build_time = (time_module.time() - context_build_start) * 1000 + logger.info(f"⏱️ [TIMING] Context building completed in {context_build_time:.2f}ms") # Check if workforce exists - if so, reuse it (agents are preserved) # Otherwise create new workforce @@ -407,8 +431,12 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): logger.info(f"[NEW-QUESTION] ✅ Reusing existing workforce with preserved agents") # Workforce is already stopped from skip_task, ready for new decomposition else: + # === TIMING: Workforce construction === + workforce_construct_start = time_module.time() logger.info(f"[NEW-QUESTION] 🏭 Creating NEW workforce instance (workforce=None)") (workforce, mcp) = await construct_workforce(options) + workforce_construct_time = (time_module.time() - workforce_construct_start) * 1000 + logger.info(f"⏱️ [TIMING] Workforce construction completed in {workforce_construct_time:.2f}ms") logger.info(f"[NEW-QUESTION] ✅ NEW Workforce instance created, id={id(workforce)}") for new_agent in options.new_agents: workforce.add_single_agent_worker( @@ -416,6 +444,9 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): ) task_lock.status = Status.confirmed + # === TIMING: Task creation === + task_create_start = time_module.time() + # If camel_task already exists (from previous paused task), add new question as subtask # Otherwise, create a new camel_task if camel_task is not None: @@ -434,6 +465,16 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): if len(options.attaches) > 0: camel_task.additional_info = {Path(file_path).name: file_path for file_path in options.attaches} + task_create_time = (time_module.time() - task_create_start) * 1000 + logger.info(f"⏱️ [TIMING] Task object created in {task_create_time:.2f}ms") + + # === TIMING: Task decomposition start === + decomposition_start = time_module.time() + time_since_request_to_decompose = (decomposition_start - request_start_time) * 1000 + logger.info(f"⏱️ [TIMING] Starting task decomposition, {time_since_request_to_decompose:.2f}ms since request") + # Store decomposition start time in task_lock for downstream tracking + task_lock.decomposition_start_time = decomposition_start + # Stream decomposition in background so queue items (decompose_text) are processed immediately logger.info(f"[NEW-QUESTION] 🧩 Starting task decomposition via workforce.eigent_make_sub_tasks") stream_state = {"subtasks": [], "seen_ids": set(), "last_content": ""} @@ -479,6 +520,10 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): async def run_decomposition(): nonlocal camel_task, summary_task_content try: + # === TIMING: LLM decomposition call === + llm_decompose_start = time_module.time() + decomposition_start_time = getattr(task_lock, 'decomposition_start_time', llm_decompose_start) + sub_tasks = await asyncio.to_thread( workforce.eigent_make_sub_tasks, camel_task, @@ -486,6 +531,11 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): on_stream_batch, on_stream_text, ) + + llm_decompose_time = (time_module.time() - llm_decompose_start) * 1000 + total_decompose_time = (time_module.time() - decomposition_start_time) * 1000 + logger.info(f"⏱️ [TIMING] LLM decomposition completed in {llm_decompose_time:.2f}ms (total decompose phase: {total_decompose_time:.2f}ms)") + if stream_state["subtasks"]: sub_tasks = stream_state["subtasks"] state_holder["sub_tasks"] = sub_tasks @@ -495,13 +545,17 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): except Exception: pass + # === TIMING: Summary generation === + summary_start = time_module.time() logger.info(f"[NEW-QUESTION] Generating task summary") summary_task_agent = task_summary_agent(options) try: summary_task_content = await asyncio.wait_for( summary_task(summary_task_agent, camel_task), timeout=10 ) + summary_time = (time_module.time() - summary_start) * 1000 task_lock.summary_generated = True + logger.info(f"⏱️ [TIMING] Summary generation completed in {summary_time:.2f}ms") logger.info("[NEW-QUESTION] ✅ Summary generated successfully", extra={"project_id": options.project_id}) except asyncio.TimeoutError: logger.warning("summary_task timeout", extra={"project_id": options.project_id, "task_id": options.task_id}) @@ -542,6 +596,11 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): } await task_lock.put_queue(ActionDecomposeProgressData(data=payload)) logger.info(f"[NEW-QUESTION] ✅ to_sub_tasks SSE sent") + + # === TIMING: Total time from request to decomposition complete === + request_start = getattr(task_lock, 'request_start_time', decomposition_start_time) + total_request_to_decompose = (time_module.time() - request_start) * 1000 + logger.info(f"⏱️ [TIMING] ===== TOTAL: Request → Decomposition Complete: {total_request_to_decompose:.2f}ms =====") except Exception as e: logger.error(f"Error in background decomposition: {e}", exc_info=True) @@ -1300,9 +1359,16 @@ async def get_task_result_with_optional_summary(task: Task, options: Chat) -> st @traceroot.trace() async def construct_workforce(options: Chat) -> tuple[Workforce, ListenChatAgent]: - logger.info("Constructing workforce", extra={"project_id": options.project_id, "task_id": options.task_id}) + import time as time_module + # === TIMING: construct_workforce start === + construct_start = time_module.time() + logger.info("⏱️ [TIMING] construct_workforce started", extra={"project_id": options.project_id, "task_id": options.task_id}) + working_directory = get_working_directory(options) logger.debug("Working directory set", extra={"working_directory": working_directory}) + + # === TIMING: Coordinator and Task agent creation === + coord_task_agent_start = time_module.time() [coordinator_agent, task_agent] = [ agent_model( key, @@ -1323,9 +1389,9 @@ You are a helpful coordinator. {platform.machine()} at working directory `{working_directory}`. All local file operations must occur here, but you can access files from any place in the file system. For all file system operations, you MUST use absolute paths to ensure precision and avoid ambiguity. The current date is {datetime.date.today()}. For any date-related tasks, you MUST use this as the current date. -- If a task assigned to another agent fails, you should re-assign it to the -`Developer_Agent`. The `Developer_Agent` is a powerful agent with terminal -access and can resolve a wide range of issues. +- If a task assigned to another agent fails, you should re-assign it to the +`Developer_Agent`. The `Developer_Agent` is a powerful agent with terminal +access and can resolve a wide range of issues. """, Agents.task_agent: f""" You are a helpful task planner. @@ -1335,6 +1401,11 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS """, }.items() ] + coord_task_agent_time = (time_module.time() - coord_task_agent_start) * 1000 + logger.info(f"⏱️ [TIMING] Coordinator + Task agent created in {coord_task_agent_time:.2f}ms") + + # === TIMING: New worker agent creation === + new_worker_start = time_module.time() new_worker_agent = agent_model( Agents.new_worker_agent, f""" @@ -1353,12 +1424,33 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS ).get_tools(), ], ) + new_worker_time = (time_module.time() - new_worker_start) * 1000 + logger.info(f"⏱️ [TIMING] New worker agent created in {new_worker_time:.2f}ms") # msg_toolkit = AgentCommunicationToolkit(max_message_history=100) + # === TIMING: Browser agent creation === + browser_start = time_module.time() searcher = browser_agent(options) + browser_time = (time_module.time() - browser_start) * 1000 + logger.info(f"⏱️ [TIMING] Browser agent created in {browser_time:.2f}ms") + + # === TIMING: Developer agent creation === + developer_start = time_module.time() developer = await developer_agent(options) + developer_time = (time_module.time() - developer_start) * 1000 + logger.info(f"⏱️ [TIMING] Developer agent created in {developer_time:.2f}ms") + + # === TIMING: Document agent creation === + document_start = time_module.time() documenter = await document_agent(options) + document_time = (time_module.time() - document_start) * 1000 + logger.info(f"⏱️ [TIMING] Document agent created in {document_time:.2f}ms") + + # === TIMING: Multi-modal agent creation === + multi_modal_start = time_module.time() multi_modaler = multi_modal_agent(options) + multi_modal_time = (time_module.time() - multi_modal_start) * 1000 + logger.info(f"⏱️ [TIMING] Multi-modal agent created in {multi_modal_time:.2f}ms") # msg_toolkit.register_agent("Worker", new_worker_agent) # msg_toolkit.register_agent("Browser_Agent", searcher) @@ -1373,6 +1465,8 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS # If conversion fails, default to non-OpenAI behavior model_platform_enum = None + # === TIMING: Workforce instance creation === + workforce_instance_start = time_module.time() workforce = Workforce( options.project_id, "A workforce", @@ -1383,6 +1477,11 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS new_worker_agent=new_worker_agent, use_structured_output_handler=False if model_platform_enum == ModelPlatformType.OPENAI else True, ) + workforce_instance_time = (time_module.time() - workforce_instance_start) * 1000 + logger.info(f"⏱️ [TIMING] Workforce instance created in {workforce_instance_time:.2f}ms") + + # === TIMING: Adding workers to workforce === + add_workers_start = time_module.time() workforce.add_single_agent_worker( "Developer Agent: A master-level coding assistant with a powerful " "terminal. It can write and execute code, manage files, automate " @@ -1410,18 +1509,33 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS "generate new images from text prompts.", multi_modaler, ) + add_workers_time = (time_module.time() - add_workers_start) * 1000 + logger.info(f"⏱️ [TIMING] Workers added to workforce in {add_workers_time:.2f}ms") + # workforce.add_single_agent_worker( # "Social Media Agent: A social media management assistant for " # "handling tasks related to WhatsApp, Twitter, LinkedIn, Reddit, " # "Notion, Slack, and other social platforms.", # await social_medium_agent(options), # ) + + # === TIMING: MCP agent creation === + mcp_start = time_module.time() mcp = await mcp_agent(options) + mcp_time = (time_module.time() - mcp_start) * 1000 + logger.info(f"⏱️ [TIMING] MCP agent created in {mcp_time:.2f}ms") + # workforce.add_single_agent_worker( # "MCP Agent: A Model Context Protocol agent that provides access " # "to external tools and services through MCP integrations.", # mcp, # ) + + # === TIMING: construct_workforce total === + total_construct_time = (time_module.time() - construct_start) * 1000 + logger.info(f"⏱️ [TIMING] construct_workforce TOTAL: {total_construct_time:.2f}ms") + logger.info(f"⏱️ [TIMING] construct_workforce breakdown: coord+task={coord_task_agent_time:.2f}ms, new_worker={new_worker_time:.2f}ms, browser={browser_time:.2f}ms, developer={developer_time:.2f}ms, document={document_time:.2f}ms, multi_modal={multi_modal_time:.2f}ms, workforce_init={workforce_instance_time:.2f}ms, add_workers={add_workers_time:.2f}ms, mcp={mcp_time:.2f}ms") + return workforce, mcp diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index 545c7a20..b09def0d 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -803,7 +803,7 @@ async def developer_agent(options: Chat): options.project_id, Agents.document_agent, safe_mode=True, - clone_current_env=False, + clone_current_env=True, ) terminal_toolkit = message_integration.register_toolkits(terminal_toolkit) @@ -1008,7 +1008,7 @@ def browser_agent(options: Chat): options.project_id, Agents.browser_agent, safe_mode=True, - clone_current_env=False, + clone_current_env=True, ) terminal_toolkit = message_integration.register_functions( [terminal_toolkit.shell_exec] @@ -1196,7 +1196,7 @@ async def document_agent(options: Chat): options.project_id, Agents.document_agent, safe_mode=True, - clone_current_env=False, + clone_current_env=True, ) terminal_toolkit = message_integration.register_toolkits(terminal_toolkit) tools = [ @@ -1415,7 +1415,7 @@ def multi_modal_agent(options: Chat): options.project_id, agent_name=Agents.multi_modal_agent, safe_mode=True, - clone_current_env=False, + clone_current_env=True, ) terminal_toolkit = message_integration.register_toolkits(terminal_toolkit) note_toolkit = NoteTakingToolkit( @@ -1607,7 +1607,7 @@ async def social_medium_agent(options: Chat): *TerminalToolkit( options.project_id, agent_name=Agents.social_medium_agent, - clone_current_env=False, + clone_current_env=True, ).get_tools(), *NoteTakingToolkit( options.project_id, diff --git a/backend/app/utils/toolkit/terminal_toolkit.py b/backend/app/utils/toolkit/terminal_toolkit.py index 7eff1ccd..9d00b302 100644 --- a/backend/app/utils/toolkit/terminal_toolkit.py +++ b/backend/app/utils/toolkit/terminal_toolkit.py @@ -2,6 +2,7 @@ import asyncio import logging import os import threading +import time from concurrent.futures import ThreadPoolExecutor from typing import Optional from camel.toolkits.terminal_toolkit import TerminalToolkit as BaseTerminalToolkit @@ -33,28 +34,51 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): session_logs_dir: str | None = None, safe_mode: bool = True, allowed_commands: list[str] | None = None, - clone_current_env: bool = False, + clone_current_env: bool = True, ): + # === TIMING: TerminalToolkit init start === + init_start = time.time() + self.api_task_id = api_task_id if agent_name is not None: self.agent_name = agent_name if working_directory is None: working_directory = env("file_save_path", os.path.expanduser("~/.eigent/terminal/")) - logger.info("Initializing TerminalToolkit", extra={ + logger.info(f"⏱️ [TIMING] TerminalToolkit.__init__ started for agent={self.agent_name}", extra={ "api_task_id": api_task_id, "agent_name": self.agent_name, "working_directory": working_directory, "safe_mode": safe_mode, "use_docker_backend": use_docker_backend }) + logger.info(f"⏱️ [TIMING] working_directory={working_directory}") + # === TIMING: Thread pool creation === + thread_pool_start = time.time() if TerminalToolkit._thread_pool is None: TerminalToolkit._thread_pool = ThreadPoolExecutor( max_workers=1, thread_name_prefix="terminal_toolkit" ) - logger.debug("Created terminal toolkit thread pool") + thread_pool_time = (time.time() - thread_pool_start) * 1000 + logger.info(f"⏱️ [TIMING] Created terminal toolkit thread pool in {thread_pool_time:.2f}ms") + else: + logger.debug("Thread pool already exists, skipping creation") + + # === TIMING: Base class init (this is the heavy part) === + super_init_start = time.time() + logger.info("⏱️ [TIMING] Starting BaseTerminalToolkit.__init__...") + logger.info(f"⏱️ [TIMING] Parameters: working_directory={working_directory}, clone_current_env={clone_current_env}") + + # Check if env already exists (determines if env setup is needed) + # .venv is used when clone_current_env=True, .initial_env when False + if clone_current_env: + env_path = os.path.join(working_directory, ".venv") if working_directory else None + else: + env_path = os.path.join(working_directory, ".initial_env") if working_directory else None + env_exists = env_path and os.path.exists(env_path) + logger.info(f"⏱️ [TIMING] env_path={env_path}, env_exists={env_exists}") super().__init__( timeout=timeout, @@ -65,14 +89,11 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): safe_mode=safe_mode, allowed_commands=allowed_commands, clone_current_env=clone_current_env, - install_dependencies=[ - "pandas", - "numpy", - "matplotlib", - "requests", - "openpyxl", - ], ) + super_init_time = (time.time() - super_init_start) * 1000 + total_init_time = (time.time() - init_start) * 1000 + logger.info(f"⏱️ [TIMING] BaseTerminalToolkit.__init__ completed in {super_init_time:.2f}ms (env_existed={env_exists})") + logger.info(f"⏱️ [TIMING] TerminalToolkit.__init__ TOTAL: {total_init_time:.2f}ms") def _write_to_log(self, log_file: str, content: str) -> None: r"""Write content to log file with optional ANSI stripping. diff --git a/backend/app/utils/workforce.py b/backend/app/utils/workforce.py index 0b5bde45..a26c52a1 100644 --- a/backend/app/utils/workforce.py +++ b/backend/app/utils/workforce.py @@ -1,4 +1,5 @@ import asyncio +import time from typing import Generator, List, Optional from camel.agents import ChatAgent from camel.societies.workforce.workforce import ( @@ -87,17 +88,23 @@ class Workforce(BaseWorkforce): on_stream_batch: Optional callback for streaming batches signature (List[Task], bool) on_stream_text: Optional callback for raw streaming text chunks """ + # === TIMING: eigent_make_sub_tasks start === + decompose_start = time.time() + logger.info("=" * 80) logger.info("🧩 [DECOMPOSE] eigent_make_sub_tasks CALLED", extra={ "api_task_id": self.api_task_id, "workforce_id": id(self), "task_id": task.id }) + logger.info(f"⏱️ [TIMING] eigent_make_sub_tasks started") logger.info(f"[DECOMPOSE] Task content preview: '{task.content[:200]}...'") logger.info(f"[DECOMPOSE] Has coordinator context: {bool(coordinator_context)}") logger.info(f"[DECOMPOSE] Current workforce state: {self._state.name}, _running: {self._running}") logger.info("=" * 80) + # === TIMING: Validation === + validation_start = time.time() if not validate_task_content(task.content, task.id): task.state = TaskState.FAILED task.result = "Task failed: Invalid or empty content provided" @@ -106,31 +113,43 @@ class Workforce(BaseWorkforce): "content_preview": task.content[:50] + "..." if len(task.content) > 50 else task.content }) raise UserException(code.error, task.result) + validation_time = (time.time() - validation_start) * 1000 + logger.info(f"⏱️ [TIMING] Task validation completed in {validation_time:.2f}ms") + # === TIMING: Workforce reset === + reset_start = time.time() logger.info(f"[DECOMPOSE] Resetting workforce state") self.reset() self._task = task self.set_channel(TaskChannel()) self._state = WorkforceState.RUNNING task.state = TaskState.OPEN - logger.info(f"[DECOMPOSE] Workforce reset complete, state: {self._state.name}") + reset_time = (time.time() - reset_start) * 1000 + logger.info(f"⏱️ [TIMING] Workforce reset completed in {reset_time:.2f}ms, state: {self._state.name}") + # === TIMING: handle_decompose_append_task === + handle_decompose_start = time.time() logger.info(f"[DECOMPOSE] Calling handle_decompose_append_task") subtasks = asyncio.run( self.handle_decompose_append_task( - task, - reset=False, + task, + reset=False, coordinator_context=coordinator_context, - on_stream_batch=on_stream_batch, + on_stream_batch=on_stream_batch, on_stream_text=on_stream_text ) ) + handle_decompose_time = (time.time() - handle_decompose_start) * 1000 + logger.info(f"⏱️ [TIMING] handle_decompose_append_task completed in {handle_decompose_time:.2f}ms") + + total_decompose_time = (time.time() - decompose_start) * 1000 logger.info("=" * 80) logger.info(f"✅ [DECOMPOSE] Task decomposition COMPLETED", extra={ "api_task_id": self.api_task_id, "task_id": task.id, "subtasks_count": len(subtasks) }) + logger.info(f"⏱️ [TIMING] eigent_make_sub_tasks TOTAL: {total_decompose_time:.2f}ms (validation: {validation_time:.2f}ms, reset: {reset_time:.2f}ms, decompose: {handle_decompose_time:.2f}ms)") logger.info("=" * 80) return subtasks @@ -165,7 +184,12 @@ class Workforce(BaseWorkforce): def _decompose_task(self, task: Task, stream_callback=None): """Decompose task with optional streaming text callback.""" + # === TIMING: _decompose_task start === + decompose_task_start = time.time() + logger.info(f"⏱️ [TIMING] _decompose_task started") + # === TIMING: Prompt building === + prompt_build_start = time.time() decompose_prompt = str( TASK_DECOMPOSE_PROMPT.format( content=task.content, @@ -173,10 +197,23 @@ class Workforce(BaseWorkforce): additional_info=task.additional_info, ) ) + prompt_build_time = (time.time() - prompt_build_start) * 1000 + logger.info(f"⏱️ [TIMING] Decompose prompt built in {prompt_build_time:.2f}ms (length: {len(decompose_prompt)} chars)") + + # === TIMING: Agent reset === + agent_reset_start = time.time() self.task_agent.reset() + agent_reset_time = (time.time() - agent_reset_start) * 1000 + logger.info(f"⏱️ [TIMING] Task agent reset in {agent_reset_time:.2f}ms") + + # === TIMING: LLM call (task.decompose) === + llm_call_start = time.time() + logger.info(f"⏱️ [TIMING] Starting LLM decompose call...") result = task.decompose( self.task_agent, decompose_prompt, stream_callback=stream_callback ) + llm_call_time = (time.time() - llm_call_start) * 1000 + logger.info(f"⏱️ [TIMING] LLM decompose call returned in {llm_call_time:.2f}ms (streaming={isinstance(result, Generator)})") if isinstance(result, Generator): def streaming_with_dependencies(): @@ -217,6 +254,9 @@ class Workforce(BaseWorkforce): Returns: List[Task]: The decomposed subtasks or the original task """ + # === TIMING: handle_decompose_append_task start === + handle_start = time.time() + logger.info(f"⏱️ [TIMING] handle_decompose_append_task started") logger.info(f"[DECOMPOSE] handle_decompose_append_task CALLED, task_id={task.id}, reset={reset}") if not validate_task_content(task.content, task.id): @@ -293,6 +333,10 @@ class Workforce(BaseWorkforce): except Exception as e: logger.warning(f"Final streaming callback failed: {e}") + # === TIMING: handle_decompose_append_task complete === + handle_total_time = (time.time() - handle_start) * 1000 + logger.info(f"⏱️ [TIMING] handle_decompose_append_task completed in {handle_total_time:.2f}ms, returned {len(subtasks)} subtasks") + return subtasks def _get_agent_id_from_node_id(self, node_id: str) -> str | None: From 8194b45e3b02a359acf22f1c21e2dc4d53f37af1 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 05:32:14 +0800 Subject: [PATCH 17/63] enhance: Fix docker build PR949 --- server/Dockerfile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/server/Dockerfile b/server/Dockerfile index a185a6c5..284596d1 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -4,8 +4,8 @@ FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim # Install the project into `/app` WORKDIR /app -# Disable bytecode compilation to avoid EMFILE during build on low nofile limits -ENV UV_COMPILE_BYTECODE=0 +# Disable bytecode transfer during compilation to avoid EMFILE during build on low nofile limits +ENV UV_COMPILE_BYTECODE=0 # Copy from the cache instead of linking since it's a mounted volume ENV UV_LINK_MODE=copy @@ -15,10 +15,10 @@ ENV UV_PYTHON_INSTALL_MIRROR=https://registry.npmmirror.com/-/binary/python-buil ARG database_url ENV database_url=$database_url -RUN apt-get update -o Acquire::Retries=3 && apt-get install -y --no-install-recommends \ - gcc \ - python3-dev \ - && rm -rf /var/lib/apt/lists/* +RUN apt-get update -o Acquire::Retries=3 && apt-get install -y --no-install-recommends \ + gcc \ + python3-dev \ + && rm -rf /var/lib/apt/lists/* # Copy dependency files first COPY server/pyproject.toml server/uv.lock ./ @@ -43,7 +43,7 @@ RUN uv run pybabel extract -F babel.cfg -o messages.pot . && \ # Install netcat for database connectivity check -RUN apt-get update && apt-get install -y curl netcat-openbsd && rm -rf /var/lib/apt/lists/* +RUN apt-get update -o Acquire::Retries=3 && apt-get install -y --no-install-recommends curl netcat-openbsd && rm -rf /var/lib/apt/lists/* # Place executables in the environment at the front of the path ENV PATH="/app/.venv/bin:$PATH" @@ -58,4 +58,4 @@ ENTRYPOINT [] EXPOSE 5678 # Use the start script -CMD ["/app/start.sh"] +CMD ["/app/start.sh"] From f45f6a0199756d80b94278936194967988c4d5d7 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 05:59:51 +0800 Subject: [PATCH 18/63] minor ui fix --- src/components/TopBar/index.tsx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/TopBar/index.tsx b/src/components/TopBar/index.tsx index b9695bf8..988bdce9 100644 --- a/src/components/TopBar/index.tsx +++ b/src/components/TopBar/index.tsx @@ -257,16 +257,16 @@ function HeaderWin() { - + + + )} {location.pathname !== "/history" && ( From d7d49107c8c9b5b82be6c52392423ea4e7fce131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20=C3=87elik?= Date: Tue, 20 Jan 2026 01:11:07 +0300 Subject: [PATCH 19/63] fix: correct typos and spelling errors across codebase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix "Recieved" → "Received" in chatStore.ts - Fix "finshedTask" → "finishedTask" variable name in chatStore.ts - Fix "untill" → "until" in test comments - Fix "manger" → "manager" in permission descriptions and translations --- server/app/component/permission.py | 8 ++++---- server/lang/zh_CN/LC_MESSAGES/messages.po | 8 ++++---- server/messages.pot | 8 ++++---- src/store/chatStore.ts | 6 +++--- test/integration/chatStore/deadWorkforce.test.tsx | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/server/app/component/permission.py b/server/app/component/permission.py index 1cae0db8..f9997ef8 100644 --- a/server/app/component/permission.py +++ b/server/app/component/permission.py @@ -10,7 +10,7 @@ def permissions(): return [ { "name": _("User"), - "description": _("User manger"), + "description": _("User manager"), "children": [ { "identity": "user:view", @@ -26,7 +26,7 @@ def permissions(): }, { "name": _("Admin"), - "description": _("Admin manger"), + "description": _("Admin manager"), "children": [ { "identity": "admin:view", @@ -42,7 +42,7 @@ def permissions(): }, { "name": _("Role"), - "description": _("Role manger"), + "description": _("Role manager"), "children": [ { "identity": "role:view", @@ -58,7 +58,7 @@ def permissions(): }, { "name": _("Mcp"), - "description": _("Mcp manger"), + "description": _("Mcp manager"), "children": [ { "identity": "mcp:edit", diff --git a/server/lang/zh_CN/LC_MESSAGES/messages.po b/server/lang/zh_CN/LC_MESSAGES/messages.po index 9c5f8ba1..3438d4d6 100644 --- a/server/lang/zh_CN/LC_MESSAGES/messages.po +++ b/server/lang/zh_CN/LC_MESSAGES/messages.po @@ -31,7 +31,7 @@ msgid "User" msgstr "" #: app/component/permission.py:13 -msgid "User manger" +msgid "User manager" msgstr "" #: app/component/permission.py:17 @@ -55,7 +55,7 @@ msgid "Admin" msgstr "" #: app/component/permission.py:29 -msgid "Admin manger" +msgid "Admin manager" msgstr "" #: app/component/permission.py:33 @@ -79,7 +79,7 @@ msgid "Role" msgstr "" #: app/component/permission.py:45 -msgid "Role manger" +msgid "Role manager" msgstr "" #: app/component/permission.py:49 @@ -103,7 +103,7 @@ msgid "Mcp" msgstr "" #: app/component/permission.py:61 -msgid "Mcp manger" +msgid "Mcp manager" msgstr "" #: app/component/permission.py:65 diff --git a/server/messages.pot b/server/messages.pot index d86ee0be..f9fb4611 100644 --- a/server/messages.pot +++ b/server/messages.pot @@ -30,7 +30,7 @@ msgid "User" msgstr "" #: app/component/permission.py:13 -msgid "User manger" +msgid "User manager" msgstr "" #: app/component/permission.py:17 @@ -54,7 +54,7 @@ msgid "Admin" msgstr "" #: app/component/permission.py:29 -msgid "Admin manger" +msgid "Admin manager" msgstr "" #: app/component/permission.py:33 @@ -78,7 +78,7 @@ msgid "Role" msgstr "" #: app/component/permission.py:45 -msgid "Role manger" +msgid "Role manager" msgstr "" #: app/component/permission.py:49 @@ -102,7 +102,7 @@ msgid "Mcp" msgstr "" #: app/component/permission.py:61 -msgid "Mcp manger" +msgid "Mcp manager" msgstr "" #: app/component/permission.py:65 diff --git a/src/store/chatStore.ts b/src/store/chatStore.ts index 2b475693..55c2177e 100644 --- a/src/store/chatStore.ts +++ b/src/store/chatStore.ts @@ -213,11 +213,11 @@ const chatStore = (initial?: Partial) => createStore()( computedProgressValue(taskId: string) { const { tasks, setProgressValue, activeTaskId } = get() const taskRunning = [...tasks[taskId].taskRunning] - const finshedTask = taskRunning?.filter( + const finishedTask = taskRunning?.filter( (task) => task.status === "completed" || task.status === "failed" ).length; const taskProgress = ( - ((finshedTask || 0) / (taskRunning?.length || 0)) * + ((finishedTask || 0) / (taskRunning?.length || 0)) * 100 ).toFixed(2); setProgressValue( @@ -1056,7 +1056,7 @@ const chatStore = (initial?: Partial) => createStore()( if (agentMessages.step === "new_task_state") { const { task_id, content, state, result, failure_count } = agentMessages.data; //new chatStore logic is handled along side "confirmed" event - console.log(`Recieved new task: ${task_id} with content: ${content}`); + console.log(`Received new task: ${task_id} with content: ${content}`); return; } diff --git a/test/integration/chatStore/deadWorkforce.test.tsx b/test/integration/chatStore/deadWorkforce.test.tsx index 8e362187..e5563530 100644 --- a/test/integration/chatStore/deadWorkforce.test.tsx +++ b/test/integration/chatStore/deadWorkforce.test.tsx @@ -172,7 +172,7 @@ describe('Integration Test: Case 2 - same session new chat', () => { console.log("Progress test - task status:", task?.status); }, { timeout: 1500 }) - // Test 3: Rerender untill status is "finished" + // Test 3: Rerender until status is "finished" await waitFor(() => { rerender() const {chatStore: newChatStore} = result.current; @@ -392,7 +392,7 @@ describe('Integration Test: Case 2 - same session new chat', () => { }) }) - //TODO: Don't let new startTask untill newChatStore appended + //TODO: Don't let new startTask until newChatStore appended it("Parallel startTask calls with separate chatStores (startTask -> wait for append -> startTask)", async () => { const { result, rerender } = renderHook(() => useChatStoreAdapter()) From 35b4420ac5b14ec97529e56b2cab9eceaf8a2226 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 06:15:00 +0800 Subject: [PATCH 20/63] enhance: stealth electron PR923 --- electron/main/index.ts | 5 +-- electron/main/webview.ts | 77 ++++++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/electron/main/index.ts b/electron/main/index.ts index 11456e8a..1261ec42 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -120,9 +120,10 @@ app.commandLine.appendSwitch( ); // Override User Agent to remove Electron/eigent identifiers -// Dynamically generate User Agent based on actual platform +// Dynamically generate User Agent based on actual platform and Chrome version const getPlatformUA = () => { - const chromeVersion = '131.0.0.0'; + // Use actual Chrome version from Electron instead of hardcoded value + const chromeVersion = process.versions.chrome || '131.0.0.0'; switch (process.platform) { case 'darwin': return `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`; diff --git a/electron/main/webview.ts b/electron/main/webview.ts index 17dac070..96dd86e1 100644 --- a/electron/main/webview.ts +++ b/electron/main/webview.ts @@ -80,50 +80,63 @@ export class WebViewManager { view.webContents.on('did-finish-load', () => { // Inject stealth script to avoid bot detection view.webContents.executeJavaScript(` + // Save original values before overriding to maintain consistency + const originalLanguages = navigator.languages ? [...navigator.languages] : ['en-US', 'en']; + const originalHardwareConcurrency = navigator.hardwareConcurrency || 8; + const originalDeviceMemory = navigator.deviceMemory || 8; + // Hide webdriver property Object.defineProperty(navigator, 'webdriver', { get: () => undefined, configurable: true }); - // Override plugins + // Override plugins with proper PluginArray-like behavior Object.defineProperty(navigator, 'plugins', { - get: () => ({ - length: 3, - 0: { name: 'Chrome PDF Plugin', description: 'Portable Document Format', filename: 'internal-pdf-viewer' }, - 1: { name: 'Chrome PDF Viewer', description: '', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai' }, - 2: { name: 'Native Client', description: '', filename: 'internal-nacl-plugin' }, - item: function(index) { return this[index] || null; }, - namedItem: function(name) { - for (let i = 0; i < this.length; i++) { - if (this[i].name === name) return this[i]; + get: () => { + const plugins = { + length: 3, + 0: { name: 'Chrome PDF Plugin', description: 'Portable Document Format', filename: 'internal-pdf-viewer' }, + 1: { name: 'Chrome PDF Viewer', description: '', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai' }, + 2: { name: 'Native Client', description: '', filename: 'internal-nacl-plugin' }, + item: function(index) { return this[index] || null; }, + namedItem: function(name) { + for (let i = 0; i < this.length; i++) { + if (this[i].name === name) return this[i]; + } + return null; + }, + refresh: function() {}, + [Symbol.iterator]: function* () { + for (let i = 0; i < this.length; i++) { + yield this[i]; + } } - return null; - }, - refresh: function() {} - }), + }; + return plugins; + }, configurable: true }); - // Override languages + // Use original system languages for consistency with other browser data Object.defineProperty(navigator, 'languages', { - get: () => ['en-US', 'en'], + get: () => originalLanguages, configurable: true }); - // Override hardwareConcurrency + // Use original hardwareConcurrency, clamped to common range (4-16) to avoid extreme fingerprints Object.defineProperty(navigator, 'hardwareConcurrency', { - get: () => 8, + get: () => Math.min(Math.max(originalHardwareConcurrency, 4), 16), configurable: true }); - // Override deviceMemory + // Use original deviceMemory, clamped to common range (4-16) to avoid extreme fingerprints Object.defineProperty(navigator, 'deviceMemory', { - get: () => 8, + get: () => Math.min(Math.max(originalDeviceMemory, 4), 16), configurable: true }); - // Fix WebGL vendor/renderer + // Fix WebGL vendor/renderer for both WebGL and WebGL2 const getParameter = WebGLRenderingContext.prototype.getParameter; WebGLRenderingContext.prototype.getParameter = function(parameter) { if (parameter === 37445) return 'Intel Inc.'; @@ -131,12 +144,22 @@ export class WebViewManager { return getParameter.call(this, parameter); }; - // Override chrome runtime - if (!window.chrome) window.chrome = {}; - window.chrome.runtime = { - onConnect: undefined, - onMessage: undefined - }; + // Also patch WebGL2RenderingContext + if (typeof WebGL2RenderingContext !== 'undefined') { + const getParameter2 = WebGL2RenderingContext.prototype.getParameter; + WebGL2RenderingContext.prototype.getParameter = function(parameter) { + if (parameter === 37445) return 'Intel Inc.'; + if (parameter === 37446) return 'Intel(R) Iris(TM) Graphics 6100'; + return getParameter2.call(this, parameter); + }; + } + + // Override chrome runtime - real Chrome has window.chrome but runtime is undefined + if (!window.chrome) { + window.chrome = {}; + } + // In real Chrome, runtime exists but is undefined outside extensions + // Don't set it to an object, that's detectable // Hide automation variables const automationVars = ['__webdriver_evaluate', '__selenium_evaluate', '__webdriver_script_fn', From 3a1ecb1c3373c9aa2b53dd9607e7de7e29130187 Mon Sep 17 00:00:00 2001 From: leonace924 Date: Mon, 19 Jan 2026 19:16:38 +0100 Subject: [PATCH 21/63] [Fix] tool list per agent not rendering properly (#957) --- src/components/AddWorker/ToolSelect.tsx | 2 +- src/components/AddWorker/index.tsx | 2 +- src/components/WorkFlow/node.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/AddWorker/ToolSelect.tsx b/src/components/AddWorker/ToolSelect.tsx index 24e45502..d2be3cd5 100644 --- a/src/components/AddWorker/ToolSelect.tsx +++ b/src/components/AddWorker/ToolSelect.tsx @@ -630,7 +630,7 @@ const ToolSelect = forwardRef< key={item.id + item.key + (item.isLocal + "")} className="h-5 bg-button-tertiery-fill-default flex items-center gap-1 w-auto flex-shrink-0 px-xs" > - {item.name || item.mcp_name} + {item.name || item.mcp_name || item.key || "Unknown Tool"}
tool.name)], + tools: [...selectedTools.map((tool) => tool.name || tool.key || tool.mcp_name || "")], activeWebviewIds: [], workerInfo: { name: workerName, diff --git a/src/components/WorkFlow/node.tsx b/src/components/WorkFlow/node.tsx index 0f5a5e8f..a897f6a5 100644 --- a/src/components/WorkFlow/node.tsx +++ b/src/components/WorkFlow/node.tsx @@ -420,7 +420,7 @@ export function Node({ id, data }: NodeProps) {
{/* {JSON.stringify(data.agent)} */} {agentToolkits[ From c25b38fdde8e5197d41a9a4e83fc78987bb8faf1 Mon Sep 17 00:00:00 2001 From: puzhen <1303385763@qq.com> Date: Mon, 19 Jan 2026 22:24:47 +0000 Subject: [PATCH 22/63] update workforce construct to parallel initialization --- backend/app/service/chat_service.py | 17 +++++++++++++++-- src/store/chatStore.ts | 16 ++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/backend/app/service/chat_service.py b/backend/app/service/chat_service.py index 71f5d427..5bda2910 100644 --- a/backend/app/service/chat_service.py +++ b/backend/app/service/chat_service.py @@ -477,7 +477,7 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): # Stream decomposition in background so queue items (decompose_text) are processed immediately logger.info(f"[NEW-QUESTION] 🧩 Starting task decomposition via workforce.eigent_make_sub_tasks") - stream_state = {"subtasks": [], "seen_ids": set(), "last_content": ""} + stream_state = {"subtasks": [], "seen_ids": set(), "last_content": "", "first_token_logged": False} state_holder: dict[str, Any] = {"sub_tasks": [], "summary_task": ""} def on_stream_batch(new_tasks: list[Task], is_final: bool = False): @@ -502,6 +502,12 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): stream_state["last_content"] = accumulated_content if delta_content: + # === TIMING: Log TTFT (Time to First Token) === + if not stream_state["first_token_logged"]: + stream_state["first_token_logged"] = True + ttft = (time_module.time() - task_lock.decomposition_start_time) * 1000 + logger.info(f"⏱️ [TIMING] 🚀 TTFT (Time to First Token): {ttft:.2f}ms - First streaming token received for task decomposition") + asyncio.run_coroutine_threadsafe( task_lock.put_queue( ActionDecomposeTextData( @@ -841,7 +847,8 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): context_for_multi_turn = build_context_for_workforce(task_lock, options) logger.info(f"[LIFECYCLE] Multi-turn: calling workforce.handle_decompose_append_task for new task decomposition") - stream_state = {"subtasks": [], "seen_ids": set(), "last_content": ""} + multi_turn_decompose_start = time_module.time() + stream_state = {"subtasks": [], "seen_ids": set(), "last_content": "", "first_token_logged": False, "start_time": multi_turn_decompose_start} def on_stream_batch(new_tasks: list[Task], is_final: bool = False): fresh_tasks = [t for t in new_tasks if t.id not in stream_state["seen_ids"]] @@ -864,6 +871,12 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): stream_state["last_content"] = accumulated_content if delta_content: + # === TIMING: Log TTFT (Time to First Token) for multi-turn === + if not stream_state["first_token_logged"]: + stream_state["first_token_logged"] = True + ttft = (time_module.time() - stream_state["start_time"]) * 1000 + logger.info(f"⏱️ [TIMING] 🚀 TTFT (Time to First Token): {ttft:.2f}ms - First streaming token received for multi-turn task decomposition") + asyncio.run_coroutine_threadsafe( task_lock.put_queue( ActionDecomposeTextData( diff --git a/src/store/chatStore.ts b/src/store/chatStore.ts index 2b475693..4f00e8e7 100644 --- a/src/store/chatStore.ts +++ b/src/store/chatStore.ts @@ -159,6 +159,8 @@ const resolveProcessTaskIdForToolkitEvent = ( // Throttle streaming decompose text updates to prevent excessive re-renders const streamingDecomposeTextBuffer: Record = {}; const streamingDecomposeTextTimers: Record> = {}; +// TTFT (Time to First Token) tracking for task decomposition +const ttftTracking: Record = {}; const chatStore = (initial?: Partial) => createStore()( (set, get) => ({ @@ -757,6 +759,11 @@ const chatStore = (initial?: Partial) => createStore()( //Enable it for the rest of current SSE session skipFirstConfirm = false; + + // Record confirmed time for TTFT tracking + const ttftTaskId = getCurrentTaskId(); + ttftTracking[ttftTaskId] = { confirmedAt: performance.now(), firstTokenLogged: false }; + console.log(`[TTFT] Task ${ttftTaskId} confirmed at ${new Date().toISOString()}, starting TTFT measurement`); return } @@ -796,6 +803,13 @@ const chatStore = (initial?: Partial) => createStore()( const text = content; const currentId = getCurrentTaskId(); + // Log TTFT (Time to First Token) on first decompose_text event + if (ttftTracking[currentId] && !ttftTracking[currentId].firstTokenLogged) { + ttftTracking[currentId].firstTokenLogged = true; + const ttft = performance.now() - ttftTracking[currentId].confirmedAt; + console.log(`%c[TTFT] 🚀 Time to First Token: ${ttft.toFixed(2)}ms - First streaming token received for task ${currentId}`, 'color: #4CAF50; font-weight: bold'); + } + // Get current buffer or task state const currentContent = streamingDecomposeTextBuffer[currentId] || getCurrentChatStore().tasks[currentId]?.streamingDecomposeText || ""; @@ -829,6 +843,8 @@ const chatStore = (initial?: Partial) => createStore()( if (agentMessages.step === "to_sub_tasks") { // Clear streaming decompose text when task splitting is done clearStreamingDecomposeText(currentTaskId); + // Clean up TTFT tracking + delete ttftTracking[currentTaskId]; // Check if this is a multi-turn scenario after task completion const isMultiTurnAfterCompletion = tasks[currentTaskId].status === 'finished'; From e26f7316ac138a50b44058e03b393373b7c5d222 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 06:27:03 +0800 Subject: [PATCH 23/63] minor update based on review --- .github/workflows/build.yml | 9 ++++++++- package.json | 2 +- scripts/preinstall-deps.js | 10 ++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0a290420..1dd0b679 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,6 +56,13 @@ jobs: - name: Install Dependencies run: npm install + # Install libfuse2 for Linux AppImage builds + - name: Install libfuse2 (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y libfuse2 + # Step for macOS builds with signing - name: Build Release Files (macOS with signing) if: runner.os == 'macOS' @@ -185,4 +192,4 @@ jobs: release/win-x64/* release/linux-x64/* env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index aabe476d..9cdd6453 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "build:mac:test": "npm run preinstall-deps && npm run clean-symlinks && npm run compile-babel && tsc && vite build && electron-builder --mac && npm run test-signing", "build:win": "npm run preinstall-deps && npm run compile-babel && tsc && vite build && electron-builder --win", "build:linux": "npm run preinstall-deps && npm run clean-symlinks && npm run compile-babel && tsc && vite build && electron-builder --linux", - "build:all": "npm run preinstall-deps && npm run compile-babel && tsc && vite build && electron-builder --mac --win", + "build:all": "npm run preinstall-deps && npm run compile-babel && tsc && vite build && electron-builder --mac --win --linux", "preview": "vite preview", "pretest": "vite build --mode=test", "test": "vitest run", diff --git a/scripts/preinstall-deps.js b/scripts/preinstall-deps.js index b34f35a1..a5ef3311 100644 --- a/scripts/preinstall-deps.js +++ b/scripts/preinstall-deps.js @@ -399,12 +399,14 @@ async function installUv() { const targetPath = path.join(BIN_DIR, 'uv'); if (fs.existsSync(nestedUvPath)) { console.log(` Found uv in ${nestedDir}, moving...`); - if (fs.existsSync(targetPath)) fs.unlinkSync(targetPath); - fs.renameSync(nestedUvPath, targetPath); - // Clean up directory try { + if (fs.existsSync(targetPath)) fs.unlinkSync(targetPath); + fs.renameSync(nestedUvPath, targetPath); + // Clean up directory fs.rmSync(path.join(BIN_DIR, nestedDir), { recursive: true, force: true }); - } catch (e) { console.log(' Warning: Failed to cleanup nested dir'); } + } catch (e) { + console.log(` Warning: Failed to move uv from nested dir: ${e.message}`); + } } } } From afea64c0005c9657fd575a0e83b6853405f4837e Mon Sep 17 00:00:00 2001 From: Dream <42954461+eureka928@users.noreply.github.com> Date: Mon, 19 Jan 2026 17:33:29 -0500 Subject: [PATCH 24/63] Update src/components/AddWorker/index.tsx Co-authored-by: bytecraftii <994513625@qq.com> --- src/components/AddWorker/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddWorker/index.tsx b/src/components/AddWorker/index.tsx index 1c128c90..6f1ec63f 100644 --- a/src/components/AddWorker/index.tsx +++ b/src/components/AddWorker/index.tsx @@ -282,7 +282,7 @@ export function AddWorker({ name: workerName, type: workerName as AgentNameType, log: [], - tools: [...selectedTools.map((tool) => tool.name || tool.key || tool.mcp_name || "")], + tools: [...selectedTools.map((tool) => tool.name || tool.mcp_name || tool.key || "Unknown Tool")], activeWebviewIds: [], workerInfo: { name: workerName, From 054f4c92b1770c0a6c5458f2ce8fd688a5fd1c8f Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 06:41:15 +0800 Subject: [PATCH 25/63] fix unused return --- backend/app/utils/toolkit/hybrid_browser_toolkit.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/app/utils/toolkit/hybrid_browser_toolkit.py b/backend/app/utils/toolkit/hybrid_browser_toolkit.py index 0b814f5a..5ed39a82 100644 --- a/backend/app/utils/toolkit/hybrid_browser_toolkit.py +++ b/backend/app/utils/toolkit/hybrid_browser_toolkit.py @@ -350,8 +350,6 @@ class HybridBrowserToolkit(BaseHybridBrowserToolkit, AbstractToolkit): full_visual_mode=self._full_visual_mode, ) - return cloned_toolkit - async def browser_sheet_input(self, *, cells: List[SheetCell]) -> Dict[str, Any]: # Use typing_extensions.TypedDict for Pydantic <3.12 compatibility. return await super().browser_sheet_input(cells=cells) From 438913cc93ec71e92a7af4248b0f1fd5ac11748c Mon Sep 17 00:00:00 2001 From: puzhen <1303385763@qq.com> Date: Mon, 19 Jan 2026 22:47:55 +0000 Subject: [PATCH 26/63] parallel optimize --- backend/app/service/chat_service.py | 238 +++++++++++++++++----------- backend/app/utils/agent.py | 124 +++++++++++++-- backend/app/utils/workforce.py | 14 ++ 3 files changed, 273 insertions(+), 103 deletions(-) diff --git a/backend/app/service/chat_service.py b/backend/app/service/chat_service.py index 5bda2910..561d903c 100644 --- a/backend/app/service/chat_service.py +++ b/backend/app/service/chat_service.py @@ -40,6 +40,7 @@ from app.utils.agent import ( social_medium_agent, task_summary_agent, question_confirm_agent, + set_main_event_loop, ) from app.service.task import Action, Agents from app.utils.server.sync_step import sync_step @@ -247,6 +248,8 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): start_event_loop = True + # === TIMING: Task lock initialization === + init_start = time_module.time() if not hasattr(task_lock, 'conversation_history'): task_lock.conversation_history = [] if not hasattr(task_lock, 'last_task_result'): @@ -255,11 +258,16 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): task_lock.question_agent = None if not hasattr(task_lock, 'summary_generated'): task_lock.summary_generated = False + init_time = (time_module.time() - init_start) * 1000 + logger.info(f"⏱️ [TIMING] Task lock attrs initialized in {init_time:.2f}ms") # Create or reuse persistent question_agent + # === TIMING: question_agent creation === + question_agent_start = time_module.time() if task_lock.question_agent is None: task_lock.question_agent = question_confirm_agent(options) - logger.info(f"Created new persistent question_agent for project {options.project_id}") + question_agent_time = (time_module.time() - question_agent_start) * 1000 + logger.info(f"⏱️ [TIMING] question_confirm_agent created in {question_agent_time:.2f}ms") else: logger.info(f"Reusing existing question_agent with {len(task_lock.conversation_history)} history entries") @@ -1372,31 +1380,46 @@ async def get_task_result_with_optional_summary(task: Task, options: Chat) -> st @traceroot.trace() async def construct_workforce(options: Chat) -> tuple[Workforce, ListenChatAgent]: + """Construct a workforce with all required agents. + + This function creates all agents in PARALLEL to minimize startup time. + Sync functions are run in thread pool, async functions are awaited concurrently. + """ import time as time_module + # === TIMING: construct_workforce start === construct_start = time_module.time() - logger.info("⏱️ [TIMING] construct_workforce started", extra={"project_id": options.project_id, "task_id": options.task_id}) + logger.info("⏱️ [TIMING] construct_workforce started (PARALLEL mode)", extra={"project_id": options.project_id, "task_id": options.task_id}) + + # Store main event loop reference for thread-safe async task scheduling + # This allows agent_model() to schedule tasks when called from worker threads + set_main_event_loop(asyncio.get_running_loop()) working_directory = get_working_directory(options) logger.debug("Working directory set", extra={"working_directory": working_directory}) - # === TIMING: Coordinator and Task agent creation === - coord_task_agent_start = time_module.time() - [coordinator_agent, task_agent] = [ - agent_model( - key, - prompt, - options, - [ - *( - ToolkitMessageIntegration( - message_handler=HumanToolkit(options.project_id, key).send_message_to_user - ).register_toolkits(NoteTakingToolkit(options.project_id, working_directory=working_directory)) - ).get_tools() - ], - ) - for key, prompt in { - Agents.coordinator_agent: f""" + # ======================================================================== + # Define sync agent creation functions (will be run in thread pool) + # ======================================================================== + + def _create_coordinator_and_task_agents() -> list[ListenChatAgent]: + """Create coordinator and task agents (sync, runs in thread pool).""" + start = time_module.time() + agents = [ + agent_model( + key, + prompt, + options, + [ + *( + ToolkitMessageIntegration( + message_handler=HumanToolkit(options.project_id, key).send_message_to_user + ).register_toolkits(NoteTakingToolkit(options.project_id, working_directory=working_directory)) + ).get_tools() + ], + ) + for key, prompt in { + Agents.coordinator_agent: f""" You are a helpful coordinator. - You are now working in system {platform.system()} with architecture {platform.machine()} at working directory `{working_directory}`. All local file operations must occur here, but you can access files from any place in the file system. For all file system operations, you MUST use absolute paths to ensure precision and avoid ambiguity. @@ -1406,76 +1429,130 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS `Developer_Agent`. The `Developer_Agent` is a powerful agent with terminal access and can resolve a wide range of issues. """, - Agents.task_agent: f""" + Agents.task_agent: f""" You are a helpful task planner. - You are now working in system {platform.system()} with architecture {platform.machine()} at working directory `{working_directory}`. All local file operations must occur here, but you can access files from any place in the file system. For all file system operations, you MUST use absolute paths to ensure precision and avoid ambiguity. The current date is {datetime.date.today()}. For any date-related tasks, you MUST use this as the current date. """, - }.items() - ] - coord_task_agent_time = (time_module.time() - coord_task_agent_start) * 1000 - logger.info(f"⏱️ [TIMING] Coordinator + Task agent created in {coord_task_agent_time:.2f}ms") + }.items() + ] + elapsed = (time_module.time() - start) * 1000 + logger.info(f"⏱️ [TIMING] Coordinator + Task agents created in {elapsed:.2f}ms (thread)") + return agents - # === TIMING: New worker agent creation === - new_worker_start = time_module.time() - new_worker_agent = agent_model( - Agents.new_worker_agent, - f""" + def _create_new_worker_agent() -> ListenChatAgent: + """Create new worker agent (sync, runs in thread pool).""" + start = time_module.time() + agent = agent_model( + Agents.new_worker_agent, + f""" You are a helpful assistant. - You are now working in system {platform.system()} with architecture {platform.machine()} at working directory `{working_directory}`. All local file operations must occur here, but you can access files from any place in the file system. For all file system operations, you MUST use absolute paths to ensure precision and avoid ambiguity. The current date is {datetime.date.today()}. For any date-related tasks, you MUST use this as the current date. """, - options, - [ - *HumanToolkit.get_can_use_tools(options.project_id, Agents.new_worker_agent), - *( - ToolkitMessageIntegration( - message_handler=HumanToolkit(options.project_id, Agents.new_worker_agent).send_message_to_user - ).register_toolkits(NoteTakingToolkit(options.project_id, working_directory=working_directory)) - ).get_tools(), - ], + options, + [ + *HumanToolkit.get_can_use_tools(options.project_id, Agents.new_worker_agent), + *( + ToolkitMessageIntegration( + message_handler=HumanToolkit(options.project_id, Agents.new_worker_agent).send_message_to_user + ).register_toolkits(NoteTakingToolkit(options.project_id, working_directory=working_directory)) + ).get_tools(), + ], + ) + elapsed = (time_module.time() - start) * 1000 + logger.info(f"⏱️ [TIMING] New worker agent created in {elapsed:.2f}ms (thread)") + return agent + + def _create_browser_agent() -> ListenChatAgent: + """Create browser agent (sync, runs in thread pool).""" + start = time_module.time() + agent = browser_agent(options) + elapsed = (time_module.time() - start) * 1000 + logger.info(f"⏱️ [TIMING] Browser agent created in {elapsed:.2f}ms (thread)") + return agent + + def _create_multi_modal_agent() -> ListenChatAgent: + """Create multi-modal agent (sync, runs in thread pool).""" + start = time_module.time() + agent = multi_modal_agent(options) + elapsed = (time_module.time() - start) * 1000 + logger.info(f"⏱️ [TIMING] Multi-modal agent created in {elapsed:.2f}ms (thread)") + return agent + + # ======================================================================== + # Define async agent creation wrappers (for timing) + # ======================================================================== + + async def _create_developer_agent() -> ListenChatAgent: + """Create developer agent (async).""" + start = time_module.time() + agent = await developer_agent(options) + elapsed = (time_module.time() - start) * 1000 + logger.info(f"⏱️ [TIMING] Developer agent created in {elapsed:.2f}ms (async)") + return agent + + async def _create_document_agent() -> ListenChatAgent: + """Create document agent (async).""" + start = time_module.time() + agent = await document_agent(options) + elapsed = (time_module.time() - start) * 1000 + logger.info(f"⏱️ [TIMING] Document agent created in {elapsed:.2f}ms (async)") + return agent + + async def _create_mcp_agent() -> ListenChatAgent: + """Create MCP agent (async).""" + start = time_module.time() + agent = await mcp_agent(options) + elapsed = (time_module.time() - start) * 1000 + logger.info(f"⏱️ [TIMING] MCP agent created in {elapsed:.2f}ms (async)") + return agent + + # ======================================================================== + # Execute all agent creations in PARALLEL + # ======================================================================== + + parallel_start = time_module.time() + logger.info("⏱️ [TIMING] Starting parallel agent creation...") + + # asyncio.gather runs all coroutines concurrently + # asyncio.to_thread runs sync functions in thread pool without blocking event loop + results = await asyncio.gather( + asyncio.to_thread(_create_coordinator_and_task_agents), # sync -> thread + asyncio.to_thread(_create_new_worker_agent), # sync -> thread + asyncio.to_thread(_create_browser_agent), # sync -> thread + _create_developer_agent(), # async + _create_document_agent(), # async + asyncio.to_thread(_create_multi_modal_agent), # sync -> thread + _create_mcp_agent(), # async ) - new_worker_time = (time_module.time() - new_worker_start) * 1000 - logger.info(f"⏱️ [TIMING] New worker agent created in {new_worker_time:.2f}ms") - # msg_toolkit = AgentCommunicationToolkit(max_message_history=100) - # === TIMING: Browser agent creation === - browser_start = time_module.time() - searcher = browser_agent(options) - browser_time = (time_module.time() - browser_start) * 1000 - logger.info(f"⏱️ [TIMING] Browser agent created in {browser_time:.2f}ms") + parallel_time = (time_module.time() - parallel_start) * 1000 + logger.info(f"⏱️ [TIMING] All agents created in parallel: {parallel_time:.2f}ms") - # === TIMING: Developer agent creation === - developer_start = time_module.time() - developer = await developer_agent(options) - developer_time = (time_module.time() - developer_start) * 1000 - logger.info(f"⏱️ [TIMING] Developer agent created in {developer_time:.2f}ms") + # Unpack results + ( + coord_task_agents, # [coordinator_agent, task_agent] + new_worker_agent, + searcher, # browser agent + developer, + documenter, + multi_modaler, + mcp, + ) = results - # === TIMING: Document agent creation === - document_start = time_module.time() - documenter = await document_agent(options) - document_time = (time_module.time() - document_start) * 1000 - logger.info(f"⏱️ [TIMING] Document agent created in {document_time:.2f}ms") + coordinator_agent, task_agent = coord_task_agents - # === TIMING: Multi-modal agent creation === - multi_modal_start = time_module.time() - multi_modaler = multi_modal_agent(options) - multi_modal_time = (time_module.time() - multi_modal_start) * 1000 - logger.info(f"⏱️ [TIMING] Multi-modal agent created in {multi_modal_time:.2f}ms") - - # msg_toolkit.register_agent("Worker", new_worker_agent) - # msg_toolkit.register_agent("Browser_Agent", searcher) - # msg_toolkit.register_agent("Developer_Agent", developer) - # msg_toolkit.register_agent("Document_Agent", documenter) - # msg_toolkit.register_agent("Multi_Modal_Agent", multi_modaler) + # ======================================================================== + # Create Workforce instance and add workers (must be sequential) + # ======================================================================== # Convert string model_platform to enum for comparison try: model_platform_enum = ModelPlatformType(options.model_platform.lower()) except (ValueError, AttributeError): - # If conversion fails, default to non-OpenAI behavior model_platform_enum = None # === TIMING: Workforce instance creation === @@ -1483,7 +1560,7 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS workforce = Workforce( options.project_id, "A workforce", - graceful_shutdown_timeout=3, # 30 seconds for debugging + graceful_shutdown_timeout=3, share_memory=False, coordinator_agent=coordinator_agent, task_agent=task_agent, @@ -1525,29 +1602,10 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS add_workers_time = (time_module.time() - add_workers_start) * 1000 logger.info(f"⏱️ [TIMING] Workers added to workforce in {add_workers_time:.2f}ms") - # workforce.add_single_agent_worker( - # "Social Media Agent: A social media management assistant for " - # "handling tasks related to WhatsApp, Twitter, LinkedIn, Reddit, " - # "Notion, Slack, and other social platforms.", - # await social_medium_agent(options), - # ) - - # === TIMING: MCP agent creation === - mcp_start = time_module.time() - mcp = await mcp_agent(options) - mcp_time = (time_module.time() - mcp_start) * 1000 - logger.info(f"⏱️ [TIMING] MCP agent created in {mcp_time:.2f}ms") - - # workforce.add_single_agent_worker( - # "MCP Agent: A Model Context Protocol agent that provides access " - # "to external tools and services through MCP integrations.", - # mcp, - # ) - # === TIMING: construct_workforce total === total_construct_time = (time_module.time() - construct_start) * 1000 - logger.info(f"⏱️ [TIMING] construct_workforce TOTAL: {total_construct_time:.2f}ms") - logger.info(f"⏱️ [TIMING] construct_workforce breakdown: coord+task={coord_task_agent_time:.2f}ms, new_worker={new_worker_time:.2f}ms, browser={browser_time:.2f}ms, developer={developer_time:.2f}ms, document={document_time:.2f}ms, multi_modal={multi_modal_time:.2f}ms, workforce_init={workforce_instance_time:.2f}ms, add_workers={add_workers_time:.2f}ms, mcp={mcp_time:.2f}ms") + logger.info(f"⏱️ [TIMING] construct_workforce TOTAL: {total_construct_time:.2f}ms (parallel agents: {parallel_time:.2f}ms)") + logger.info(f"⏱️ [TIMING] construct_workforce summary: parallel_agents={parallel_time:.2f}ms, workforce_init={workforce_instance_time:.2f}ms, add_workers={add_workers_time:.2f}ms") return workforce, mcp diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index b09def0d..1c007f9e 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -7,6 +7,42 @@ import traceback from typing import Any, Callable, Dict, List, Tuple import uuid from utils import traceroot_wrapper as traceroot + +# Thread-safe reference to main event loop for scheduling tasks from worker threads +_main_event_loop: asyncio.AbstractEventLoop | None = None + + +def set_main_event_loop(loop: asyncio.AbstractEventLoop | None): + """Set the main event loop reference for thread-safe task scheduling. + + This should be called from the main async context before spawning threads + that need to schedule async tasks. + """ + global _main_event_loop + _main_event_loop = loop + + +def _schedule_async_task(coro): + """Schedule an async coroutine as a task, thread-safe. + + This function handles scheduling from both the main event loop thread + and from worker threads (e.g., when using asyncio.to_thread). + """ + try: + # Try to get the running loop (works in main event loop thread) + loop = asyncio.get_running_loop() + loop.create_task(coro) + except RuntimeError: + # No running loop in this thread (we're in a worker thread) + # Use the stored main loop reference + if _main_event_loop is not None and _main_event_loop.is_running(): + asyncio.run_coroutine_threadsafe(coro, _main_event_loop) + else: + # Fallback: run synchronously (not ideal but works) + traceroot.get_logger("agent").warning( + "No event loop available for async task scheduling, running synchronously" + ) + asyncio.run(coro) from camel.agents import ChatAgent from camel.agents.chat_agent import ( StreamingChatAgentResponse, @@ -666,12 +702,16 @@ def agent_model( toolkits_to_register_agent: list[RegisteredAgentToolkit] | None = None, enable_snapshot_clean: bool = False, ): + import time as time_module + agent_model_start = time_module.time() + task_lock = get_task_lock(options.project_id) agent_id = str(uuid.uuid4()) traceroot_logger.info( f"Creating agent: {agent_name} with id: {agent_id} for project: {options.project_id}" ) - asyncio.create_task( + # Use thread-safe scheduling to support parallel agent creation + _schedule_async_task( task_lock.put_queue( ActionCreateAgentData( data={ @@ -735,18 +775,25 @@ def agent_model( ) model_platform_enum = None - return ListenChatAgent( + # === TIMING: ModelFactory.create === + t0 = time_module.time() + model = ModelFactory.create( + model_platform=options.model_platform, + model_type=options.model_type, + api_key=options.api_key, + url=options.api_url, + model_config_dict=model_config or None, + **init_params, + ) + model_create_time = (time_module.time() - t0) * 1000 + + # === TIMING: ListenChatAgent creation === + t0 = time_module.time() + agent = ListenChatAgent( options.project_id, agent_name, system_message, - model=ModelFactory.create( - model_platform=options.model_platform, - model_type=options.model_type, - api_key=options.api_key, - url=options.api_url, - model_config_dict=model_config or None, - **init_params, - ), + model=model, # output_language=options.language, tools=tools, agent_id=agent_id, @@ -755,6 +802,11 @@ def agent_model( enable_snapshot_clean=enable_snapshot_clean, stream_accumulate=False, ) + agent_create_time = (time_module.time() - t0) * 1000 + + total_time = (time_module.time() - agent_model_start) * 1000 + traceroot_logger.info(f"⏱️ [TIMING] agent_model({agent_name}): {total_time:.2f}ms (model_create={model_create_time:.2f}ms, agent_create={agent_create_time:.2f}ms)") + return agent @traceroot.trace() @@ -967,16 +1019,25 @@ these tips to maximize your effectiveness: @traceroot.trace() def browser_agent(options: Chat): + import time as time_module + browser_agent_start = time_module.time() + working_directory = get_working_directory(options) traceroot_logger.info( f"Creating browser agent for project: {options.project_id} in directory: {working_directory}" ) + + # === TIMING: message_integration === + t0 = time_module.time() message_integration = ToolkitMessageIntegration( message_handler=HumanToolkit( options.project_id, Agents.browser_agent ).send_message_to_user ) + traceroot_logger.info(f"⏱️ [TIMING] browser_agent: message_integration in {(time_module.time() - t0) * 1000:.2f}ms") + # === TIMING: HybridBrowserToolkit === + t0 = time_module.time() web_toolkit_custom = HybridBrowserToolkit( options.project_id, headless=False, @@ -1000,10 +1061,14 @@ def browser_agent(options: Chat): # "browser_get_som_screenshot", ], ) + traceroot_logger.info(f"⏱️ [TIMING] browser_agent: HybridBrowserToolkit in {(time_module.time() - t0) * 1000:.2f}ms") # Save reference before registering for toolkits_to_register_agent web_toolkit_for_agent_registration = web_toolkit_custom web_toolkit_custom = message_integration.register_toolkits(web_toolkit_custom) + + # === TIMING: TerminalToolkit (already has internal timing) === + t0 = time_module.time() terminal_toolkit = TerminalToolkit( options.project_id, Agents.browser_agent, @@ -1013,17 +1078,25 @@ def browser_agent(options: Chat): terminal_toolkit = message_integration.register_functions( [terminal_toolkit.shell_exec] ) + traceroot_logger.info(f"⏱️ [TIMING] browser_agent: TerminalToolkit+register in {(time_module.time() - t0) * 1000:.2f}ms") + # === TIMING: NoteTakingToolkit === + t0 = time_module.time() note_toolkit = NoteTakingToolkit( options.project_id, Agents.browser_agent, working_directory=working_directory ) note_toolkit = message_integration.register_toolkits(note_toolkit) + traceroot_logger.info(f"⏱️ [TIMING] browser_agent: NoteTakingToolkit in {(time_module.time() - t0) * 1000:.2f}ms") + + # === TIMING: SearchToolkit === + t0 = time_module.time() search_tools = SearchToolkit.get_can_use_tools(options.project_id) # Only register search tools if any are available if search_tools: search_tools = message_integration.register_functions(search_tools) else: search_tools = [] + traceroot_logger.info(f"⏱️ [TIMING] browser_agent: SearchToolkit in {(time_module.time() - t0) * 1000:.2f}ms") tools = [ *HumanToolkit.get_can_use_tools(options.project_id, Agents.browser_agent), @@ -1168,10 +1241,15 @@ Your approach depends on available search tools: @traceroot.trace() async def document_agent(options: Chat): + import time as time_module + working_directory = get_working_directory(options) traceroot_logger.info( f"Creating document agent for project: {options.project_id} in directory: {working_directory}" ) + + # === TIMING: Toolkits creation === + t0 = time_module.time() message_integration = ToolkitMessageIntegration( message_handler=HumanToolkit( options.project_id, Agents.task_agent @@ -1192,6 +1270,9 @@ async def document_agent(options: Chat): options.project_id, Agents.document_agent, working_directory=working_directory ) note_toolkit = message_integration.register_toolkits(note_toolkit) + traceroot_logger.info(f"⏱️ [TIMING] document_agent: basic toolkits in {(time_module.time() - t0) * 1000:.2f}ms") + + t0 = time_module.time() terminal_toolkit = TerminalToolkit( options.project_id, Agents.document_agent, @@ -1199,6 +1280,15 @@ async def document_agent(options: Chat): clone_current_env=True, ) terminal_toolkit = message_integration.register_toolkits(terminal_toolkit) + traceroot_logger.info(f"⏱️ [TIMING] document_agent: TerminalToolkit in {(time_module.time() - t0) * 1000:.2f}ms") + + # === TIMING: GoogleDriveMCPToolkit (async) === + t0 = time_module.time() + google_drive_tools = await GoogleDriveMCPToolkit.get_can_use_tools( + options.project_id, options.get_bun_env() + ) + traceroot_logger.info(f"⏱️ [TIMING] document_agent: GoogleDriveMCPToolkit in {(time_module.time() - t0) * 1000:.2f}ms") + tools = [ *file_write_toolkit.get_tools(), *pptx_toolkit.get_tools(), @@ -1207,9 +1297,7 @@ async def document_agent(options: Chat): *excel_toolkit.get_tools(), *note_toolkit.get_tools(), *terminal_toolkit.get_tools(), - *await GoogleDriveMCPToolkit.get_can_use_tools( - options.project_id, options.get_bun_env() - ), + *google_drive_tools, ] # if env("EXA_API_KEY") or options.is_cloud(): # search_toolkit = SearchToolkit(options.project_id, Agents.document_agent).search_exa @@ -1391,10 +1479,15 @@ supported formats including advanced spreadsheet functionality. @traceroot.trace() def multi_modal_agent(options: Chat): + import time as time_module + working_directory = get_working_directory(options) traceroot_logger.info( f"Creating multi-modal agent for project: {options.project_id} in directory: {working_directory}" ) + + # === TIMING: Basic toolkits === + t0 = time_module.time() message_integration = ToolkitMessageIntegration( message_handler=HumanToolkit( options.project_id, Agents.multi_modal_agent @@ -1410,7 +1503,10 @@ def multi_modal_agent(options: Chat): image_analysis_toolkit = message_integration.register_toolkits( image_analysis_toolkit ) + traceroot_logger.info(f"⏱️ [TIMING] multi_modal_agent: basic toolkits in {(time_module.time() - t0) * 1000:.2f}ms") + # === TIMING: TerminalToolkit === + t0 = time_module.time() terminal_toolkit = TerminalToolkit( options.project_id, agent_name=Agents.multi_modal_agent, @@ -1418,6 +1514,8 @@ def multi_modal_agent(options: Chat): clone_current_env=True, ) terminal_toolkit = message_integration.register_toolkits(terminal_toolkit) + traceroot_logger.info(f"⏱️ [TIMING] multi_modal_agent: TerminalToolkit in {(time_module.time() - t0) * 1000:.2f}ms") + note_toolkit = NoteTakingToolkit( options.project_id, Agents.multi_modal_agent, diff --git a/backend/app/utils/workforce.py b/backend/app/utils/workforce.py index a26c52a1..7f2afb94 100644 --- a/backend/app/utils/workforce.py +++ b/backend/app/utils/workforce.py @@ -453,15 +453,23 @@ class Workforce(BaseWorkforce): pool_max_size: int = DEFAULT_WORKER_POOL_SIZE, enable_workflow_memory: bool = False, ) -> BaseWorkforce: + import time as time_module + add_worker_start = time_module.time() + if self._state == WorkforceState.RUNNING: raise RuntimeError("Cannot add workers while workforce is running. Pause the workforce first.") # Validate worker agent compatibility + t0 = time_module.time() self._validate_agent_compatibility(worker, "Worker agent") + validate_time = (time_module.time() - t0) * 1000 # Ensure the worker agent shares this workforce's pause control + t0 = time_module.time() self._attach_pause_event_to_agent(worker) + attach_time = (time_module.time() - t0) * 1000 + t0 = time_module.time() worker_node = SingleAgentWorker( description=description, worker=worker, @@ -470,6 +478,7 @@ class Workforce(BaseWorkforce): context_utility=None, # Will be set during save/load operations enable_workflow_memory=enable_workflow_memory, ) + create_node_time = (time_module.time() - t0) * 1000 self._children.append(worker_node) # If we have a channel set up, set it for the new worker @@ -477,7 +486,9 @@ class Workforce(BaseWorkforce): worker_node.set_channel(self._channel) # If workforce is paused, start the worker's listening task + t0 = time_module.time() self._start_child_node_when_paused(worker_node.start()) + start_child_time = (time_module.time() - t0) * 1000 # Use proper CAMEL pattern for metrics logging metrics_callbacks = [cb for cb in self._callbacks if isinstance(cb, WorkforceMetrics)] @@ -488,6 +499,9 @@ class Workforce(BaseWorkforce): role=worker_node.description, ) metrics_callbacks[0].log_worker_created(event) + + total_time = (time_module.time() - add_worker_start) * 1000 + logger.info(f"⏱️ [TIMING] add_single_agent_worker: {total_time:.2f}ms (validate={validate_time:.2f}ms, attach={attach_time:.2f}ms, create_node={create_node_time:.2f}ms, start_child={start_child_time:.2f}ms) for {description[:30]}...") return self async def _handle_completed_task(self, task: Task) -> None: From 9755333a75664520dca4921ed0aca34caabd0e83 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 07:00:48 +0800 Subject: [PATCH 27/63] chore: update camel version to 0283 --- backend/app/utils/agent.py | 2 + backend/pyproject.toml | 2 +- backend/uv.lock | 154 +++++++++++++++++++------------------ server/pyproject.toml | 2 +- server/uv.lock | 105 ++++++++++++------------- 5 files changed, 135 insertions(+), 130 deletions(-) diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index 0a810658..47eabfff 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -639,7 +639,9 @@ class ListenChatAgent(ChatAgent): mask_tool_output=self.mask_tool_output, pause_event=self.pause_event, prune_tool_calls_from_memory=self.prune_tool_calls_from_memory, + enable_snapshot_clean=self._enable_snapshot_clean, step_timeout=self.step_timeout, + stream_accumulate=self.stream_accumulate, ) new_agent.process_task_id = self.process_task_id diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 9dbe8c24..172a1ea5 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -6,7 +6,7 @@ readme = "README.md" requires-python = ">=3.10,<3.11" dependencies = [ "pip>=23.0", - "camel-ai[eigent]==0.2.83a9", + "camel-ai[eigent]==0.2.83", "fastapi>=0.115.12", "fastapi-babel>=1.0.0", "uvicorn[standard]>=0.34.2", diff --git a/backend/uv.lock b/backend/uv.lock index fdde31a4..4259346e 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -192,15 +192,15 @@ wheels = [ [[package]] name = "azure-core" -version = "1.37.0" +version = "1.38.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ef/83/41c9371c8298999c67b007e308a0a3c4d6a59c6908fa9c62101f031f886f/azure_core-1.37.0.tar.gz", hash = "sha256:7064f2c11e4b97f340e8e8c6d923b822978be3016e46b7bc4aa4b337cfb48aee", size = 357620, upload-time = "2025-12-11T20:05:13.518Z" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/1b/e503e08e755ea94e7d3419c9242315f888fc664211c90d032e40479022bf/azure_core-1.38.0.tar.gz", hash = "sha256:8194d2682245a3e4e3151a667c686464c3786fed7918b394d035bdcd61bb5993", size = 363033, upload-time = "2026-01-12T17:03:05.535Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/34/a9914e676971a13d6cc671b1ed172f9804b50a3a80a143ff196e52f4c7ee/azure_core-1.37.0-py3-none-any.whl", hash = "sha256:b3abe2c59e7d6bb18b38c275a5029ff80f98990e7c90a5e646249a56630fcc19", size = 214006, upload-time = "2025-12-11T20:05:14.96Z" }, + { url = "https://files.pythonhosted.org/packages/fc/d8/b8fcba9464f02b121f39de2db2bf57f0b216fe11d014513d666e8634380d/azure_core-1.38.0-py3-none-any.whl", hash = "sha256:ab0c9b2cd71fecb1842d52c965c95285d3cfb38902f6766e4a471f1cd8905335", size = 217825, upload-time = "2026-01-12T17:03:07.291Z" }, ] [[package]] @@ -261,7 +261,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "aiofiles", specifier = ">=24.1.0" }, - { name = "camel-ai", extras = ["eigent"], specifier = "==0.2.83a9" }, + { name = "camel-ai", extras = ["eigent"], specifier = "==0.2.83" }, { name = "debugpy", specifier = ">=1.8.17" }, { name = "fastapi", specifier = ">=0.115.12" }, { name = "fastapi-babel", specifier = ">=1.0.0" }, @@ -309,35 +309,35 @@ wheels = [ [[package]] name = "boto3" -version = "1.42.24" +version = "1.42.30" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ee/21/8be0e3685c3a4868be48d8d2f6e5b4641727e1d8a5d396b8b401d2b5f06e/boto3-1.42.24.tar.gz", hash = "sha256:c47a2f40df933e3861fc66fd8d6b87ee36d4361663a7e7ba39a87f5a78b2eae1", size = 112788, upload-time = "2026-01-07T20:30:51.019Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/79/2dac8b7cb075cfa43908ee9af3f8ee06880d84b86013854c5cca8945afac/boto3-1.42.30.tar.gz", hash = "sha256:ba9cd2f7819637d15bfbeb63af4c567fcc8a7dcd7b93dd12734ec58601169538", size = 112809, upload-time = "2026-01-16T20:37:23.636Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/75/bbfccb268f9faa4f59030888e859dca9797a980b77d6a074113af73bd4bf/boto3-1.42.24-py3-none-any.whl", hash = "sha256:8ed6ad670a5a2d7f66c1b0d3362791b48392c7a08f78479f5d8ab319a4d9118f", size = 140572, upload-time = "2026-01-07T20:30:49.431Z" }, + { url = "https://files.pythonhosted.org/packages/52/b3/2c0d828c9f668292e277ca5232e6160dd5b4b660a3f076f20dd5378baa1e/boto3-1.42.30-py3-none-any.whl", hash = "sha256:d7e548bea65e0ae2c465c77de937bc686b591aee6a352d5a19a16bc751e591c1", size = 140573, upload-time = "2026-01-16T20:37:22.089Z" }, ] [[package]] name = "botocore" -version = "1.42.24" +version = "1.42.30" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/12/d7/bb4a4e839b238ffb67b002d7326b328ebe5eb23ed5180f2ca10399a802de/botocore-1.42.24.tar.gz", hash = "sha256:be8d1bea64fb91eea08254a1e5fea057e4428d08e61f4e11083a02cafc1f8cc6", size = 14878455, upload-time = "2026-01-07T20:30:40.379Z" } +sdist = { url = "https://files.pythonhosted.org/packages/44/38/23862628a0eb044c8b8b3d7a9ad1920b3bfd6bce6d746d5a871e8382c7e4/botocore-1.42.30.tar.gz", hash = "sha256:9bf1662b8273d5cc3828a49f71ca85abf4e021011c1f0a71f41a2ea5769a5116", size = 14891439, upload-time = "2026-01-16T20:37:13.77Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/d4/f2655d777eed8b069ecab3761454cb83f830f8be8b5b0d292e4b3a980d00/botocore-1.42.24-py3-none-any.whl", hash = "sha256:8fca9781d7c84f7ad070fceffaff7179c4aa7a5ffb27b43df9d1d957801e0a8d", size = 14551806, upload-time = "2026-01-07T20:30:38.103Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8d/6d7b016383b1f74dd93611b1c5078bbaddaca901553ab886dcda87cae365/botocore-1.42.30-py3-none-any.whl", hash = "sha256:97070a438cac92430bb7b65f8ebd7075224f4a289719da4ee293d22d1e98db02", size = 14566340, upload-time = "2026-01-16T20:37:10.94Z" }, ] [[package]] name = "camel-ai" -version = "0.2.83a9" +version = "0.2.83" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astor" }, @@ -354,9 +354,9 @@ dependencies = [ { name = "tiktoken" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/8c/7d8071776ba973bb6e734edb6caaf4fdbdf60ecebdc1c4017948cc67ad48/camel_ai-0.2.83a9.tar.gz", hash = "sha256:2ee560551797b089f9849d3b9d63cd3a2b4eb45d339d17e6bf95eba2b85c4b50", size = 1124774, upload-time = "2026-01-15T21:28:24.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/d1/36f0982862ba2b992968ace43b1c04dd72f7114ce3954342a99e18619d6a/camel_ai-0.2.83.tar.gz", hash = "sha256:c25eb414e9353aab166021852fb54d1d3a0c0e17485fefa996de2cccdf4c8eb9", size = 1125708, upload-time = "2026-01-19T20:37:45.197Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/34/77/f7594707571af9c86351a69ff9f7f580602b42ffe8113803153c069b6bff/camel_ai-0.2.83a9-py3-none-any.whl", hash = "sha256:7cfe97b590096c1cc5afddf6dca023c5b9a47d104196c16b4b2b1934931af260", size = 1595808, upload-time = "2026-01-15T21:28:21.068Z" }, + { url = "https://files.pythonhosted.org/packages/32/e2/4e2964059794af9161889223fa7d17630c1bcc74005c9892cd1e1627650c/camel_ai-0.2.83-py3-none-any.whl", hash = "sha256:3a183efdcccd211ae216b2a7903d48a8811ad0f4541223cacc05cb25a11279a6", size = 1599355, upload-time = "2026-01-19T20:37:41.985Z" }, ] [package.optional-dependencies] @@ -990,14 +990,14 @@ wheels = [ [[package]] name = "httplib2" -version = "0.31.0" +version = "0.31.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyparsing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/52/77/6653db69c1f7ecfe5e3f9726fdadc981794656fcd7d98c4209fecfea9993/httplib2-0.31.0.tar.gz", hash = "sha256:ac7ab497c50975147d4f7b1ade44becc7df2f8954d42b38b3d69c515f531135c", size = 250759, upload-time = "2025-09-11T12:16:03.403Z" } +sdist = { url = "https://files.pythonhosted.org/packages/77/df/6eb1d485a513776bbdbb1c919b72e59b5acc51c5e7ef28ad1cd444e252a3/httplib2-0.31.1.tar.gz", hash = "sha256:21591655ac54953624c6ab8d587c71675e379e31e2cfe3147c83c11e9ef41f92", size = 250746, upload-time = "2026-01-13T12:14:14.365Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/a2/0d269db0f6163be503775dc8b6a6fa15820cc9fdc866f6ba608d86b721f2/httplib2-0.31.0-py3-none-any.whl", hash = "sha256:b9cd78abea9b4e43a7714c6e0f8b6b8561a6fc1e95d5dbd367f5bf0ef35f5d24", size = 91148, upload-time = "2025-09-11T12:16:01.803Z" }, + { url = "https://files.pythonhosted.org/packages/f0/d8/1b05076441c2f01e4b64f59e5255edc2f0384a711b6d618845c023dc269b/httplib2-0.31.1-py3-none-any.whl", hash = "sha256:d520d22fa7e50c746a7ed856bac298c4300105d01bc2d8c2580a9b57fb9ed617", size = 91101, upload-time = "2026-01-13T12:14:12.676Z" }, ] [[package]] @@ -1046,7 +1046,7 @@ wheels = [ [[package]] name = "huggingface-hub" -version = "1.3.1" +version = "1.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -1060,9 +1060,9 @@ dependencies = [ { name = "typer-slim" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/dd/dd/1cc985c5dda36298b152f75e82a1c81f52243b78fb7e9cad637a29561ad1/huggingface_hub-1.3.1.tar.gz", hash = "sha256:e80e0cfb4a75557c51ab20d575bdea6bb6106c2f97b7c75d8490642f1efb6df5", size = 622356, upload-time = "2026-01-09T14:08:16.888Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/d6/02d1c505e1d3364230e5fa16d2b58c8f36a39c5efe8e99bc4d03d06fd0ca/huggingface_hub-1.3.2.tar.gz", hash = "sha256:15d7902e154f04174a0816d1e9594adcf15cdad57596920a5dc70fadb5d896c7", size = 624018, upload-time = "2026-01-14T13:57:39.635Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/fb/cb8fe5f71d5622427f20bcab9e06a696a5aaf21bfe7bd0a8a0c63c88abf5/huggingface_hub-1.3.1-py3-none-any.whl", hash = "sha256:efbc7f3153cb84e2bb69b62ed90985e21ecc9343d15647a419fc0ee4b85f0ac3", size = 533351, upload-time = "2026-01-09T14:08:14.519Z" }, + { url = "https://files.pythonhosted.org/packages/88/1d/acd3ef8aabb7813c6ef2f91785d855583ac5cd7c3599e5c1a1a2ed1ec2e5/huggingface_hub-1.3.2-py3-none-any.whl", hash = "sha256:b552b9562a5532102a041fa31a6966bb9de95138fc7aa578bb3703198c25d1b6", size = 534504, upload-time = "2026-01-14T13:57:37.555Z" }, ] [[package]] @@ -1456,30 +1456,30 @@ wheels = [ [[package]] name = "nodejs-wheel" -version = "24.12.0" +version = "24.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodejs-wheel-binaries" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/30/73/0e8cd7c336f64d3b72c608bc7a7a5074cf6a9721c5d3630b8803f3176a3d/nodejs_wheel-24.12.0.tar.gz", hash = "sha256:edfaa3482bd21a2da03a9e7ebda7d4d738cdc864a2d9ddfe87760994a9644232", size = 2968, upload-time = "2025-12-11T21:12:26.103Z" } +sdist = { url = "https://files.pythonhosted.org/packages/37/f0/3345c6ec958c96eaa9d59355e59c0e93359aec54634f38bc4cd06baf23aa/nodejs_wheel-24.13.0.tar.gz", hash = "sha256:8c423cbf434b4c853ebac076d563b0899d3c6594ef0f99f6cd368ca4e3a28ca2", size = 2965, upload-time = "2026-01-14T11:05:32.811Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/5f/72f857250e54c9dacdfbf35f9d77eefdf954de0679f905e2fd03d8faf980/nodejs_wheel-24.12.0-py3-none-any.whl", hash = "sha256:0234fa0c46902d7efb858d41f5d055948cafa6a824812e9e8eeb64662d8963b6", size = 3988, upload-time = "2025-12-11T21:11:56.287Z" }, + { url = "https://files.pythonhosted.org/packages/c3/29/f259f6c5d31a0dae8257afd8dd7ab4b60a1b6e03fab793789e5bad480d83/nodejs_wheel-24.13.0-py3-none-any.whl", hash = "sha256:c0fc56a4677f55f7639f306a6381fb253d11ce24189c87a5489ea848f6e2bf24", size = 3986, upload-time = "2026-01-14T11:05:02.807Z" }, ] [[package]] name = "nodejs-wheel-binaries" -version = "24.12.0" +version = "24.13.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b9/35/d806c2ca66072e36dc340ccdbeb2af7e4f1b5bcc33f1481f00ceed476708/nodejs_wheel_binaries-24.12.0.tar.gz", hash = "sha256:f1b50aa25375e264697dec04b232474906b997c2630c8f499f4caf3692938435", size = 8058, upload-time = "2025-12-11T21:12:26.856Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/f1/73182280e2c05f49a7c2c8dbd46144efe3f74f03f798fb90da67b4a93bbf/nodejs_wheel_binaries-24.13.0.tar.gz", hash = "sha256:766aed076e900061b83d3e76ad48bfec32a035ef0d41bd09c55e832eb93ef7a4", size = 8056, upload-time = "2026-01-14T11:05:33.653Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/3b/9d6f044319cd5b1e98f07c41e2465b58cadc1c9c04a74c891578f3be6cb5/nodejs_wheel_binaries-24.12.0-py2.py3-none-macosx_13_0_arm64.whl", hash = "sha256:7564ddea0a87eff34e9b3ef71764cc2a476a8f09a5cccfddc4691148b0a47338", size = 55125859, upload-time = "2025-12-11T21:11:58.132Z" }, - { url = "https://files.pythonhosted.org/packages/48/a5/f5722bf15c014e2f476d7c76bce3d55c341d19122d8a5d86454db32a61a4/nodejs_wheel_binaries-24.12.0-py2.py3-none-macosx_13_0_x86_64.whl", hash = "sha256:8ff929c4669e64613ceb07f5bbd758d528c3563820c75d5de3249eb452c0c0ab", size = 55309035, upload-time = "2025-12-11T21:12:01.754Z" }, - { url = "https://files.pythonhosted.org/packages/a9/61/68d39a6f1b5df67805969fd2829ba7e80696c9af19537856ec912050a2be/nodejs_wheel_binaries-24.12.0-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:6ebacefa8891bc456ad3655e6bce0af7e20ba08662f79d9109986faeb703fd6f", size = 59661017, upload-time = "2025-12-11T21:12:05.268Z" }, - { url = "https://files.pythonhosted.org/packages/16/a1/31aad16f55a5e44ca7ea62d1367fc69f4b6e1dba67f58a0a41d0ed854540/nodejs_wheel_binaries-24.12.0-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:3292649a03682ccbfa47f7b04d3e4240e8c46ef04dc941b708f20e4e6a764f75", size = 60159770, upload-time = "2025-12-11T21:12:08.696Z" }, - { url = "https://files.pythonhosted.org/packages/c4/5e/b7c569aa1862690ca4d4daf3a64cafa1ea6ce667a9e3ae3918c56e127d9b/nodejs_wheel_binaries-24.12.0-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7fb83df312955ea355ba7f8cbd7055c477249a131d3cb43b60e4aeb8f8c730b1", size = 61653561, upload-time = "2025-12-11T21:12:12.575Z" }, - { url = "https://files.pythonhosted.org/packages/71/87/567f58d7ba69ff0208be849b37be0f2c2e99c69e49334edd45ff44f00043/nodejs_wheel_binaries-24.12.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:2473c819448fedd7b036dde236b09f3c8bbf39fbbd0c1068790a0498800f498b", size = 62238331, upload-time = "2025-12-11T21:12:16.143Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9d/c6492188ce8de90093c6755a4a63bb6b2b4efb17094cb4f9a9a49c73ed3b/nodejs_wheel_binaries-24.12.0-py2.py3-none-win_amd64.whl", hash = "sha256:2090d59f75a68079fabc9b86b14df8238b9aecb9577966dc142ce2a23a32e9bb", size = 41342076, upload-time = "2025-12-11T21:12:20.618Z" }, - { url = "https://files.pythonhosted.org/packages/df/af/cd3290a647df567645353feed451ef4feaf5844496ced69c4dcb84295ff4/nodejs_wheel_binaries-24.12.0-py2.py3-none-win_arm64.whl", hash = "sha256:d0c2273b667dd7e3f55e369c0085957b702144b1b04bfceb7ce2411e58333757", size = 39048104, upload-time = "2025-12-11T21:12:23.495Z" }, + { url = "https://files.pythonhosted.org/packages/c4/dc/4d7548aa74a5b446d093f03aff4fb236b570959d793f21c9c42ab6ad870a/nodejs_wheel_binaries-24.13.0-py2.py3-none-macosx_13_0_arm64.whl", hash = "sha256:356654baa37bfd894e447e7e00268db403ea1d223863963459a0fbcaaa1d9d48", size = 55133268, upload-time = "2026-01-14T11:05:05.335Z" }, + { url = "https://files.pythonhosted.org/packages/24/8a/8a4454d28339487240dd2232f42f1090e4a58544c581792d427f6239798c/nodejs_wheel_binaries-24.13.0-py2.py3-none-macosx_13_0_x86_64.whl", hash = "sha256:92fdef7376120e575f8b397789bafcb13bbd22a1b4d21b060d200b14910f22a5", size = 55314800, upload-time = "2026-01-14T11:05:09.121Z" }, + { url = "https://files.pythonhosted.org/packages/e7/fb/46c600fcc748bd13bc536a735f11532a003b14f5c4dfd6865f5911672175/nodejs_wheel_binaries-24.13.0-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3f619ac140e039ecd25f2f71d6e83ad1414017a24608531851b7c31dc140cdfd", size = 59666320, upload-time = "2026-01-14T11:05:12.369Z" }, + { url = "https://files.pythonhosted.org/packages/85/47/d48f11fc5d1541ace5d806c62a45738a1db9ce33e85a06fe4cd3d9ce83f6/nodejs_wheel_binaries-24.13.0-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:dfb31ebc2c129538192ddb5bedd3d63d6de5d271437cd39ea26bf3fe229ba430", size = 60162447, upload-time = "2026-01-14T11:05:16.003Z" }, + { url = "https://files.pythonhosted.org/packages/b1/74/d285c579ae8157c925b577dde429543963b845e69cd006549e062d1cf5b6/nodejs_wheel_binaries-24.13.0-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fdd720d7b378d5bb9b2710457bbc880d4c4d1270a94f13fbe257198ac707f358", size = 61659994, upload-time = "2026-01-14T11:05:19.68Z" }, + { url = "https://files.pythonhosted.org/packages/ba/97/88b4254a2ff93ed2eaed725f77b7d3d2d8d7973bf134359ce786db894faf/nodejs_wheel_binaries-24.13.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9ad6383613f3485a75b054647a09f1cd56d12380d7459184eebcf4a5d403f35c", size = 62244373, upload-time = "2026-01-14T11:05:23.987Z" }, + { url = "https://files.pythonhosted.org/packages/4e/c3/0e13a3da78f08cb58650971a6957ac7bfef84164b405176e53ab1e3584e2/nodejs_wheel_binaries-24.13.0-py2.py3-none-win_amd64.whl", hash = "sha256:605be4763e3ef427a3385a55da5a1bcf0a659aa2716eebbf23f332926d7e5f23", size = 41345528, upload-time = "2026-01-14T11:05:27.67Z" }, + { url = "https://files.pythonhosted.org/packages/a3/f1/0578d65b4e3dc572967fd702221ea1f42e1e60accfb6b0dd8d8f15410139/nodejs_wheel_binaries-24.13.0-py2.py3-none-win_arm64.whl", hash = "sha256:2e3431d869d6b2dbeef1d469ad0090babbdcc8baaa72c01dd3cc2c6121c96af5", size = 39054688, upload-time = "2026-01-14T11:05:30.739Z" }, ] [[package]] @@ -1933,26 +1933,26 @@ wheels = [ [[package]] name = "pyarrow" -version = "22.0.0" +version = "23.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload-time = "2025-10-24T12:30:00.762Z" } +sdist = { url = "https://files.pythonhosted.org/packages/01/33/ffd9c3eb087fa41dd79c3cf20c4c0ae3cdb877c4f8e1107a446006344924/pyarrow-23.0.0.tar.gz", hash = "sha256:180e3150e7edfcd182d3d9afba72f7cf19839a497cc76555a8dce998a8f67615", size = 1167185, upload-time = "2026-01-18T16:19:42.218Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/9b/cb3f7e0a345353def531ca879053e9ef6b9f38ed91aebcf68b09ba54dec0/pyarrow-22.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:77718810bd3066158db1e95a63c160ad7ce08c6b0710bc656055033e39cdad88", size = 34223968, upload-time = "2025-10-24T10:03:31.21Z" }, - { url = "https://files.pythonhosted.org/packages/6c/41/3184b8192a120306270c5307f105b70320fdaa592c99843c5ef78aaefdcf/pyarrow-22.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:44d2d26cda26d18f7af7db71453b7b783788322d756e81730acb98f24eb90ace", size = 35942085, upload-time = "2025-10-24T10:03:38.146Z" }, - { url = "https://files.pythonhosted.org/packages/d9/3d/a1eab2f6f08001f9fb714b8ed5cfb045e2fe3e3e3c0c221f2c9ed1e6d67d/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:b9d71701ce97c95480fecb0039ec5bb889e75f110da72005743451339262f4ce", size = 44964613, upload-time = "2025-10-24T10:03:46.516Z" }, - { url = "https://files.pythonhosted.org/packages/46/46/a1d9c24baf21cfd9ce994ac820a24608decf2710521b29223d4334985127/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:710624ab925dc2b05a6229d47f6f0dac1c1155e6ed559be7109f684eba048a48", size = 47627059, upload-time = "2025-10-24T10:03:55.353Z" }, - { url = "https://files.pythonhosted.org/packages/3a/4c/f711acb13075c1391fd54bc17e078587672c575f8de2a6e62509af026dcf/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f963ba8c3b0199f9d6b794c90ec77545e05eadc83973897a4523c9e8d84e9340", size = 47947043, upload-time = "2025-10-24T10:04:05.408Z" }, - { url = "https://files.pythonhosted.org/packages/4e/70/1f3180dd7c2eab35c2aca2b29ace6c519f827dcd4cfeb8e0dca41612cf7a/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd0d42297ace400d8febe55f13fdf46e86754842b860c978dfec16f081e5c653", size = 50206505, upload-time = "2025-10-24T10:04:15.786Z" }, - { url = "https://files.pythonhosted.org/packages/80/07/fea6578112c8c60ffde55883a571e4c4c6bc7049f119d6b09333b5cc6f73/pyarrow-22.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:00626d9dc0f5ef3a75fe63fd68b9c7c8302d2b5bbc7f74ecaedba83447a24f84", size = 28101641, upload-time = "2025-10-24T10:04:22.57Z" }, + { url = "https://files.pythonhosted.org/packages/ae/2f/23e042a5aa99bcb15e794e14030e8d065e00827e846e53a66faec73c7cd6/pyarrow-23.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:cbdc2bf5947aa4d462adcf8453cf04aee2f7932653cb67a27acd96e5e8528a67", size = 34281861, upload-time = "2026-01-18T16:13:34.332Z" }, + { url = "https://files.pythonhosted.org/packages/8b/65/1651933f504b335ec9cd8f99463718421eb08d883ed84f0abd2835a16cad/pyarrow-23.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:4d38c836930ce15cd31dce20114b21ba082da231c884bdc0a7b53e1477fe7f07", size = 35825067, upload-time = "2026-01-18T16:13:42.549Z" }, + { url = "https://files.pythonhosted.org/packages/84/ec/d6fceaec050c893f4e35c0556b77d4cc9973fcc24b0a358a5781b1234582/pyarrow-23.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:4222ff8f76919ecf6c716175a0e5fddb5599faeed4c56d9ea41a2c42be4998b2", size = 44458539, upload-time = "2026-01-18T16:13:52.975Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d9/369f134d652b21db62fe3ec1c5c2357e695f79eb67394b8a93f3a2b2cffa/pyarrow-23.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:87f06159cbe38125852657716889296c83c37b4d09a5e58f3d10245fd1f69795", size = 47535889, upload-time = "2026-01-18T16:14:03.693Z" }, + { url = "https://files.pythonhosted.org/packages/a3/95/f37b6a252fdbf247a67a78fb3f61a529fe0600e304c4d07741763d3522b1/pyarrow-23.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1675c374570d8b91ea6d4edd4608fa55951acd44e0c31bd146e091b4005de24f", size = 48157777, upload-time = "2026-01-18T16:14:12.483Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ab/fb94923108c9c6415dab677cf1f066d3307798eafc03f9a65ab4abc61056/pyarrow-23.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:247374428fde4f668f138b04031a7e7077ba5fa0b5b1722fdf89a017bf0b7ee0", size = 50580441, upload-time = "2026-01-18T16:14:20.187Z" }, + { url = "https://files.pythonhosted.org/packages/ae/78/897ba6337b517fc8e914891e1bd918da1c4eb8e936a553e95862e67b80f6/pyarrow-23.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:de53b1bd3b88a2ee93c9af412c903e57e738c083be4f6392288294513cd8b2c1", size = 27530028, upload-time = "2026-01-18T16:14:27.353Z" }, ] [[package]] name = "pyasn1" -version = "0.6.1" +version = "0.6.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/b6/6e630dff89739fcd427e3f72b3d905ce0acb85a45d4ec3e2678718a3487f/pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b", size = 146586, upload-time = "2026-01-16T18:04:18.534Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" }, + { url = "https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf", size = 83371, upload-time = "2026-01-16T18:04:17.174Z" }, ] [[package]] @@ -2051,14 +2051,14 @@ wheels = [ [[package]] name = "pydash" -version = "8.0.5" +version = "8.0.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/24/91c037f47e434172c2112d65c00c84d475a6715425e3315ba2cbb7a87e66/pydash-8.0.5.tar.gz", hash = "sha256:7cc44ebfe5d362f4f5f06c74c8684143c5ac481376b059ff02570705523f9e2e", size = 164861, upload-time = "2025-01-17T16:08:50.562Z" } +sdist = { url = "https://files.pythonhosted.org/packages/75/c1/1c55272f49d761cec38ddb80be9817935b9c91ebd6a8988e10f532868d56/pydash-8.0.6.tar.gz", hash = "sha256:b2821547e9723f69cf3a986be4db64de41730be149b2641947ecd12e1e11025a", size = 164338, upload-time = "2026-01-17T16:42:56.576Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/86/e74c978800131c657fc5145f2c1c63e0cea01a49b6216f729cf77a2e1edf/pydash-8.0.5-py3-none-any.whl", hash = "sha256:b2625f8981862e19911daa07f80ed47b315ce20d9b5eb57aaf97aaf570c3892f", size = 102077, upload-time = "2025-01-17T16:08:47.91Z" }, + { url = "https://files.pythonhosted.org/packages/a5/b7/cc5e7974699db40014d58c7dd7c4ad4ffc244d36930dc9ec7d06ee67d7a9/pydash-8.0.6-py3-none-any.whl", hash = "sha256:ee70a81a5b292c007f28f03a4ee8e75c1f5d7576df5457b836ec7ab2839cc5d0", size = 101561, upload-time = "2026-01-17T16:42:55.448Z" }, ] [[package]] @@ -2277,38 +2277,40 @@ wheels = [ [[package]] name = "regex" -version = "2025.11.3" +version = "2026.1.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/a9/546676f25e573a4cf00fe8e119b78a37b6a8fe2dc95cda877b30889c9c45/regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01", size = 414669, upload-time = "2025-11-03T21:34:22.089Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/86/07d5056945f9ec4590b518171c4254a5925832eb727b56d3c38a7476f316/regex-2026.1.15.tar.gz", hash = "sha256:164759aa25575cbc0651bef59a0b18353e54300d79ace8084c818ad8ac72b7d5", size = 414811, upload-time = "2026-01-14T23:18:02.775Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/d6/d788d52da01280a30a3f6268aef2aa71043bff359c618fea4c5b536654d5/regex-2025.11.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2b441a4ae2c8049106e8b39973bfbddfb25a179dda2bdb99b0eeb60c40a6a3af", size = 488087, upload-time = "2025-11-03T21:30:47.317Z" }, - { url = "https://files.pythonhosted.org/packages/69/39/abec3bd688ec9bbea3562de0fd764ff802976185f5ff22807bf0a2697992/regex-2025.11.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2fa2eed3f76677777345d2f81ee89f5de2f5745910e805f7af7386a920fa7313", size = 290544, upload-time = "2025-11-03T21:30:49.912Z" }, - { url = "https://files.pythonhosted.org/packages/39/b3/9a231475d5653e60002508f41205c61684bb2ffbf2401351ae2186897fc4/regex-2025.11.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d8b4a27eebd684319bdf473d39f1d79eed36bf2cd34bd4465cdb4618d82b3d56", size = 288408, upload-time = "2025-11-03T21:30:51.344Z" }, - { url = "https://files.pythonhosted.org/packages/c3/c5/1929a0491bd5ac2d1539a866768b88965fa8c405f3e16a8cef84313098d6/regex-2025.11.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cf77eac15bd264986c4a2c63353212c095b40f3affb2bc6b4ef80c4776c1a28", size = 781584, upload-time = "2025-11-03T21:30:52.596Z" }, - { url = "https://files.pythonhosted.org/packages/ce/fd/16aa16cf5d497ef727ec966f74164fbe75d6516d3d58ac9aa989bc9cdaad/regex-2025.11.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b7f9ee819f94c6abfa56ec7b1dbab586f41ebbdc0a57e6524bd5e7f487a878c7", size = 850733, upload-time = "2025-11-03T21:30:53.825Z" }, - { url = "https://files.pythonhosted.org/packages/e6/49/3294b988855a221cb6565189edf5dc43239957427df2d81d4a6b15244f64/regex-2025.11.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:838441333bc90b829406d4a03cb4b8bf7656231b84358628b0406d803931ef32", size = 898691, upload-time = "2025-11-03T21:30:55.575Z" }, - { url = "https://files.pythonhosted.org/packages/14/62/b56d29e70b03666193369bdbdedfdc23946dbe9f81dd78ce262c74d988ab/regex-2025.11.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cfe6d3f0c9e3b7e8c0c694b24d25e677776f5ca26dce46fd6b0489f9c8339391", size = 791662, upload-time = "2025-11-03T21:30:57.262Z" }, - { url = "https://files.pythonhosted.org/packages/15/fc/e4c31d061eced63fbf1ce9d853975f912c61a7d406ea14eda2dd355f48e7/regex-2025.11.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2ab815eb8a96379a27c3b6157fcb127c8f59c36f043c1678110cea492868f1d5", size = 782587, upload-time = "2025-11-03T21:30:58.788Z" }, - { url = "https://files.pythonhosted.org/packages/b2/bb/5e30c7394bcf63f0537121c23e796be67b55a8847c3956ae6068f4c70702/regex-2025.11.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:728a9d2d173a65b62bdc380b7932dd8e74ed4295279a8fe1021204ce210803e7", size = 774709, upload-time = "2025-11-03T21:31:00.081Z" }, - { url = "https://files.pythonhosted.org/packages/c5/c4/fce773710af81b0cb37cb4ff0947e75d5d17dee304b93d940b87a67fc2f4/regex-2025.11.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:509dc827f89c15c66a0c216331260d777dd6c81e9a4e4f830e662b0bb296c313", size = 845773, upload-time = "2025-11-03T21:31:01.583Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5e/9466a7ec4b8ec282077095c6eb50a12a389d2e036581134d4919e8ca518c/regex-2025.11.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:849202cd789e5f3cf5dcc7822c34b502181b4824a65ff20ce82da5524e45e8e9", size = 836164, upload-time = "2025-11-03T21:31:03.244Z" }, - { url = "https://files.pythonhosted.org/packages/95/18/82980a60e8ed1594eb3c89eb814fb276ef51b9af7caeab1340bfd8564af6/regex-2025.11.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b6f78f98741dcc89607c16b1e9426ee46ce4bf31ac5e6b0d40e81c89f3481ea5", size = 779832, upload-time = "2025-11-03T21:31:04.876Z" }, - { url = "https://files.pythonhosted.org/packages/03/cc/90ab0fdbe6dce064a42015433f9152710139fb04a8b81b4fb57a1cb63ffa/regex-2025.11.3-cp310-cp310-win32.whl", hash = "sha256:149eb0bba95231fb4f6d37c8f760ec9fa6fabf65bab555e128dde5f2475193ec", size = 265802, upload-time = "2025-11-03T21:31:06.581Z" }, - { url = "https://files.pythonhosted.org/packages/34/9d/e9e8493a85f3b1ddc4a5014465f5c2b78c3ea1cbf238dcfde78956378041/regex-2025.11.3-cp310-cp310-win_amd64.whl", hash = "sha256:ee3a83ce492074c35a74cc76cf8235d49e77b757193a5365ff86e3f2f93db9fd", size = 277722, upload-time = "2025-11-03T21:31:08.144Z" }, - { url = "https://files.pythonhosted.org/packages/15/c4/b54b24f553966564506dbf873a3e080aef47b356a3b39b5d5aba992b50db/regex-2025.11.3-cp310-cp310-win_arm64.whl", hash = "sha256:38af559ad934a7b35147716655d4a2f79fcef2d695ddfe06a06ba40ae631fa7e", size = 270289, upload-time = "2025-11-03T21:31:10.267Z" }, + { url = "https://files.pythonhosted.org/packages/ea/d2/e6ee96b7dff201a83f650241c52db8e5bd080967cb93211f57aa448dc9d6/regex-2026.1.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4e3dd93c8f9abe8aa4b6c652016da9a3afa190df5ad822907efe6b206c09896e", size = 488166, upload-time = "2026-01-14T23:13:46.408Z" }, + { url = "https://files.pythonhosted.org/packages/23/8a/819e9ce14c9f87af026d0690901b3931f3101160833e5d4c8061fa3a1b67/regex-2026.1.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97499ff7862e868b1977107873dd1a06e151467129159a6ffd07b66706ba3a9f", size = 290632, upload-time = "2026-01-14T23:13:48.688Z" }, + { url = "https://files.pythonhosted.org/packages/d5/c3/23dfe15af25d1d45b07dfd4caa6003ad710dcdcb4c4b279909bdfe7a2de8/regex-2026.1.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0bda75ebcac38d884240914c6c43d8ab5fb82e74cde6da94b43b17c411aa4c2b", size = 288500, upload-time = "2026-01-14T23:13:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/c6/31/1adc33e2f717df30d2f4d973f8776d2ba6ecf939301efab29fca57505c95/regex-2026.1.15-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7dcc02368585334f5bc81fc73a2a6a0bbade60e7d83da21cead622faf408f32c", size = 781670, upload-time = "2026-01-14T23:13:52.453Z" }, + { url = "https://files.pythonhosted.org/packages/23/ce/21a8a22d13bc4adcb927c27b840c948f15fc973e21ed2346c1bd0eae22dc/regex-2026.1.15-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:693b465171707bbe882a7a05de5e866f33c76aa449750bee94a8d90463533cc9", size = 850820, upload-time = "2026-01-14T23:13:54.894Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/3eeacdf587a4705a44484cd0b30e9230a0e602811fb3e2cc32268c70d509/regex-2026.1.15-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b0d190e6f013ea938623a58706d1469a62103fb2a241ce2873a9906e0386582c", size = 898777, upload-time = "2026-01-14T23:13:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/79/a9/1898a077e2965c35fc22796488141a22676eed2d73701e37c73ad7c0b459/regex-2026.1.15-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ff818702440a5878a81886f127b80127f5d50563753a28211482867f8318106", size = 791750, upload-time = "2026-01-14T23:13:58.527Z" }, + { url = "https://files.pythonhosted.org/packages/4c/84/e31f9d149a178889b3817212827f5e0e8c827a049ff31b4b381e76b26e2d/regex-2026.1.15-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f052d1be37ef35a54e394de66136e30fa1191fab64f71fc06ac7bc98c9a84618", size = 782674, upload-time = "2026-01-14T23:13:59.874Z" }, + { url = "https://files.pythonhosted.org/packages/d2/ff/adf60063db24532add6a1676943754a5654dcac8237af024ede38244fd12/regex-2026.1.15-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6bfc31a37fd1592f0c4fc4bfc674b5c42e52efe45b4b7a6a14f334cca4bcebe4", size = 767906, upload-time = "2026-01-14T23:14:01.298Z" }, + { url = "https://files.pythonhosted.org/packages/af/3e/e6a216cee1e2780fec11afe7fc47b6f3925d7264e8149c607ac389fd9b1a/regex-2026.1.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3d6ce5ae80066b319ae3bc62fd55a557c9491baa5efd0d355f0de08c4ba54e79", size = 774798, upload-time = "2026-01-14T23:14:02.715Z" }, + { url = "https://files.pythonhosted.org/packages/0f/98/23a4a8378a9208514ed3efc7e7850c27fa01e00ed8557c958df0335edc4a/regex-2026.1.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1704d204bd42b6bb80167df0e4554f35c255b579ba99616def38f69e14a5ccb9", size = 845861, upload-time = "2026-01-14T23:14:04.824Z" }, + { url = "https://files.pythonhosted.org/packages/f8/57/d7605a9d53bd07421a8785d349cd29677fe660e13674fa4c6cbd624ae354/regex-2026.1.15-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:e3174a5ed4171570dc8318afada56373aa9289eb6dc0d96cceb48e7358b0e220", size = 755648, upload-time = "2026-01-14T23:14:06.371Z" }, + { url = "https://files.pythonhosted.org/packages/6f/76/6f2e24aa192da1e299cc1101674a60579d3912391867ce0b946ba83e2194/regex-2026.1.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:87adf5bd6d72e3e17c9cb59ac4096b1faaf84b7eb3037a5ffa61c4b4370f0f13", size = 836250, upload-time = "2026-01-14T23:14:08.343Z" }, + { url = "https://files.pythonhosted.org/packages/11/3a/1f2a1d29453299a7858eab7759045fc3d9d1b429b088dec2dc85b6fa16a2/regex-2026.1.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e85dc94595f4d766bd7d872a9de5ede1ca8d3063f3bdf1e2c725f5eb411159e3", size = 779919, upload-time = "2026-01-14T23:14:09.954Z" }, + { url = "https://files.pythonhosted.org/packages/c0/67/eab9bc955c9dcc58e9b222c801e39cff7ca0b04261792a2149166ce7e792/regex-2026.1.15-cp310-cp310-win32.whl", hash = "sha256:21ca32c28c30d5d65fc9886ff576fc9b59bbca08933e844fa2363e530f4c8218", size = 265888, upload-time = "2026-01-14T23:14:11.35Z" }, + { url = "https://files.pythonhosted.org/packages/1d/62/31d16ae24e1f8803bddb0885508acecaec997fcdcde9c243787103119ae4/regex-2026.1.15-cp310-cp310-win_amd64.whl", hash = "sha256:3038a62fc7d6e5547b8915a3d927a0fbeef84cdbe0b1deb8c99bbd4a8961b52a", size = 277830, upload-time = "2026-01-14T23:14:12.908Z" }, + { url = "https://files.pythonhosted.org/packages/e5/36/5d9972bccd6417ecd5a8be319cebfd80b296875e7f116c37fb2a2deecebf/regex-2026.1.15-cp310-cp310-win_arm64.whl", hash = "sha256:505831646c945e3e63552cc1b1b9b514f0e93232972a2d5bedbcc32f15bc82e3", size = 270376, upload-time = "2026-01-14T23:14:14.782Z" }, ] [[package]] name = "reportlab" -version = "4.4.7" +version = "4.4.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "charset-normalizer" }, { name = "pillow" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/a7/4600cb1cfc975a06552e8927844ddcb8fd90217e9a6068f5c7aa76c3f221/reportlab-4.4.7.tar.gz", hash = "sha256:41e8287af965e5996764933f3e75e7f363c3b6f252ba172f9429e81658d7b170", size = 3714000, upload-time = "2025-12-21T11:50:11.336Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/39/42cf24aee570a80e1903221ae3a92a2e34c324794a392eb036cbb6dc3839/reportlab-4.4.9.tar.gz", hash = "sha256:7cf487764294ee791a4781f5a157bebce262a666ae4bbb87786760a9676c9378", size = 3911246, upload-time = "2026-01-15T10:07:56.08Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/bf/a29507386366ab17306b187ad247dd78e4599be9032cb5f44c940f547fc0/reportlab-4.4.7-py3-none-any.whl", hash = "sha256:8fa05cbf468e0e76745caf2029a4770276edb3c8e86a0b71e0398926baf50673", size = 1954263, upload-time = "2025-12-21T11:50:08.93Z" }, + { url = "https://files.pythonhosted.org/packages/17/77/546e50edfaba6a0e58e8ec5fdc4446510227cec9e8f40172b60941d5a633/reportlab-4.4.9-py3-none-any.whl", hash = "sha256:68e2d103ae8041a37714e8896ec9b79a1c1e911d68c3bd2ea17546568cf17bfd", size = 1954401, upload-time = "2026-01-15T09:27:59.133Z" }, ] [[package]] @@ -2453,11 +2455,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.8.1" +version = "2.8.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/89/23/adf3796d740536d63a6fbda113d07e60c734b6ed5d3058d1e47fc0495e47/soupsieve-2.8.1.tar.gz", hash = "sha256:4cf733bc50fa805f5df4b8ef4740fc0e0fa6218cf3006269afd3f9d6d80fd350", size = 117856, upload-time = "2025-12-18T13:50:34.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/93/f2/21d6ca70c3cf35d01ae9e01be534bf6b6b103c157a728082a5028350c310/soupsieve-2.8.2.tar.gz", hash = "sha256:78a66b0fdee2ab40b7199dc3e747ee6c6e231899feeaae0b9b98a353afd48fd8", size = 118601, upload-time = "2026-01-18T16:21:31.09Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/f3/b67d6ea49ca9154453b6d70b34ea22f3996b9fa55da105a79d8732227adc/soupsieve-2.8.1-py3-none-any.whl", hash = "sha256:a11fe2a6f3d76ab3cf2de04eb339c1be5b506a8a47f2ceb6d139803177f85434", size = 36710, upload-time = "2025-12-18T13:50:33.267Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9a/b4450ccce353e2430621b3bb571899ffe1033d5cd72c9e065110f95b1a63/soupsieve-2.8.2-py3-none-any.whl", hash = "sha256:0f4c2f6b5a5fb97a641cf69c0bd163670a0e45e6d6c01a2107f93a6a6f93c51a", size = 37016, upload-time = "2026-01-18T16:21:29.7Z" }, ] [[package]] @@ -2474,15 +2476,15 @@ wheels = [ [[package]] name = "sse-starlette" -version = "3.1.2" +version = "3.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "starlette" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/34/f5df66cb383efdbf4f2db23cabb27f51b1dcb737efaf8a558f6f1d195134/sse_starlette-3.1.2.tar.gz", hash = "sha256:55eff034207a83a0eb86de9a68099bd0157838f0b8b999a1b742005c71e33618", size = 26303, upload-time = "2025-12-31T08:02:20.023Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/8d/00d280c03ffd39aaee0e86ec81e2d3b9253036a0f93f51d10503adef0e65/sse_starlette-3.2.0.tar.gz", hash = "sha256:8127594edfb51abe44eac9c49e59b0b01f1039d0c7461c6fd91d4e03b70da422", size = 27253, upload-time = "2026-01-17T13:11:05.62Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/95/8c4b76eec9ae574474e5d2997557cebf764bcd3586458956c30631ae08f4/sse_starlette-3.1.2-py3-none-any.whl", hash = "sha256:cd800dd349f4521b317b9391d3796fa97b71748a4da9b9e00aafab32dda375c8", size = 12484, upload-time = "2025-12-31T08:02:18.894Z" }, + { url = "https://files.pythonhosted.org/packages/96/7f/832f015020844a8b8f7a9cbc103dd76ba8e3875004c41e08440ea3a2b41a/sse_starlette-3.2.0-py3-none-any.whl", hash = "sha256:5876954bd51920fc2cd51baee47a080eb88a37b5b784e615abb0b283f801cdbf", size = 12763, upload-time = "2026-01-17T13:11:03.775Z" }, ] [[package]] @@ -2540,11 +2542,11 @@ wheels = [ [[package]] name = "tomli" -version = "2.3.0" +version = "2.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, ] [[package]] diff --git a/server/pyproject.toml b/server/pyproject.toml index fb23ec22..b3a0e592 100644 --- a/server/pyproject.toml +++ b/server/pyproject.toml @@ -7,7 +7,7 @@ requires-python = ">=3.12,<3.13" dependencies = [ "alembic>=1.15.2", "openai>=1.99.3,<2", - "camel-ai==0.2.83a9", + "camel-ai==0.2.83", "pydantic[email]>=2.11.1", "click>=8.1.8", "fastapi>=0.115.12", diff --git a/server/uv.lock b/server/uv.lock index 1bcd3d49..5cefc7f7 100644 --- a/server/uv.lock +++ b/server/uv.lock @@ -4,16 +4,16 @@ requires-python = "==3.12.*" [[package]] name = "alembic" -version = "1.17.2" +version = "1.18.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mako" }, { name = "sqlalchemy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/02/a6/74c8cadc2882977d80ad756a13857857dbcf9bd405bc80b662eb10651282/alembic-1.17.2.tar.gz", hash = "sha256:bbe9751705c5e0f14877f02d46c53d10885e377e3d90eda810a016f9baa19e8e", size = 1988064, upload-time = "2025-11-14T20:35:04.057Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/cc/aca263693b2ece99fa99a09b6d092acb89973eb2bb575faef1777e04f8b4/alembic-1.18.1.tar.gz", hash = "sha256:83ac6b81359596816fb3b893099841a0862f2117b2963258e965d70dc62fb866", size = 2044319, upload-time = "2026-01-14T18:53:14.907Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/88/6237e97e3385b57b5f1528647addea5cc03d4d65d5979ab24327d41fb00d/alembic-1.17.2-py3-none-any.whl", hash = "sha256:f483dd1fe93f6c5d49217055e4d15b905b425b6af906746abb35b69c1996c4e6", size = 248554, upload-time = "2025-11-14T20:35:05.699Z" }, + { url = "https://files.pythonhosted.org/packages/83/36/cd9cb6101e81e39076b2fbe303bfa3c85ca34e55142b0324fcbf22c5c6e2/alembic-1.18.1-py3-none-any.whl", hash = "sha256:f1c3b0920b87134e851c25f1f7f236d8a332c34b75416802d06971df5d1b7810", size = 260973, upload-time = "2026-01-14T18:53:17.533Z" }, ] [[package]] @@ -117,35 +117,35 @@ wheels = [ [[package]] name = "boto3" -version = "1.42.24" +version = "1.42.30" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ee/21/8be0e3685c3a4868be48d8d2f6e5b4641727e1d8a5d396b8b401d2b5f06e/boto3-1.42.24.tar.gz", hash = "sha256:c47a2f40df933e3861fc66fd8d6b87ee36d4361663a7e7ba39a87f5a78b2eae1", size = 112788, upload-time = "2026-01-07T20:30:51.019Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/79/2dac8b7cb075cfa43908ee9af3f8ee06880d84b86013854c5cca8945afac/boto3-1.42.30.tar.gz", hash = "sha256:ba9cd2f7819637d15bfbeb63af4c567fcc8a7dcd7b93dd12734ec58601169538", size = 112809, upload-time = "2026-01-16T20:37:23.636Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/75/bbfccb268f9faa4f59030888e859dca9797a980b77d6a074113af73bd4bf/boto3-1.42.24-py3-none-any.whl", hash = "sha256:8ed6ad670a5a2d7f66c1b0d3362791b48392c7a08f78479f5d8ab319a4d9118f", size = 140572, upload-time = "2026-01-07T20:30:49.431Z" }, + { url = "https://files.pythonhosted.org/packages/52/b3/2c0d828c9f668292e277ca5232e6160dd5b4b660a3f076f20dd5378baa1e/boto3-1.42.30-py3-none-any.whl", hash = "sha256:d7e548bea65e0ae2c465c77de937bc686b591aee6a352d5a19a16bc751e591c1", size = 140573, upload-time = "2026-01-16T20:37:22.089Z" }, ] [[package]] name = "botocore" -version = "1.42.24" +version = "1.42.30" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/12/d7/bb4a4e839b238ffb67b002d7326b328ebe5eb23ed5180f2ca10399a802de/botocore-1.42.24.tar.gz", hash = "sha256:be8d1bea64fb91eea08254a1e5fea057e4428d08e61f4e11083a02cafc1f8cc6", size = 14878455, upload-time = "2026-01-07T20:30:40.379Z" } +sdist = { url = "https://files.pythonhosted.org/packages/44/38/23862628a0eb044c8b8b3d7a9ad1920b3bfd6bce6d746d5a871e8382c7e4/botocore-1.42.30.tar.gz", hash = "sha256:9bf1662b8273d5cc3828a49f71ca85abf4e021011c1f0a71f41a2ea5769a5116", size = 14891439, upload-time = "2026-01-16T20:37:13.77Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/d4/f2655d777eed8b069ecab3761454cb83f830f8be8b5b0d292e4b3a980d00/botocore-1.42.24-py3-none-any.whl", hash = "sha256:8fca9781d7c84f7ad070fceffaff7179c4aa7a5ffb27b43df9d1d957801e0a8d", size = 14551806, upload-time = "2026-01-07T20:30:38.103Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8d/6d7b016383b1f74dd93611b1c5078bbaddaca901553ab886dcda87cae365/botocore-1.42.30-py3-none-any.whl", hash = "sha256:97070a438cac92430bb7b65f8ebd7075224f4a289719da4ee293d22d1e98db02", size = 14566340, upload-time = "2026-01-16T20:37:10.94Z" }, ] [[package]] name = "camel-ai" -version = "0.2.83a9" +version = "0.2.83" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astor" }, @@ -162,9 +162,9 @@ dependencies = [ { name = "tiktoken" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/8c/7d8071776ba973bb6e734edb6caaf4fdbdf60ecebdc1c4017948cc67ad48/camel_ai-0.2.83a9.tar.gz", hash = "sha256:2ee560551797b089f9849d3b9d63cd3a2b4eb45d339d17e6bf95eba2b85c4b50", size = 1124774, upload-time = "2026-01-15T21:28:24.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/d1/36f0982862ba2b992968ace43b1c04dd72f7114ce3954342a99e18619d6a/camel_ai-0.2.83.tar.gz", hash = "sha256:c25eb414e9353aab166021852fb54d1d3a0c0e17485fefa996de2cccdf4c8eb9", size = 1125708, upload-time = "2026-01-19T20:37:45.197Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/34/77/f7594707571af9c86351a69ff9f7f580602b42ffe8113803153c069b6bff/camel_ai-0.2.83a9-py3-none-any.whl", hash = "sha256:7cfe97b590096c1cc5afddf6dca023c5b9a47d104196c16b4b2b1934931af260", size = 1595808, upload-time = "2026-01-15T21:28:21.068Z" }, + { url = "https://files.pythonhosted.org/packages/32/e2/4e2964059794af9161889223fa7d17630c1bcc74005c9892cd1e1627650c/camel_ai-0.2.83-py3-none-any.whl", hash = "sha256:3a183efdcccd211ae216b2a7903d48a8811ad0f4541223cacc05cb25a11279a6", size = 1599355, upload-time = "2026-01-19T20:37:41.985Z" }, ] [[package]] @@ -364,7 +364,7 @@ requires-dist = [ { name = "alembic", specifier = ">=1.15.2" }, { name = "arrow", specifier = ">=1.3.0" }, { name = "bcrypt", specifier = "==4.0.1" }, - { name = "camel-ai", specifier = "==0.2.83a9" }, + { name = "camel-ai", specifier = "==0.2.83" }, { name = "click", specifier = ">=8.1.8" }, { name = "convert-case", specifier = ">=1.2.3" }, { name = "cryptography", specifier = ">=45.0.4" }, @@ -473,16 +473,16 @@ wheels = [ [[package]] name = "fastapi-pagination" -version = "0.15.5" +version = "0.15.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fastapi" }, { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/41/5e/656fa2a88b25f3362d96b838d4858cb10f75ae62a917584375be3dae30fc/fastapi_pagination-0.15.5.tar.gz", hash = "sha256:65871797e53392f5a62eb206b4e1f5494d1f64a8ed4d085a32c4f7c1a1987ee1", size = 572714, upload-time = "2026-01-08T16:19:07.372Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a0/da/ad34e0fc98ca9731b0f76d07faeb39d525cb80440ac5814e270cb379d92a/fastapi_pagination-0.15.6.tar.gz", hash = "sha256:c59ca1aa056dccee3526953357c2d1128f988f83d3034d95ddb8de6f5a68e9f8", size = 573720, upload-time = "2026-01-11T22:15:36.385Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/47/f8/6d3dbbd818a106309d073c81081706541e8ffbf9ed581f799cf525e01e15/fastapi_pagination-0.15.5-py3-none-any.whl", hash = "sha256:a9276ad322d0c85b46f1d5e43b2ef33dce21d1a4dbf5598269752b7542a2b47b", size = 56576, upload-time = "2026-01-08T16:19:05.81Z" }, + { url = "https://files.pythonhosted.org/packages/01/28/0cf3b51115e98c0b84553b9e11ec07f59ae580bf8585eb7876fa9afe4c7a/fastapi_pagination-0.15.6-py3-none-any.whl", hash = "sha256:5c44bfaa78c1c968ca6f027b01a27c1805194c7cc8776eb84ec78235abcdaece", size = 59624, upload-time = "2026-01-11T22:15:37.746Z" }, ] [[package]] @@ -515,7 +515,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f8/0a/a3871375c7b9727edaeeea994bfff7c63ff7804c9829c19309ba2e058807/greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb", size = 276379, upload-time = "2025-12-04T14:23:30.498Z" }, { url = "https://files.pythonhosted.org/packages/43/ab/7ebfe34dce8b87be0d11dae91acbf76f7b8246bf9d6b319c741f99fa59c6/greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3", size = 597294, upload-time = "2025-12-04T14:50:06.847Z" }, { url = "https://files.pythonhosted.org/packages/a4/39/f1c8da50024feecd0793dbd5e08f526809b8ab5609224a2da40aad3a7641/greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655", size = 607742, upload-time = "2025-12-04T14:57:42.349Z" }, - { url = "https://files.pythonhosted.org/packages/77/cb/43692bcd5f7a0da6ec0ec6d58ee7cddb606d055ce94a62ac9b1aa481e969/greenlet-3.3.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c024b1e5696626890038e34f76140ed1daf858e37496d33f2af57f06189e70d7", size = 622297, upload-time = "2025-12-04T15:07:13.552Z" }, { url = "https://files.pythonhosted.org/packages/75/b0/6bde0b1011a60782108c01de5913c588cf51a839174538d266de15e4bf4d/greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b", size = 609885, upload-time = "2025-12-04T14:26:02.368Z" }, { url = "https://files.pythonhosted.org/packages/49/0e/49b46ac39f931f59f987b7cd9f34bfec8ef81d2a1e6e00682f55be5de9f4/greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53", size = 1567424, upload-time = "2025-12-04T15:04:23.757Z" }, { url = "https://files.pythonhosted.org/packages/05/f5/49a9ac2dff7f10091935def9165c90236d8f175afb27cbed38fb1d61ab6b/greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614", size = 1636017, upload-time = "2025-12-04T14:27:29.688Z" }, @@ -738,21 +737,21 @@ wheels = [ [[package]] name = "numpy" -version = "2.4.0" +version = "2.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a4/7a/6a3d14e205d292b738db449d0de649b373a59edb0d0b4493821d0a3e8718/numpy-2.4.0.tar.gz", hash = "sha256:6e504f7b16118198f138ef31ba24d985b124c2c469fe8467007cf30fd992f934", size = 20685720, upload-time = "2025-12-20T16:18:19.023Z" } +sdist = { url = "https://files.pythonhosted.org/packages/24/62/ae72ff66c0f1fd959925b4c11f8c2dea61f47f6acaea75a08512cdfe3fed/numpy-2.4.1.tar.gz", hash = "sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690", size = 20721320, upload-time = "2026-01-10T06:44:59.619Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/ff/f6400ffec95de41c74b8e73df32e3fff1830633193a7b1e409be7fb1bb8c/numpy-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a8b6bb8369abefb8bd1801b054ad50e02b3275c8614dc6e5b0373c305291037", size = 16653117, upload-time = "2025-12-20T16:16:06.709Z" }, - { url = "https://files.pythonhosted.org/packages/fd/28/6c23e97450035072e8d830a3c411bf1abd1f42c611ff9d29e3d8f55c6252/numpy-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e284ca13d5a8367e43734148622caf0b261b275673823593e3e3634a6490f83", size = 12369711, upload-time = "2025-12-20T16:16:08.758Z" }, - { url = "https://files.pythonhosted.org/packages/bc/af/acbef97b630ab1bb45e6a7d01d1452e4251aa88ce680ac36e56c272120ec/numpy-2.4.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:49ff32b09f5aa0cd30a20c2b39db3e669c845589f2b7fc910365210887e39344", size = 5198355, upload-time = "2025-12-20T16:16:10.902Z" }, - { url = "https://files.pythonhosted.org/packages/c1/c8/4e0d436b66b826f2e53330adaa6311f5cac9871a5b5c31ad773b27f25a74/numpy-2.4.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:36cbfb13c152b1c7c184ddac43765db8ad672567e7bafff2cc755a09917ed2e6", size = 6545298, upload-time = "2025-12-20T16:16:12.607Z" }, - { url = "https://files.pythonhosted.org/packages/ef/27/e1f5d144ab54eac34875e79037011d511ac57b21b220063310cb96c80fbc/numpy-2.4.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35ddc8f4914466e6fc954c76527aa91aa763682a4f6d73249ef20b418fe6effb", size = 14398387, upload-time = "2025-12-20T16:16:14.257Z" }, - { url = "https://files.pythonhosted.org/packages/67/64/4cb909dd5ab09a9a5d086eff9586e69e827b88a5585517386879474f4cf7/numpy-2.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc578891de1db95b2a35001b695451767b580bb45753717498213c5ff3c41d63", size = 16363091, upload-time = "2025-12-20T16:16:17.32Z" }, - { url = "https://files.pythonhosted.org/packages/9d/9c/8efe24577523ec6809261859737cf117b0eb6fdb655abdfdc81b2e468ce4/numpy-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98e81648e0b36e325ab67e46b5400a7a6d4a22b8a7c8e8bbfe20e7db7906bf95", size = 16176394, upload-time = "2025-12-20T16:16:19.524Z" }, - { url = "https://files.pythonhosted.org/packages/61/f0/1687441ece7b47a62e45a1f82015352c240765c707928edd8aef875d5951/numpy-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d57b5046c120561ba8fa8e4030fbb8b822f3063910fa901ffadf16e2b7128ad6", size = 18287378, upload-time = "2025-12-20T16:16:22.866Z" }, - { url = "https://files.pythonhosted.org/packages/d3/6f/f868765d44e6fc466467ed810ba9d8d6db1add7d4a748abfa2a4c99a3194/numpy-2.4.0-cp312-cp312-win32.whl", hash = "sha256:92190db305a6f48734d3982f2c60fa30d6b5ee9bff10f2887b930d7b40119f4c", size = 5955432, upload-time = "2025-12-20T16:16:25.06Z" }, - { url = "https://files.pythonhosted.org/packages/d4/b5/94c1e79fcbab38d1ca15e13777477b2914dd2d559b410f96949d6637b085/numpy-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:680060061adb2d74ce352628cb798cfdec399068aa7f07ba9fb818b2b3305f98", size = 12306201, upload-time = "2025-12-20T16:16:26.979Z" }, - { url = "https://files.pythonhosted.org/packages/70/09/c39dadf0b13bb0768cd29d6a3aaff1fb7c6905ac40e9aaeca26b1c086e06/numpy-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:39699233bc72dd482da1415dcb06076e32f60eddc796a796c5fb6c5efce94667", size = 10308234, upload-time = "2025-12-20T16:16:29.417Z" }, + { url = "https://files.pythonhosted.org/packages/78/7f/ec53e32bf10c813604edf07a3682616bd931d026fcde7b6d13195dfb684a/numpy-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d3703409aac693fa82c0aee023a1ae06a6e9d065dba10f5e8e80f642f1e9d0a2", size = 16656888, upload-time = "2026-01-10T06:42:40.913Z" }, + { url = "https://files.pythonhosted.org/packages/b8/e0/1f9585d7dae8f14864e948fd7fa86c6cb72dee2676ca2748e63b1c5acfe0/numpy-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7211b95ca365519d3596a1d8688a95874cc94219d417504d9ecb2df99fa7bfa8", size = 12373956, upload-time = "2026-01-10T06:42:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/8e/43/9762e88909ff2326f5e7536fa8cb3c49fb03a7d92705f23e6e7f553d9cb3/numpy-2.4.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5adf01965456a664fc727ed69cc71848f28d063217c63e1a0e200a118d5eec9a", size = 5202567, upload-time = "2026-01-10T06:42:45.107Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ee/34b7930eb61e79feb4478800a4b95b46566969d837546aa7c034c742ef98/numpy-2.4.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:26f0bcd9c79a00e339565b303badc74d3ea2bd6d52191eeca5f95936cad107d0", size = 6549459, upload-time = "2026-01-10T06:42:48.152Z" }, + { url = "https://files.pythonhosted.org/packages/79/e3/5f115fae982565771be994867c89bcd8d7208dbfe9469185497d70de5ddf/numpy-2.4.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0093e85df2960d7e4049664b26afc58b03236e967fb942354deef3208857a04c", size = 14404859, upload-time = "2026-01-10T06:42:49.947Z" }, + { url = "https://files.pythonhosted.org/packages/d9/7d/9c8a781c88933725445a859cac5d01b5871588a15969ee6aeb618ba99eee/numpy-2.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ad270f438cbdd402c364980317fb6b117d9ec5e226fff5b4148dd9aa9fc6e02", size = 16371419, upload-time = "2026-01-10T06:42:52.409Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d2/8aa084818554543f17cf4162c42f162acbd3bb42688aefdba6628a859f77/numpy-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:297c72b1b98100c2e8f873d5d35fb551fce7040ade83d67dd51d38c8d42a2162", size = 16182131, upload-time = "2026-01-10T06:42:54.694Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/0425216684297c58a8df35f3284ef56ec4a043e6d283f8a59c53562caf1b/numpy-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf6470d91d34bf669f61d515499859fa7a4c2f7c36434afb70e82df7217933f9", size = 18295342, upload-time = "2026-01-10T06:42:56.991Z" }, + { url = "https://files.pythonhosted.org/packages/31/4c/14cb9d86240bd8c386c881bafbe43f001284b7cce3bc01623ac9475da163/numpy-2.4.1-cp312-cp312-win32.whl", hash = "sha256:b6bcf39112e956594b3331316d90c90c90fb961e39696bda97b89462f5f3943f", size = 5959015, upload-time = "2026-01-10T06:42:59.631Z" }, + { url = "https://files.pythonhosted.org/packages/51/cf/52a703dbeb0c65807540d29699fef5fda073434ff61846a564d5c296420f/numpy-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:e1a27bb1b2dee45a2a53f5ca6ff2d1a7f135287883a1689e930d44d1ff296c87", size = 12310730, upload-time = "2026-01-10T06:43:01.627Z" }, + { url = "https://files.pythonhosted.org/packages/69/80/a828b2d0ade5e74a9fe0f4e0a17c30fdc26232ad2bc8c9f8b3197cf7cf18/numpy-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:0e6e8f9d9ecf95399982019c01223dc130542960a12edfa8edd1122dfa66a8a8", size = 10312166, upload-time = "2026-01-10T06:43:03.673Z" }, ] [[package]] @@ -1175,14 +1174,14 @@ wheels = [ [[package]] name = "pydash" -version = "8.0.5" +version = "8.0.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/24/91c037f47e434172c2112d65c00c84d475a6715425e3315ba2cbb7a87e66/pydash-8.0.5.tar.gz", hash = "sha256:7cc44ebfe5d362f4f5f06c74c8684143c5ac481376b059ff02570705523f9e2e", size = 164861, upload-time = "2025-01-17T16:08:50.562Z" } +sdist = { url = "https://files.pythonhosted.org/packages/75/c1/1c55272f49d761cec38ddb80be9817935b9c91ebd6a8988e10f532868d56/pydash-8.0.6.tar.gz", hash = "sha256:b2821547e9723f69cf3a986be4db64de41730be149b2641947ecd12e1e11025a", size = 164338, upload-time = "2026-01-17T16:42:56.576Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/86/e74c978800131c657fc5145f2c1c63e0cea01a49b6216f729cf77a2e1edf/pydash-8.0.5-py3-none-any.whl", hash = "sha256:b2625f8981862e19911daa07f80ed47b315ce20d9b5eb57aaf97aaf570c3892f", size = 102077, upload-time = "2025-01-17T16:08:47.91Z" }, + { url = "https://files.pythonhosted.org/packages/a5/b7/cc5e7974699db40014d58c7dd7c4ad4ffc244d36930dc9ec7d06ee67d7a9/pydash-8.0.6-py3-none-any.whl", hash = "sha256:ee70a81a5b292c007f28f03a4ee8e75c1f5d7576df5457b836ec7ab2839cc5d0", size = 101561, upload-time = "2026-01-17T16:42:55.448Z" }, ] [[package]] @@ -1281,24 +1280,26 @@ wheels = [ [[package]] name = "regex" -version = "2025.11.3" +version = "2026.1.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/a9/546676f25e573a4cf00fe8e119b78a37b6a8fe2dc95cda877b30889c9c45/regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01", size = 414669, upload-time = "2025-11-03T21:34:22.089Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/86/07d5056945f9ec4590b518171c4254a5925832eb727b56d3c38a7476f316/regex-2026.1.15.tar.gz", hash = "sha256:164759aa25575cbc0651bef59a0b18353e54300d79ace8084c818ad8ac72b7d5", size = 414811, upload-time = "2026-01-14T23:18:02.775Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/74/18f04cb53e58e3fb107439699bd8375cf5a835eec81084e0bddbd122e4c2/regex-2025.11.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bc8ab71e2e31b16e40868a40a69007bc305e1109bd4658eb6cad007e0bf67c41", size = 489312, upload-time = "2025-11-03T21:31:34.343Z" }, - { url = "https://files.pythonhosted.org/packages/78/3f/37fcdd0d2b1e78909108a876580485ea37c91e1acf66d3bb8e736348f441/regex-2025.11.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:22b29dda7e1f7062a52359fca6e58e548e28c6686f205e780b02ad8ef710de36", size = 291256, upload-time = "2025-11-03T21:31:35.675Z" }, - { url = "https://files.pythonhosted.org/packages/bf/26/0a575f58eb23b7ebd67a45fccbc02ac030b737b896b7e7a909ffe43ffd6a/regex-2025.11.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a91e4a29938bc1a082cc28fdea44be420bf2bebe2665343029723892eb073e1", size = 288921, upload-time = "2025-11-03T21:31:37.07Z" }, - { url = "https://files.pythonhosted.org/packages/ea/98/6a8dff667d1af907150432cf5abc05a17ccd32c72a3615410d5365ac167a/regex-2025.11.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08b884f4226602ad40c5d55f52bf91a9df30f513864e0054bad40c0e9cf1afb7", size = 798568, upload-time = "2025-11-03T21:31:38.784Z" }, - { url = "https://files.pythonhosted.org/packages/64/15/92c1db4fa4e12733dd5a526c2dd2b6edcbfe13257e135fc0f6c57f34c173/regex-2025.11.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3e0b11b2b2433d1c39c7c7a30e3f3d0aeeea44c2a8d0bae28f6b95f639927a69", size = 864165, upload-time = "2025-11-03T21:31:40.559Z" }, - { url = "https://files.pythonhosted.org/packages/f9/e7/3ad7da8cdee1ce66c7cd37ab5ab05c463a86ffeb52b1a25fe7bd9293b36c/regex-2025.11.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87eb52a81ef58c7ba4d45c3ca74e12aa4b4e77816f72ca25258a85b3ea96cb48", size = 912182, upload-time = "2025-11-03T21:31:42.002Z" }, - { url = "https://files.pythonhosted.org/packages/84/bd/9ce9f629fcb714ffc2c3faf62b6766ecb7a585e1e885eb699bcf130a5209/regex-2025.11.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a12ab1f5c29b4e93db518f5e3872116b7e9b1646c9f9f426f777b50d44a09e8c", size = 803501, upload-time = "2025-11-03T21:31:43.815Z" }, - { url = "https://files.pythonhosted.org/packages/7c/0f/8dc2e4349d8e877283e6edd6c12bdcebc20f03744e86f197ab6e4492bf08/regex-2025.11.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7521684c8c7c4f6e88e35ec89680ee1aa8358d3f09d27dfbdf62c446f5d4c695", size = 787842, upload-time = "2025-11-03T21:31:45.353Z" }, - { url = "https://files.pythonhosted.org/packages/f9/73/cff02702960bc185164d5619c0c62a2f598a6abff6695d391b096237d4ab/regex-2025.11.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7fe6e5440584e94cc4b3f5f4d98a25e29ca12dccf8873679a635638349831b98", size = 858519, upload-time = "2025-11-03T21:31:46.814Z" }, - { url = "https://files.pythonhosted.org/packages/61/83/0e8d1ae71e15bc1dc36231c90b46ee35f9d52fab2e226b0e039e7ea9c10a/regex-2025.11.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8e026094aa12b43f4fd74576714e987803a315c76edb6b098b9809db5de58f74", size = 850611, upload-time = "2025-11-03T21:31:48.289Z" }, - { url = "https://files.pythonhosted.org/packages/c8/f5/70a5cdd781dcfaa12556f2955bf170cd603cb1c96a1827479f8faea2df97/regex-2025.11.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:435bbad13e57eb5606a68443af62bed3556de2f46deb9f7d4237bc2f1c9fb3a0", size = 789759, upload-time = "2025-11-03T21:31:49.759Z" }, - { url = "https://files.pythonhosted.org/packages/59/9b/7c29be7903c318488983e7d97abcf8ebd3830e4c956c4c540005fcfb0462/regex-2025.11.3-cp312-cp312-win32.whl", hash = "sha256:3839967cf4dc4b985e1570fd8d91078f0c519f30491c60f9ac42a8db039be204", size = 266194, upload-time = "2025-11-03T21:31:51.53Z" }, - { url = "https://files.pythonhosted.org/packages/1a/67/3b92df89f179d7c367be654ab5626ae311cb28f7d5c237b6bb976cd5fbbb/regex-2025.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:e721d1b46e25c481dc5ded6f4b3f66c897c58d2e8cfdf77bbced84339108b0b9", size = 277069, upload-time = "2025-11-03T21:31:53.151Z" }, - { url = "https://files.pythonhosted.org/packages/d7/55/85ba4c066fe5094d35b249c3ce8df0ba623cfd35afb22d6764f23a52a1c5/regex-2025.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:64350685ff08b1d3a6fff33f45a9ca183dc1d58bbfe4981604e70ec9801bbc26", size = 270330, upload-time = "2025-11-03T21:31:54.514Z" }, + { url = "https://files.pythonhosted.org/packages/92/81/10d8cf43c807d0326efe874c1b79f22bfb0fb226027b0b19ebc26d301408/regex-2026.1.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4c8fcc5793dde01641a35905d6731ee1548f02b956815f8f1cab89e515a5bdf1", size = 489398, upload-time = "2026-01-14T23:14:43.741Z" }, + { url = "https://files.pythonhosted.org/packages/90/b0/7c2a74e74ef2a7c32de724658a69a862880e3e4155cba992ba04d1c70400/regex-2026.1.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bfd876041a956e6a90ad7cdb3f6a630c07d491280bfeed4544053cd434901681", size = 291339, upload-time = "2026-01-14T23:14:45.183Z" }, + { url = "https://files.pythonhosted.org/packages/19/4d/16d0773d0c818417f4cc20aa0da90064b966d22cd62a8c46765b5bd2d643/regex-2026.1.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9250d087bc92b7d4899ccd5539a1b2334e44eee85d848c4c1aef8e221d3f8c8f", size = 289003, upload-time = "2026-01-14T23:14:47.25Z" }, + { url = "https://files.pythonhosted.org/packages/c6/e4/1fc4599450c9f0863d9406e944592d968b8d6dfd0d552a7d569e43bceada/regex-2026.1.15-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8a154cf6537ebbc110e24dabe53095e714245c272da9c1be05734bdad4a61aa", size = 798656, upload-time = "2026-01-14T23:14:48.77Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e6/59650d73a73fa8a60b3a590545bfcf1172b4384a7df2e7fe7b9aab4e2da9/regex-2026.1.15-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8050ba2e3ea1d8731a549e83c18d2f0999fbc99a5f6bd06b4c91449f55291804", size = 864252, upload-time = "2026-01-14T23:14:50.528Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ab/1d0f4d50a1638849a97d731364c9a80fa304fec46325e48330c170ee8e80/regex-2026.1.15-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf065240704cb8951cc04972cf107063917022511273e0969bdb34fc173456c", size = 912268, upload-time = "2026-01-14T23:14:52.952Z" }, + { url = "https://files.pythonhosted.org/packages/dd/df/0d722c030c82faa1d331d1921ee268a4e8fb55ca8b9042c9341c352f17fa/regex-2026.1.15-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c32bef3e7aeee75746748643667668ef941d28b003bfc89994ecf09a10f7a1b5", size = 803589, upload-time = "2026-01-14T23:14:55.182Z" }, + { url = "https://files.pythonhosted.org/packages/66/23/33289beba7ccb8b805c6610a8913d0131f834928afc555b241caabd422a9/regex-2026.1.15-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d5eaa4a4c5b1906bd0d2508d68927f15b81821f85092e06f1a34a4254b0e1af3", size = 775700, upload-time = "2026-01-14T23:14:56.707Z" }, + { url = "https://files.pythonhosted.org/packages/e7/65/bf3a42fa6897a0d3afa81acb25c42f4b71c274f698ceabd75523259f6688/regex-2026.1.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:86c1077a3cc60d453d4084d5b9649065f3bf1184e22992bd322e1f081d3117fb", size = 787928, upload-time = "2026-01-14T23:14:58.312Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f5/13bf65864fc314f68cdd6d8ca94adcab064d4d39dbd0b10fef29a9da48fc/regex-2026.1.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:2b091aefc05c78d286657cd4db95f2e6313375ff65dcf085e42e4c04d9c8d410", size = 858607, upload-time = "2026-01-14T23:15:00.657Z" }, + { url = "https://files.pythonhosted.org/packages/a3/31/040e589834d7a439ee43fb0e1e902bc81bd58a5ba81acffe586bb3321d35/regex-2026.1.15-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:57e7d17f59f9ebfa9667e6e5a1c0127b96b87cb9cede8335482451ed00788ba4", size = 763729, upload-time = "2026-01-14T23:15:02.248Z" }, + { url = "https://files.pythonhosted.org/packages/9b/84/6921e8129687a427edf25a34a5594b588b6d88f491320b9de5b6339a4fcb/regex-2026.1.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c6c4dcdfff2c08509faa15d36ba7e5ef5fcfab25f1e8f85a0c8f45bc3a30725d", size = 850697, upload-time = "2026-01-14T23:15:03.878Z" }, + { url = "https://files.pythonhosted.org/packages/8a/87/3d06143d4b128f4229158f2de5de6c8f2485170c7221e61bf381313314b2/regex-2026.1.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf8ff04c642716a7f2048713ddc6278c5fd41faa3b9cab12607c7abecd012c22", size = 789849, upload-time = "2026-01-14T23:15:06.102Z" }, + { url = "https://files.pythonhosted.org/packages/77/69/c50a63842b6bd48850ebc7ab22d46e7a2a32d824ad6c605b218441814639/regex-2026.1.15-cp312-cp312-win32.whl", hash = "sha256:82345326b1d8d56afbe41d881fdf62f1926d7264b2fc1537f99ae5da9aad7913", size = 266279, upload-time = "2026-01-14T23:15:07.678Z" }, + { url = "https://files.pythonhosted.org/packages/f2/36/39d0b29d087e2b11fd8191e15e81cce1b635fcc845297c67f11d0d19274d/regex-2026.1.15-cp312-cp312-win_amd64.whl", hash = "sha256:4def140aa6156bc64ee9912383d4038f3fdd18fee03a6f222abd4de6357ce42a", size = 277166, upload-time = "2026-01-14T23:15:09.257Z" }, + { url = "https://files.pythonhosted.org/packages/28/32/5b8e476a12262748851fa8ab1b0be540360692325975b094e594dfebbb52/regex-2026.1.15-cp312-cp312-win_arm64.whl", hash = "sha256:c6c565d9a6e1a8d783c1948937ffc377dd5771e83bd56de8317c450a954d2056", size = 270415, upload-time = "2026-01-14T23:15:10.743Z" }, ] [[package]] @@ -1424,15 +1425,15 @@ wheels = [ [[package]] name = "sse-starlette" -version = "3.1.2" +version = "3.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "starlette" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/34/f5df66cb383efdbf4f2db23cabb27f51b1dcb737efaf8a558f6f1d195134/sse_starlette-3.1.2.tar.gz", hash = "sha256:55eff034207a83a0eb86de9a68099bd0157838f0b8b999a1b742005c71e33618", size = 26303, upload-time = "2025-12-31T08:02:20.023Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/8d/00d280c03ffd39aaee0e86ec81e2d3b9253036a0f93f51d10503adef0e65/sse_starlette-3.2.0.tar.gz", hash = "sha256:8127594edfb51abe44eac9c49e59b0b01f1039d0c7461c6fd91d4e03b70da422", size = 27253, upload-time = "2026-01-17T13:11:05.62Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/95/8c4b76eec9ae574474e5d2997557cebf764bcd3586458956c30631ae08f4/sse_starlette-3.1.2-py3-none-any.whl", hash = "sha256:cd800dd349f4521b317b9391d3796fa97b71748a4da9b9e00aafab32dda375c8", size = 12484, upload-time = "2025-12-31T08:02:18.894Z" }, + { url = "https://files.pythonhosted.org/packages/96/7f/832f015020844a8b8f7a9cbc103dd76ba8e3875004c41e08440ea3a2b41a/sse_starlette-3.2.0-py3-none-any.whl", hash = "sha256:5876954bd51920fc2cd51baee47a080eb88a37b5b784e615abb0b283f801cdbf", size = 12763, upload-time = "2026-01-17T13:11:03.775Z" }, ] [[package]] From d755a3edc11faa239f95eefc0ea7a473856dd987 Mon Sep 17 00:00:00 2001 From: puzhen <1303385763@qq.com> Date: Mon, 19 Jan 2026 23:03:30 +0000 Subject: [PATCH 28/63] clean code --- backend/app/controller/chat_controller.py | 26 +--- backend/app/service/chat_service.py | 117 ++++-------------- backend/app/utils/agent.py | 91 ++++---------- backend/app/utils/toolkit/terminal_toolkit.py | 34 +---- backend/app/utils/workforce.py | 110 ++-------------- 5 files changed, 63 insertions(+), 315 deletions(-) diff --git a/backend/app/controller/chat_controller.py b/backend/app/controller/chat_controller.py index de44fdc2..3dd63795 100644 --- a/backend/app/controller/chat_controller.py +++ b/backend/app/controller/chat_controller.py @@ -74,24 +74,16 @@ async def timeout_stream_wrapper(stream_generator, timeout_seconds: int = SSE_TI @router.post("/chat", name="start chat") @traceroot.trace() async def post(data: Chat, request: Request): - # === TIMING: Request received === request_start_time = time.time() chat_logger.info( - "⏱️ [TIMING] Request received", - extra={"project_id": data.project_id, "task_id": data.task_id, "user": data.email, "timestamp": request_start_time} + "Starting new chat session", + extra={"project_id": data.project_id, "task_id": data.task_id, "user": data.email} ) - task_lock_start = time.time() task_lock = get_or_create_task_lock(data.project_id) - task_lock_time = (time.time() - task_lock_start) * 1000 - chat_logger.info(f"⏱️ [TIMING] task_lock created in {task_lock_time:.2f}ms") - # Store request start time in task_lock for downstream timing task_lock.request_start_time = request_start_time - # === TIMING: Environment setup === - env_setup_start = time.time() - # Set user-specific environment path for this thread set_user_env_path(data.env_path) load_dotenv(dotenv_path=data.env_path) @@ -105,12 +97,9 @@ async def post(data: Chat, request: Request): # Set user-specific search engine configuration if provided if data.search_config: for key, value in data.search_config.items(): - if value: # Only set non-empty values + if value: os.environ[key] = value - chat_logger.info(f"Set search config: {key}", extra={"project_id": data.project_id}) - - env_setup_time = (time.time() - env_setup_start) * 1000 - chat_logger.info(f"⏱️ [TIMING] Environment setup completed in {env_setup_time:.2f}ms") + chat_logger.debug(f"Set search config: {key}", extra={"project_id": data.project_id}) email_sanitized = re.sub(r'[\\/*?:"<>|\s]', "_", data.email.split("@")[0]).strip(".") camel_log = ( @@ -131,16 +120,11 @@ async def post(data: Chat, request: Request): # Set the initial current_task_id in task_lock set_current_task_id(data.project_id, data.task_id) - # === TIMING: Queue operation === - queue_start = time.time() # Put initial action in queue to start processing await task_lock.put_queue(ActionImproveData(data=data.question, new_task_id=data.task_id)) - queue_time = (time.time() - queue_start) * 1000 - chat_logger.info(f"⏱️ [TIMING] Question queued in {queue_time:.2f}ms") - total_controller_time = (time.time() - request_start_time) * 1000 chat_logger.info( - f"⏱️ [TIMING] Controller total time: {total_controller_time:.2f}ms (task_lock: {task_lock_time:.2f}ms, env: {env_setup_time:.2f}ms, queue: {queue_time:.2f}ms)", + "Chat session initialized", extra={"project_id": data.project_id, "task_id": data.task_id, "log_dir": str(camel_log)}, ) return StreamingResponse( diff --git a/backend/app/service/chat_service.py b/backend/app/service/chat_service.py index 561d903c..28205e73 100644 --- a/backend/app/service/chat_service.py +++ b/backend/app/service/chat_service.py @@ -1385,27 +1385,21 @@ async def construct_workforce(options: Chat) -> tuple[Workforce, ListenChatAgent This function creates all agents in PARALLEL to minimize startup time. Sync functions are run in thread pool, async functions are awaited concurrently. """ - import time as time_module - - # === TIMING: construct_workforce start === - construct_start = time_module.time() - logger.info("⏱️ [TIMING] construct_workforce started (PARALLEL mode)", extra={"project_id": options.project_id, "task_id": options.task_id}) + logger.debug("construct_workforce started", extra={"project_id": options.project_id, "task_id": options.task_id}) # Store main event loop reference for thread-safe async task scheduling # This allows agent_model() to schedule tasks when called from worker threads set_main_event_loop(asyncio.get_running_loop()) working_directory = get_working_directory(options) - logger.debug("Working directory set", extra={"working_directory": working_directory}) # ======================================================================== - # Define sync agent creation functions (will be run in thread pool) + # Define agent creation functions # ======================================================================== def _create_coordinator_and_task_agents() -> list[ListenChatAgent]: """Create coordinator and task agents (sync, runs in thread pool).""" - start = time_module.time() - agents = [ + return [ agent_model( key, prompt, @@ -1437,14 +1431,10 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS """, }.items() ] - elapsed = (time_module.time() - start) * 1000 - logger.info(f"⏱️ [TIMING] Coordinator + Task agents created in {elapsed:.2f}ms (thread)") - return agents def _create_new_worker_agent() -> ListenChatAgent: """Create new worker agent (sync, runs in thread pool).""" - start = time_module.time() - agent = agent_model( + return agent_model( Agents.new_worker_agent, f""" You are a helpful assistant. @@ -1462,81 +1452,34 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS ).get_tools(), ], ) - elapsed = (time_module.time() - start) * 1000 - logger.info(f"⏱️ [TIMING] New worker agent created in {elapsed:.2f}ms (thread)") - return agent - - def _create_browser_agent() -> ListenChatAgent: - """Create browser agent (sync, runs in thread pool).""" - start = time_module.time() - agent = browser_agent(options) - elapsed = (time_module.time() - start) * 1000 - logger.info(f"⏱️ [TIMING] Browser agent created in {elapsed:.2f}ms (thread)") - return agent - - def _create_multi_modal_agent() -> ListenChatAgent: - """Create multi-modal agent (sync, runs in thread pool).""" - start = time_module.time() - agent = multi_modal_agent(options) - elapsed = (time_module.time() - start) * 1000 - logger.info(f"⏱️ [TIMING] Multi-modal agent created in {elapsed:.2f}ms (thread)") - return agent - - # ======================================================================== - # Define async agent creation wrappers (for timing) - # ======================================================================== - - async def _create_developer_agent() -> ListenChatAgent: - """Create developer agent (async).""" - start = time_module.time() - agent = await developer_agent(options) - elapsed = (time_module.time() - start) * 1000 - logger.info(f"⏱️ [TIMING] Developer agent created in {elapsed:.2f}ms (async)") - return agent - - async def _create_document_agent() -> ListenChatAgent: - """Create document agent (async).""" - start = time_module.time() - agent = await document_agent(options) - elapsed = (time_module.time() - start) * 1000 - logger.info(f"⏱️ [TIMING] Document agent created in {elapsed:.2f}ms (async)") - return agent - - async def _create_mcp_agent() -> ListenChatAgent: - """Create MCP agent (async).""" - start = time_module.time() - agent = await mcp_agent(options) - elapsed = (time_module.time() - start) * 1000 - logger.info(f"⏱️ [TIMING] MCP agent created in {elapsed:.2f}ms (async)") - return agent # ======================================================================== # Execute all agent creations in PARALLEL # ======================================================================== - parallel_start = time_module.time() - logger.info("⏱️ [TIMING] Starting parallel agent creation...") - - # asyncio.gather runs all coroutines concurrently - # asyncio.to_thread runs sync functions in thread pool without blocking event loop - results = await asyncio.gather( - asyncio.to_thread(_create_coordinator_and_task_agents), # sync -> thread - asyncio.to_thread(_create_new_worker_agent), # sync -> thread - asyncio.to_thread(_create_browser_agent), # sync -> thread - _create_developer_agent(), # async - _create_document_agent(), # async - asyncio.to_thread(_create_multi_modal_agent), # sync -> thread - _create_mcp_agent(), # async - ) - - parallel_time = (time_module.time() - parallel_start) * 1000 - logger.info(f"⏱️ [TIMING] All agents created in parallel: {parallel_time:.2f}ms") + try: + # asyncio.gather runs all coroutines concurrently + # asyncio.to_thread runs sync functions in thread pool without blocking event loop + results = await asyncio.gather( + asyncio.to_thread(_create_coordinator_and_task_agents), + asyncio.to_thread(_create_new_worker_agent), + asyncio.to_thread(browser_agent, options), + developer_agent(options), + document_agent(options), + asyncio.to_thread(multi_modal_agent, options), + mcp_agent(options), + ) + except Exception as e: + logger.error(f"Failed to create agents in parallel: {e}", exc_info=True) + # Clear event loop reference on failure + set_main_event_loop(None) + raise # Unpack results ( - coord_task_agents, # [coordinator_agent, task_agent] + coord_task_agents, new_worker_agent, - searcher, # browser agent + searcher, developer, documenter, multi_modaler, @@ -1549,14 +1492,11 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS # Create Workforce instance and add workers (must be sequential) # ======================================================================== - # Convert string model_platform to enum for comparison try: model_platform_enum = ModelPlatformType(options.model_platform.lower()) except (ValueError, AttributeError): model_platform_enum = None - # === TIMING: Workforce instance creation === - workforce_instance_start = time_module.time() workforce = Workforce( options.project_id, "A workforce", @@ -1567,11 +1507,7 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS new_worker_agent=new_worker_agent, use_structured_output_handler=False if model_platform_enum == ModelPlatformType.OPENAI else True, ) - workforce_instance_time = (time_module.time() - workforce_instance_start) * 1000 - logger.info(f"⏱️ [TIMING] Workforce instance created in {workforce_instance_time:.2f}ms") - # === TIMING: Adding workers to workforce === - add_workers_start = time_module.time() workforce.add_single_agent_worker( "Developer Agent: A master-level coding assistant with a powerful " "terminal. It can write and execute code, manage files, automate " @@ -1599,13 +1535,6 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS "generate new images from text prompts.", multi_modaler, ) - add_workers_time = (time_module.time() - add_workers_start) * 1000 - logger.info(f"⏱️ [TIMING] Workers added to workforce in {add_workers_time:.2f}ms") - - # === TIMING: construct_workforce total === - total_construct_time = (time_module.time() - construct_start) * 1000 - logger.info(f"⏱️ [TIMING] construct_workforce TOTAL: {total_construct_time:.2f}ms (parallel agents: {parallel_time:.2f}ms)") - logger.info(f"⏱️ [TIMING] construct_workforce summary: parallel_agents={parallel_time:.2f}ms, workforce_init={workforce_instance_time:.2f}ms, add_workers={add_workers_time:.2f}ms") return workforce, mcp diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index 1c007f9e..070d188b 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -1,4 +1,5 @@ import asyncio +import contextvars import json import os import platform @@ -8,18 +9,21 @@ from typing import Any, Callable, Dict, List, Tuple import uuid from utils import traceroot_wrapper as traceroot -# Thread-safe reference to main event loop for scheduling tasks from worker threads -_main_event_loop: asyncio.AbstractEventLoop | None = None +# Thread-safe reference to main event loop using contextvars +# This ensures each request has its own event loop reference, avoiding race conditions +_main_event_loop_var: contextvars.ContextVar[asyncio.AbstractEventLoop | None] = contextvars.ContextVar( + '_main_event_loop', default=None +) def set_main_event_loop(loop: asyncio.AbstractEventLoop | None): """Set the main event loop reference for thread-safe task scheduling. This should be called from the main async context before spawning threads - that need to schedule async tasks. + that need to schedule async tasks. Uses contextvars to ensure thread-safety + across concurrent requests. """ - global _main_event_loop - _main_event_loop = loop + _main_event_loop_var.set(loop) def _schedule_async_task(coro): @@ -34,15 +38,16 @@ def _schedule_async_task(coro): loop.create_task(coro) except RuntimeError: # No running loop in this thread (we're in a worker thread) - # Use the stored main loop reference - if _main_event_loop is not None and _main_event_loop.is_running(): - asyncio.run_coroutine_threadsafe(coro, _main_event_loop) + # Use the stored main loop reference from contextvars + main_loop = _main_event_loop_var.get() + if main_loop is not None and main_loop.is_running(): + asyncio.run_coroutine_threadsafe(coro, main_loop) else: - # Fallback: run synchronously (not ideal but works) - traceroot.get_logger("agent").warning( - "No event loop available for async task scheduling, running synchronously" + # This should not happen in normal operation - log error and skip + traceroot.get_logger("agent").error( + "No event loop available for async task scheduling, task skipped. " + "Ensure set_main_event_loop() is called before parallel agent creation." ) - asyncio.run(coro) from camel.agents import ChatAgent from camel.agents.chat_agent import ( StreamingChatAgentResponse, @@ -702,12 +707,9 @@ def agent_model( toolkits_to_register_agent: list[RegisteredAgentToolkit] | None = None, enable_snapshot_clean: bool = False, ): - import time as time_module - agent_model_start = time_module.time() - task_lock = get_task_lock(options.project_id) agent_id = str(uuid.uuid4()) - traceroot_logger.info( + traceroot_logger.debug( f"Creating agent: {agent_name} with id: {agent_id} for project: {options.project_id}" ) # Use thread-safe scheduling to support parallel agent creation @@ -775,8 +777,6 @@ def agent_model( ) model_platform_enum = None - # === TIMING: ModelFactory.create === - t0 = time_module.time() model = ModelFactory.create( model_platform=options.model_platform, model_type=options.model_type, @@ -785,16 +785,12 @@ def agent_model( model_config_dict=model_config or None, **init_params, ) - model_create_time = (time_module.time() - t0) * 1000 - # === TIMING: ListenChatAgent creation === - t0 = time_module.time() - agent = ListenChatAgent( + return ListenChatAgent( options.project_id, agent_name, system_message, model=model, - # output_language=options.language, tools=tools, agent_id=agent_id, prune_tool_calls_from_memory=prune_tool_calls_from_memory, @@ -802,11 +798,6 @@ def agent_model( enable_snapshot_clean=enable_snapshot_clean, stream_accumulate=False, ) - agent_create_time = (time_module.time() - t0) * 1000 - - total_time = (time_module.time() - agent_model_start) * 1000 - traceroot_logger.info(f"⏱️ [TIMING] agent_model({agent_name}): {total_time:.2f}ms (model_create={model_create_time:.2f}ms, agent_create={agent_create_time:.2f}ms)") - return agent @traceroot.trace() @@ -1019,25 +1010,17 @@ these tips to maximize your effectiveness: @traceroot.trace() def browser_agent(options: Chat): - import time as time_module - browser_agent_start = time_module.time() - working_directory = get_working_directory(options) - traceroot_logger.info( + traceroot_logger.debug( f"Creating browser agent for project: {options.project_id} in directory: {working_directory}" ) - # === TIMING: message_integration === - t0 = time_module.time() message_integration = ToolkitMessageIntegration( message_handler=HumanToolkit( options.project_id, Agents.browser_agent ).send_message_to_user ) - traceroot_logger.info(f"⏱️ [TIMING] browser_agent: message_integration in {(time_module.time() - t0) * 1000:.2f}ms") - # === TIMING: HybridBrowserToolkit === - t0 = time_module.time() web_toolkit_custom = HybridBrowserToolkit( options.project_id, headless=False, @@ -1058,17 +1041,13 @@ def browser_agent(options: Chat): "browser_enter", "browser_visit_page", "browser_get_page_snapshot", - # "browser_get_som_screenshot", ], ) - traceroot_logger.info(f"⏱️ [TIMING] browser_agent: HybridBrowserToolkit in {(time_module.time() - t0) * 1000:.2f}ms") # Save reference before registering for toolkits_to_register_agent web_toolkit_for_agent_registration = web_toolkit_custom web_toolkit_custom = message_integration.register_toolkits(web_toolkit_custom) - # === TIMING: TerminalToolkit (already has internal timing) === - t0 = time_module.time() terminal_toolkit = TerminalToolkit( options.project_id, Agents.browser_agent, @@ -1078,25 +1057,17 @@ def browser_agent(options: Chat): terminal_toolkit = message_integration.register_functions( [terminal_toolkit.shell_exec] ) - traceroot_logger.info(f"⏱️ [TIMING] browser_agent: TerminalToolkit+register in {(time_module.time() - t0) * 1000:.2f}ms") - # === TIMING: NoteTakingToolkit === - t0 = time_module.time() note_toolkit = NoteTakingToolkit( options.project_id, Agents.browser_agent, working_directory=working_directory ) note_toolkit = message_integration.register_toolkits(note_toolkit) - traceroot_logger.info(f"⏱️ [TIMING] browser_agent: NoteTakingToolkit in {(time_module.time() - t0) * 1000:.2f}ms") - # === TIMING: SearchToolkit === - t0 = time_module.time() search_tools = SearchToolkit.get_can_use_tools(options.project_id) - # Only register search tools if any are available if search_tools: search_tools = message_integration.register_functions(search_tools) else: search_tools = [] - traceroot_logger.info(f"⏱️ [TIMING] browser_agent: SearchToolkit in {(time_module.time() - t0) * 1000:.2f}ms") tools = [ *HumanToolkit.get_can_use_tools(options.project_id, Agents.browser_agent), @@ -1241,15 +1212,11 @@ Your approach depends on available search tools: @traceroot.trace() async def document_agent(options: Chat): - import time as time_module - working_directory = get_working_directory(options) - traceroot_logger.info( + traceroot_logger.debug( f"Creating document agent for project: {options.project_id} in directory: {working_directory}" ) - # === TIMING: Toolkits creation === - t0 = time_module.time() message_integration = ToolkitMessageIntegration( message_handler=HumanToolkit( options.project_id, Agents.task_agent @@ -1270,9 +1237,7 @@ async def document_agent(options: Chat): options.project_id, Agents.document_agent, working_directory=working_directory ) note_toolkit = message_integration.register_toolkits(note_toolkit) - traceroot_logger.info(f"⏱️ [TIMING] document_agent: basic toolkits in {(time_module.time() - t0) * 1000:.2f}ms") - t0 = time_module.time() terminal_toolkit = TerminalToolkit( options.project_id, Agents.document_agent, @@ -1280,14 +1245,10 @@ async def document_agent(options: Chat): clone_current_env=True, ) terminal_toolkit = message_integration.register_toolkits(terminal_toolkit) - traceroot_logger.info(f"⏱️ [TIMING] document_agent: TerminalToolkit in {(time_module.time() - t0) * 1000:.2f}ms") - # === TIMING: GoogleDriveMCPToolkit (async) === - t0 = time_module.time() google_drive_tools = await GoogleDriveMCPToolkit.get_can_use_tools( options.project_id, options.get_bun_env() ) - traceroot_logger.info(f"⏱️ [TIMING] document_agent: GoogleDriveMCPToolkit in {(time_module.time() - t0) * 1000:.2f}ms") tools = [ *file_write_toolkit.get_tools(), @@ -1479,15 +1440,11 @@ supported formats including advanced spreadsheet functionality. @traceroot.trace() def multi_modal_agent(options: Chat): - import time as time_module - working_directory = get_working_directory(options) - traceroot_logger.info( + traceroot_logger.debug( f"Creating multi-modal agent for project: {options.project_id} in directory: {working_directory}" ) - # === TIMING: Basic toolkits === - t0 = time_module.time() message_integration = ToolkitMessageIntegration( message_handler=HumanToolkit( options.project_id, Agents.multi_modal_agent @@ -1503,10 +1460,7 @@ def multi_modal_agent(options: Chat): image_analysis_toolkit = message_integration.register_toolkits( image_analysis_toolkit ) - traceroot_logger.info(f"⏱️ [TIMING] multi_modal_agent: basic toolkits in {(time_module.time() - t0) * 1000:.2f}ms") - # === TIMING: TerminalToolkit === - t0 = time_module.time() terminal_toolkit = TerminalToolkit( options.project_id, agent_name=Agents.multi_modal_agent, @@ -1514,7 +1468,6 @@ def multi_modal_agent(options: Chat): clone_current_env=True, ) terminal_toolkit = message_integration.register_toolkits(terminal_toolkit) - traceroot_logger.info(f"⏱️ [TIMING] multi_modal_agent: TerminalToolkit in {(time_module.time() - t0) * 1000:.2f}ms") note_toolkit = NoteTakingToolkit( options.project_id, diff --git a/backend/app/utils/toolkit/terminal_toolkit.py b/backend/app/utils/toolkit/terminal_toolkit.py index 9d00b302..d1ea86a6 100644 --- a/backend/app/utils/toolkit/terminal_toolkit.py +++ b/backend/app/utils/toolkit/terminal_toolkit.py @@ -36,49 +36,23 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): allowed_commands: list[str] | None = None, clone_current_env: bool = True, ): - # === TIMING: TerminalToolkit init start === - init_start = time.time() - self.api_task_id = api_task_id if agent_name is not None: self.agent_name = agent_name if working_directory is None: working_directory = env("file_save_path", os.path.expanduser("~/.eigent/terminal/")) - logger.info(f"⏱️ [TIMING] TerminalToolkit.__init__ started for agent={self.agent_name}", extra={ + logger.debug(f"Initializing TerminalToolkit for agent={self.agent_name}", extra={ "api_task_id": api_task_id, - "agent_name": self.agent_name, "working_directory": working_directory, - "safe_mode": safe_mode, - "use_docker_backend": use_docker_backend + "clone_current_env": clone_current_env }) - logger.info(f"⏱️ [TIMING] working_directory={working_directory}") - # === TIMING: Thread pool creation === - thread_pool_start = time.time() if TerminalToolkit._thread_pool is None: TerminalToolkit._thread_pool = ThreadPoolExecutor( max_workers=1, thread_name_prefix="terminal_toolkit" ) - thread_pool_time = (time.time() - thread_pool_start) * 1000 - logger.info(f"⏱️ [TIMING] Created terminal toolkit thread pool in {thread_pool_time:.2f}ms") - else: - logger.debug("Thread pool already exists, skipping creation") - - # === TIMING: Base class init (this is the heavy part) === - super_init_start = time.time() - logger.info("⏱️ [TIMING] Starting BaseTerminalToolkit.__init__...") - logger.info(f"⏱️ [TIMING] Parameters: working_directory={working_directory}, clone_current_env={clone_current_env}") - - # Check if env already exists (determines if env setup is needed) - # .venv is used when clone_current_env=True, .initial_env when False - if clone_current_env: - env_path = os.path.join(working_directory, ".venv") if working_directory else None - else: - env_path = os.path.join(working_directory, ".initial_env") if working_directory else None - env_exists = env_path and os.path.exists(env_path) - logger.info(f"⏱️ [TIMING] env_path={env_path}, env_exists={env_exists}") super().__init__( timeout=timeout, @@ -90,10 +64,6 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): allowed_commands=allowed_commands, clone_current_env=clone_current_env, ) - super_init_time = (time.time() - super_init_start) * 1000 - total_init_time = (time.time() - init_start) * 1000 - logger.info(f"⏱️ [TIMING] BaseTerminalToolkit.__init__ completed in {super_init_time:.2f}ms (env_existed={env_exists})") - logger.info(f"⏱️ [TIMING] TerminalToolkit.__init__ TOTAL: {total_init_time:.2f}ms") def _write_to_log(self, log_file: str, content: str) -> None: r"""Write content to log file with optional ANSI stripping. diff --git a/backend/app/utils/workforce.py b/backend/app/utils/workforce.py index 7f2afb94..db2f4fa9 100644 --- a/backend/app/utils/workforce.py +++ b/backend/app/utils/workforce.py @@ -88,48 +88,26 @@ class Workforce(BaseWorkforce): on_stream_batch: Optional callback for streaming batches signature (List[Task], bool) on_stream_text: Optional callback for raw streaming text chunks """ - # === TIMING: eigent_make_sub_tasks start === - decompose_start = time.time() - - logger.info("=" * 80) - logger.info("🧩 [DECOMPOSE] eigent_make_sub_tasks CALLED", extra={ + logger.debug("[DECOMPOSE] eigent_make_sub_tasks called", extra={ "api_task_id": self.api_task_id, - "workforce_id": id(self), "task_id": task.id }) - logger.info(f"⏱️ [TIMING] eigent_make_sub_tasks started") - logger.info(f"[DECOMPOSE] Task content preview: '{task.content[:200]}...'") - logger.info(f"[DECOMPOSE] Has coordinator context: {bool(coordinator_context)}") - logger.info(f"[DECOMPOSE] Current workforce state: {self._state.name}, _running: {self._running}") - logger.info("=" * 80) - # === TIMING: Validation === - validation_start = time.time() if not validate_task_content(task.content, task.id): task.state = TaskState.FAILED task.result = "Task failed: Invalid or empty content provided" - logger.warning("❌ [DECOMPOSE] Task rejected: Invalid or empty content", extra={ + logger.warning("[DECOMPOSE] Task rejected: Invalid or empty content", extra={ "task_id": task.id, "content_preview": task.content[:50] + "..." if len(task.content) > 50 else task.content }) raise UserException(code.error, task.result) - validation_time = (time.time() - validation_start) * 1000 - logger.info(f"⏱️ [TIMING] Task validation completed in {validation_time:.2f}ms") - # === TIMING: Workforce reset === - reset_start = time.time() - logger.info(f"[DECOMPOSE] Resetting workforce state") self.reset() self._task = task self.set_channel(TaskChannel()) self._state = WorkforceState.RUNNING task.state = TaskState.OPEN - reset_time = (time.time() - reset_start) * 1000 - logger.info(f"⏱️ [TIMING] Workforce reset completed in {reset_time:.2f}ms, state: {self._state.name}") - # === TIMING: handle_decompose_append_task === - handle_decompose_start = time.time() - logger.info(f"[DECOMPOSE] Calling handle_decompose_append_task") subtasks = asyncio.run( self.handle_decompose_append_task( task, @@ -139,57 +117,37 @@ class Workforce(BaseWorkforce): on_stream_text=on_stream_text ) ) - handle_decompose_time = (time.time() - handle_decompose_start) * 1000 - logger.info(f"⏱️ [TIMING] handle_decompose_append_task completed in {handle_decompose_time:.2f}ms") - total_decompose_time = (time.time() - decompose_start) * 1000 - logger.info("=" * 80) - logger.info(f"✅ [DECOMPOSE] Task decomposition COMPLETED", extra={ + logger.info(f"[DECOMPOSE] Task decomposition completed", extra={ "api_task_id": self.api_task_id, "task_id": task.id, "subtasks_count": len(subtasks) }) - logger.info(f"⏱️ [TIMING] eigent_make_sub_tasks TOTAL: {total_decompose_time:.2f}ms (validation: {validation_time:.2f}ms, reset: {reset_time:.2f}ms, decompose: {handle_decompose_time:.2f}ms)") - logger.info("=" * 80) return subtasks async def eigent_start(self, subtasks: list[Task]): """start the workforce""" - logger.info("=" * 80) - logger.info("▶️ [WF-LIFECYCLE] eigent_start CALLED", extra={"api_task_id": self.api_task_id, "workforce_id": id(self)}) - logger.info(f"[WF-LIFECYCLE] Starting workforce execution with {len(subtasks)} subtasks") - logger.info(f"[WF-LIFECYCLE] Current workforce state: {self._state.name}, _running: {self._running}") - logger.info("=" * 80) + logger.debug(f"[WF-LIFECYCLE] eigent_start called with {len(subtasks)} subtasks", extra={ + "api_task_id": self.api_task_id + }) self._pending_tasks.extendleft(reversed(subtasks)) - # Save initial snapshot self.save_snapshot("Initial task decomposition") try: - logger.info(f"[WF-LIFECYCLE] Calling base class start() method") await self.start() - logger.info(f"[WF-LIFECYCLE] ✅ Base class start() method completed") except Exception as e: - logger.error(f"[WF-LIFECYCLE] ❌ Error in workforce execution: {e}", extra={ + logger.error(f"[WF-LIFECYCLE] Error in workforce execution: {e}", extra={ "api_task_id": self.api_task_id, "error": str(e) }, exc_info=True) self._state = WorkforceState.STOPPED - logger.info(f"[WF-LIFECYCLE] Workforce state set to STOPPED after error") raise finally: - logger.info(f"[WF-LIFECYCLE] eigent_start finally block, current state: {self._state.name}") if self._state != WorkforceState.STOPPED: self._state = WorkforceState.IDLE - logger.info(f"[WF-LIFECYCLE] Workforce state set to IDLE") def _decompose_task(self, task: Task, stream_callback=None): """Decompose task with optional streaming text callback.""" - # === TIMING: _decompose_task start === - decompose_task_start = time.time() - logger.info(f"⏱️ [TIMING] _decompose_task started") - - # === TIMING: Prompt building === - prompt_build_start = time.time() decompose_prompt = str( TASK_DECOMPOSE_PROMPT.format( content=task.content, @@ -197,23 +155,11 @@ class Workforce(BaseWorkforce): additional_info=task.additional_info, ) ) - prompt_build_time = (time.time() - prompt_build_start) * 1000 - logger.info(f"⏱️ [TIMING] Decompose prompt built in {prompt_build_time:.2f}ms (length: {len(decompose_prompt)} chars)") - # === TIMING: Agent reset === - agent_reset_start = time.time() self.task_agent.reset() - agent_reset_time = (time.time() - agent_reset_start) * 1000 - logger.info(f"⏱️ [TIMING] Task agent reset in {agent_reset_time:.2f}ms") - - # === TIMING: LLM call (task.decompose) === - llm_call_start = time.time() - logger.info(f"⏱️ [TIMING] Starting LLM decompose call...") result = task.decompose( self.task_agent, decompose_prompt, stream_callback=stream_callback ) - llm_call_time = (time.time() - llm_call_start) * 1000 - logger.info(f"⏱️ [TIMING] LLM decompose call returned in {llm_call_time:.2f}ms (streaming={isinstance(result, Generator)})") if isinstance(result, Generator): def streaming_with_dependencies(): @@ -254,10 +200,7 @@ class Workforce(BaseWorkforce): Returns: List[Task]: The decomposed subtasks or the original task """ - # === TIMING: handle_decompose_append_task start === - handle_start = time.time() - logger.info(f"⏱️ [TIMING] handle_decompose_append_task started") - logger.info(f"[DECOMPOSE] handle_decompose_append_task CALLED, task_id={task.id}, reset={reset}") + logger.debug(f"[DECOMPOSE] handle_decompose_append_task called, task_id={task.id}, reset={reset}") if not validate_task_content(task.content, task.id): task.state = TaskState.FAILED @@ -269,31 +212,20 @@ class Workforce(BaseWorkforce): return [task] if reset and self._state != WorkforceState.RUNNING: - logger.info(f"[DECOMPOSE] Resetting workforce (reset={reset}, state={self._state.name})") self.reset() - logger.info("[DECOMPOSE] Workforce reset complete") self._task = task task.state = TaskState.FAILED if coordinator_context: - logger.info(f"[DECOMPOSE] Adding coordinator context to task") original_content = task.content - task_with_context = coordinator_context - if coordinator_context: - task_with_context += "\n=== CURRENT TASK ===\n" - task_with_context += original_content + task_with_context = coordinator_context + "\n=== CURRENT TASK ===\n" + original_content task.content = task_with_context - - logger.info(f"[DECOMPOSE] Calling _decompose_task with context") subtasks_result = self._decompose_task(task, stream_callback=on_stream_text) - task.content = original_content else: - logger.info(f"[DECOMPOSE] Calling _decompose_task without context") subtasks_result = self._decompose_task(task, stream_callback=on_stream_text) - logger.info(f"[DECOMPOSE] _decompose_task returned, processing results") if isinstance(subtasks_result, Generator): subtasks = [] for new_tasks in subtasks_result: @@ -303,18 +235,15 @@ class Workforce(BaseWorkforce): on_stream_batch(new_tasks, False) except Exception as e: logger.warning(f"Streaming callback failed: {e}") - logger.info(f"[DECOMPOSE] Collected {len(subtasks)} subtasks from generator") # After consuming the generator, check task.subtasks for final result as fallback if not subtasks and task.subtasks: subtasks = task.subtasks else: subtasks = subtasks_result - logger.info(f"[DECOMPOSE] Got {len(subtasks) if subtasks else 0} subtasks directly") if subtasks: self._pending_tasks.extendleft(reversed(subtasks)) - logger.info(f"[DECOMPOSE] ✅ Appended {len(subtasks)} subtasks to pending tasks") if not subtasks: logger.warning(f"[DECOMPOSE] No subtasks returned, creating fallback task") @@ -325,7 +254,6 @@ class Workforce(BaseWorkforce): ) task.subtasks = [fallback_task] subtasks = [fallback_task] - logger.info(f"[DECOMPOSE] Created fallback task: {fallback_task.id}") if on_stream_batch: try: @@ -333,10 +261,7 @@ class Workforce(BaseWorkforce): except Exception as e: logger.warning(f"Final streaming callback failed: {e}") - # === TIMING: handle_decompose_append_task complete === - handle_total_time = (time.time() - handle_start) * 1000 - logger.info(f"⏱️ [TIMING] handle_decompose_append_task completed in {handle_total_time:.2f}ms, returned {len(subtasks)} subtasks") - + logger.debug(f"[DECOMPOSE] handle_decompose_append_task completed, returned {len(subtasks)} subtasks") return subtasks def _get_agent_id_from_node_id(self, node_id: str) -> str | None: @@ -453,32 +378,23 @@ class Workforce(BaseWorkforce): pool_max_size: int = DEFAULT_WORKER_POOL_SIZE, enable_workflow_memory: bool = False, ) -> BaseWorkforce: - import time as time_module - add_worker_start = time_module.time() - if self._state == WorkforceState.RUNNING: raise RuntimeError("Cannot add workers while workforce is running. Pause the workforce first.") # Validate worker agent compatibility - t0 = time_module.time() self._validate_agent_compatibility(worker, "Worker agent") - validate_time = (time_module.time() - t0) * 1000 # Ensure the worker agent shares this workforce's pause control - t0 = time_module.time() self._attach_pause_event_to_agent(worker) - attach_time = (time_module.time() - t0) * 1000 - t0 = time_module.time() worker_node = SingleAgentWorker( description=description, worker=worker, pool_max_size=pool_max_size, use_structured_output_handler=self.use_structured_output_handler, - context_utility=None, # Will be set during save/load operations + context_utility=None, enable_workflow_memory=enable_workflow_memory, ) - create_node_time = (time_module.time() - t0) * 1000 self._children.append(worker_node) # If we have a channel set up, set it for the new worker @@ -486,9 +402,7 @@ class Workforce(BaseWorkforce): worker_node.set_channel(self._channel) # If workforce is paused, start the worker's listening task - t0 = time_module.time() self._start_child_node_when_paused(worker_node.start()) - start_child_time = (time_module.time() - t0) * 1000 # Use proper CAMEL pattern for metrics logging metrics_callbacks = [cb for cb in self._callbacks if isinstance(cb, WorkforceMetrics)] @@ -500,8 +414,6 @@ class Workforce(BaseWorkforce): ) metrics_callbacks[0].log_worker_created(event) - total_time = (time_module.time() - add_worker_start) * 1000 - logger.info(f"⏱️ [TIMING] add_single_agent_worker: {total_time:.2f}ms (validate={validate_time:.2f}ms, attach={attach_time:.2f}ms, create_node={create_node_time:.2f}ms, start_child={start_child_time:.2f}ms) for {description[:30]}...") return self async def _handle_completed_task(self, task: Task) -> None: From 1d3999ea9b903400534ba70311e6eb6840b02972 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 07:12:04 +0800 Subject: [PATCH 29/63] chore: add linux building to build view --- .github/workflows/build-view.yml | 48 ++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-view.yml b/.github/workflows/build-view.yml index 3546e9fe..67f6cc44 100644 --- a/.github/workflows/build-view.yml +++ b/.github/workflows/build-view.yml @@ -20,6 +20,8 @@ jobs: arch: x64 - os: windows-latest arch: x64 + - os: ubuntu-latest + arch: x64 steps: - name: Checkout Code @@ -46,6 +48,13 @@ jobs: - name: Install Dependencies run: npm install + # Install libfuse2 for Linux AppImage builds + - name: Install libfuse2 (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y libfuse2 + # Step for macOS builds with signing - name: Build Release Files (macOS with signing) if: runner.os == 'macOS' @@ -78,6 +87,19 @@ jobs: VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} USE_NPM_INSTALL_BUN: 'true' + # Step for Linux builds + - name: Build Release Files (Linux) + if: runner.os == 'Linux' + timeout-minutes: 90 + run: npm run build:linux + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} + VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} + VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} + VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} + USE_NPM_INSTALL_BUN: 'true' + - name: Upload Artifact (macOS - dmg only) if: runner.os == 'macOS' uses: actions/upload-artifact@v6 @@ -95,13 +117,22 @@ jobs: path: | release/*.exe retention-days: 5 + + - name: Upload Artifact (Linux - AppImage only) + if: runner.os == 'Linux' + uses: actions/upload-artifact@v6 + with: + name: release-${{ matrix.os }}-${{ matrix.arch }} + path: | + release/*.AppImage + retention-days: 5 merge-release: needs: build runs-on: ubuntu-latest steps: - name: Create directories run: | - mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 + mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 release/linux-x64 # Download all artifacts with correct names - name: Download mac-x64 artifact @@ -122,7 +153,13 @@ jobs: name: release-windows-latest-x64 path: temp-win-x64 - # Move only dmg files for macOS and exe files for Windows + - name: Download linux-x64 artifact + uses: actions/download-artifact@v7 + with: + name: release-ubuntu-latest-x64 + path: temp-linux-x64 + + # Move only dmg files for macOS, exe files for Windows, and AppImage for Linux - name: Move files to clean folders shell: bash run: | @@ -146,3 +183,10 @@ jobs: else find temp-win-x64 -name "*.exe" -exec mv {} release/win-x64/ \; || true fi + + # linux-x64 - only move AppImage files + if [ -d "temp-linux-x64/release" ]; then + find temp-linux-x64/release -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true + else + find temp-linux-x64 -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true + fi From 645591bef5694e2cd97fb4f5075dd03cd0e0870c Mon Sep 17 00:00:00 2001 From: puzhen <1303385763@qq.com> Date: Mon, 19 Jan 2026 23:19:11 +0000 Subject: [PATCH 30/63] fix potential bug --- backend/app/service/chat_service.py | 6 ++++-- backend/app/utils/agent.py | 19 +++++++++++++++---- backend/app/utils/workforce.py | 1 - 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/backend/app/service/chat_service.py b/backend/app/service/chat_service.py index 28205e73..e6e6918f 100644 --- a/backend/app/service/chat_service.py +++ b/backend/app/service/chat_service.py @@ -1471,9 +1471,11 @@ The current date is {datetime.date.today()}. For any date-related tasks, you MUS ) except Exception as e: logger.error(f"Failed to create agents in parallel: {e}", exc_info=True) - # Clear event loop reference on failure - set_main_event_loop(None) raise + finally: + # Always clear event loop reference after parallel agent creation completes + # This prevents stale references and potential cross-request interference + set_main_event_loop(None) # Unpack results ( diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index 070d188b..d9f16227 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -3,7 +3,7 @@ import contextvars import json import os import platform -from threading import Event +from threading import Event, Lock import traceback from typing import Any, Callable, Dict, List, Tuple import uuid @@ -15,15 +15,23 @@ _main_event_loop_var: contextvars.ContextVar[asyncio.AbstractEventLoop | None] = '_main_event_loop', default=None ) +# Global fallback for main event loop reference +# Used when contextvars don't propagate to worker threads (e.g., asyncio.to_thread) +_GLOBAL_MAIN_LOOP: asyncio.AbstractEventLoop | None = None +_GLOBAL_MAIN_LOOP_LOCK = Lock() + def set_main_event_loop(loop: asyncio.AbstractEventLoop | None): """Set the main event loop reference for thread-safe task scheduling. This should be called from the main async context before spawning threads - that need to schedule async tasks. Uses contextvars to ensure thread-safety - across concurrent requests. + that need to schedule async tasks. Uses both contextvars (for request isolation) + and a global fallback (for thread pool workers where contextvars may not propagate). """ + global _GLOBAL_MAIN_LOOP _main_event_loop_var.set(loop) + with _GLOBAL_MAIN_LOOP_LOCK: + _GLOBAL_MAIN_LOOP = loop def _schedule_async_task(coro): @@ -38,8 +46,11 @@ def _schedule_async_task(coro): loop.create_task(coro) except RuntimeError: # No running loop in this thread (we're in a worker thread) - # Use the stored main loop reference from contextvars + # First try contextvars, then fallback to global reference main_loop = _main_event_loop_var.get() + if main_loop is None: + with _GLOBAL_MAIN_LOOP_LOCK: + main_loop = _GLOBAL_MAIN_LOOP if main_loop is not None and main_loop.is_running(): asyncio.run_coroutine_threadsafe(coro, main_loop) else: diff --git a/backend/app/utils/workforce.py b/backend/app/utils/workforce.py index db2f4fa9..0d17b965 100644 --- a/backend/app/utils/workforce.py +++ b/backend/app/utils/workforce.py @@ -1,5 +1,4 @@ import asyncio -import time from typing import Generator, List, Optional from camel.agents import ChatAgent from camel.societies.workforce.workforce import ( From 8ec82050ed80a9f6c78803602e5945ac333c03c3 Mon Sep 17 00:00:00 2001 From: puzhen <1303385763@qq.com> Date: Mon, 19 Jan 2026 23:31:43 +0000 Subject: [PATCH 31/63] optimize --- backend/app/controller/chat_controller.py | 72 +++++++++++-------- backend/app/service/task.py | 14 +++- backend/app/utils/toolkit/terminal_toolkit.py | 59 ++++++++------- 3 files changed, 91 insertions(+), 54 deletions(-) diff --git a/backend/app/controller/chat_controller.py b/backend/app/controller/chat_controller.py index 46c4f8bb..09a8f7c9 100644 --- a/backend/app/controller/chat_controller.py +++ b/backend/app/controller/chat_controller.py @@ -23,7 +23,8 @@ from app.service.task import ( get_or_create_task_lock, get_task_lock, set_current_task_id, - delete_task_lock + delete_task_lock, + task_locks, ) from app.component.environment import set_user_env_path from app.utils.workforce import Workforce @@ -38,9 +39,40 @@ chat_logger = traceroot.get_logger("chat_controller") # SSE timeout configuration (30 minutes in seconds) SSE_TIMEOUT_SECONDS = 30 * 60 -async def timeout_stream_wrapper(stream_generator, timeout_seconds: int = SSE_TIMEOUT_SECONDS, task_lock = None): + +async def _cleanup_task_lock_safe(task_lock, reason: str) -> bool: + """Safely cleanup task lock with existence check. + + Args: + task_lock: The task lock to cleanup + reason: Reason for cleanup (for logging) + + Returns: + True if cleanup was performed, False otherwise """ - Wraps a stream generator with timeout handling. + if not task_lock: + return False + + # Check if task_lock still exists before attempting cleanup + if task_lock.id not in task_locks: + chat_logger.debug(f"[{reason}] Task lock already removed, skipping cleanup", + extra={"task_id": task_lock.id}) + return False + + try: + task_lock.status = Status.done + await delete_task_lock(task_lock.id) + chat_logger.info(f"[{reason}] Task lock cleanup completed", + extra={"task_id": task_lock.id}) + return True + except Exception as e: + chat_logger.error(f"[{reason}] Failed to cleanup task lock", + extra={"task_id": task_lock.id, "error": str(e)}, exc_info=True) + return False + + +async def timeout_stream_wrapper(stream_generator, timeout_seconds: int = SSE_TIMEOUT_SECONDS, task_lock=None): + """Wraps a stream generator with timeout handling. Closes the SSE connection if no data is received within the timeout period. Triggers cleanup if timeout occurs to prevent resource leaks. @@ -59,40 +91,24 @@ async def timeout_stream_wrapper(stream_generator, timeout_seconds: int = SSE_TI last_data_time = time.time() yield data except asyncio.TimeoutError: - chat_logger.warning(f"SSE timeout: No data received for {timeout_seconds} seconds, closing connection") + chat_logger.warning("SSE timeout: No data received, closing connection", + extra={"timeout_seconds": timeout_seconds}) yield sse_json("error", {"message": f"Connection timeout: No data received for {timeout_seconds // 60} minutes"}) - - # Trigger cleanup to prevent resource leaks - if task_lock: - try: - task_lock.status = Status.done - await delete_task_lock(task_lock.id) - cleanup_triggered = True - except Exception as cleanup_error: - chat_logger.error(f"[TIMEOUT-CLEANUP] Failed to cleanup task lock: {cleanup_error}", exc_info=True) + cleanup_triggered = await _cleanup_task_lock_safe(task_lock, "TIMEOUT") break except StopAsyncIteration: break except asyncio.CancelledError: chat_logger.info("[STREAM-CANCELLED] Stream cancelled, triggering cleanup") - # Trigger cleanup on cancellation - if task_lock and not cleanup_triggered: - try: - task_lock.status = Status.done - await delete_task_lock(task_lock.id) - except Exception as cleanup_error: - chat_logger.error(f"[STREAM-CANCELLED] Failed to cleanup: {cleanup_error}") + if not cleanup_triggered: + await _cleanup_task_lock_safe(task_lock, "CANCELLED") raise except Exception as e: - chat_logger.error(f"[STREAM-ERROR] Unexpected error in stream wrapper: {e}", exc_info=True) - # Trigger cleanup on unexpected errors - if task_lock and not cleanup_triggered: - try: - task_lock.status = Status.done - await delete_task_lock(task_lock.id) - except Exception as cleanup_error: - chat_logger.error(f"[STREAM-ERROR] Failed to cleanup: {cleanup_error}") + chat_logger.error("[STREAM-ERROR] Unexpected error in stream wrapper", + extra={"error": str(e)}, exc_info=True) + if not cleanup_triggered: + await _cleanup_task_lock_safe(task_lock, "ERROR") raise diff --git a/backend/app/service/task.py b/backend/app/service/task.py index e512395a..1d9bb76b 100644 --- a/backend/app/service/task.py +++ b/backend/app/service/task.py @@ -364,13 +364,23 @@ class TaskLock: def register_toolkit(self, toolkit: Any) -> None: """Register a toolkit for cleanup when task ends. - + This is used to track toolkits that create resources (like venvs) that should be cleaned up when the task is complete. + + Note: Duplicate registrations of the same toolkit instance are ignored. """ + # Prevent duplicate registration of the same toolkit instance + if any(t is toolkit for t in self.registered_toolkits): + logger.debug("Toolkit already registered, skipping", extra={ + "task_id": self.id, + "toolkit": type(toolkit).__name__ + }) + return + self.registered_toolkits.append(toolkit) logger.debug("Toolkit registered for cleanup", extra={ - "task_id": self.id, + "task_id": self.id, "toolkit": type(toolkit).__name__, "total_registered": len(self.registered_toolkits) }) diff --git a/backend/app/utils/toolkit/terminal_toolkit.py b/backend/app/utils/toolkit/terminal_toolkit.py index 53a02731..91cfd593 100644 --- a/backend/app/utils/toolkit/terminal_toolkit.py +++ b/backend/app/utils/toolkit/terminal_toolkit.py @@ -1,6 +1,7 @@ import asyncio import logging import os +import shutil import threading import time from concurrent.futures import ThreadPoolExecutor @@ -178,36 +179,46 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): def cleanup(self, remove_venv: bool = True): """Clean up all active sessions and optionally remove the virtual environment. - + Args: remove_venv: If True, removes the .venv or .initial_env folder created by this toolkit. Defaults to True to prevent disk bloat. """ # First call parent cleanup to kill all shell sessions super().cleanup() - - if remove_venv: - import shutil - - # Remove cloned env (.venv) if it exists - if self.cloned_env_path and os.path.exists(self.cloned_env_path): - try: - shutil.rmtree(self.cloned_env_path) - logger.info(f"Removed cloned venv: {self.cloned_env_path}", extra={ - "api_task_id": self.api_task_id - }) - except Exception as e: - logger.warning(f"Failed to remove cloned venv {self.cloned_env_path}: {e}") - - # Remove initial env (.initial_env) if it exists - if self.initial_env_path and os.path.exists(self.initial_env_path): - try: - shutil.rmtree(self.initial_env_path) - logger.info(f"Removed initial env: {self.initial_env_path}", extra={ - "api_task_id": self.api_task_id - }) - except Exception as e: - logger.warning(f"Failed to remove initial env {self.initial_env_path}: {e}") + + if not remove_venv: + return + + # Remove cloned env (.venv) if it exists + if self.cloned_env_path and os.path.exists(self.cloned_env_path): + try: + shutil.rmtree(self.cloned_env_path) + logger.info("Removed cloned venv", extra={ + "api_task_id": self.api_task_id, + "path": self.cloned_env_path + }) + except Exception as e: + logger.warning("Failed to remove cloned venv", extra={ + "api_task_id": self.api_task_id, + "path": self.cloned_env_path, + "error": str(e) + }) + + # Remove initial env (.initial_env) if it exists + if self.initial_env_path and os.path.exists(self.initial_env_path): + try: + shutil.rmtree(self.initial_env_path) + logger.info("Removed initial env", extra={ + "api_task_id": self.api_task_id, + "path": self.initial_env_path + }) + except Exception as e: + logger.warning("Failed to remove initial env", extra={ + "api_task_id": self.api_task_id, + "path": self.initial_env_path, + "error": str(e) + }) @classmethod def shutdown(cls): From aee850ffda4cdd635e9485a09e1b94dbcd7ca24c Mon Sep 17 00:00:00 2001 From: leonace924 Date: Tue, 20 Jan 2026 00:33:00 +0100 Subject: [PATCH 32/63] Use unique tool ID as fallback instead of static 'Unknown Tool' string --- src/components/AddWorker/ToolSelect.tsx | 2 +- src/components/AddWorker/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AddWorker/ToolSelect.tsx b/src/components/AddWorker/ToolSelect.tsx index d2be3cd5..727aa6bf 100644 --- a/src/components/AddWorker/ToolSelect.tsx +++ b/src/components/AddWorker/ToolSelect.tsx @@ -630,7 +630,7 @@ const ToolSelect = forwardRef< key={item.id + item.key + (item.isLocal + "")} className="h-5 bg-button-tertiery-fill-default flex items-center gap-1 w-auto flex-shrink-0 px-xs" > - {item.name || item.mcp_name || item.key || "Unknown Tool"} + {item.name || item.mcp_name || item.key || `tool_${item.id}`}
tool.name || tool.mcp_name || tool.key || "Unknown Tool")], + tools: [...selectedTools.map((tool) => tool.name || tool.mcp_name || tool.key || `tool_${tool.id}`)], activeWebviewIds: [], workerInfo: { name: workerName, From f97fc33b0946a80ed78b837dd90fdddedac872ec Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 07:36:59 +0800 Subject: [PATCH 33/63] chore: update builder setting --- electron-builder.json | 1 - 1 file changed, 1 deletion(-) diff --git a/electron-builder.json b/electron-builder.json index ef5630cb..0ff93ab7 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -67,7 +67,6 @@ } }, "win": { - "certificateFile": null, "icon": "build/icon.ico", "artifactName": "${productName}.Setup.${version}.exe", "target": [ From e385532dea24d717948cd88016478dd11a755f08 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 08:02:46 +0800 Subject: [PATCH 34/63] enhance: Chore/optimize workforce construct PR970 --- backend/app/controller/chat_controller.py | 3 - backend/app/service/chat_service.py | 171 ++++------------------ backend/app/utils/workforce.py | 1 + 3 files changed, 28 insertions(+), 147 deletions(-) diff --git a/backend/app/controller/chat_controller.py b/backend/app/controller/chat_controller.py index 09a8f7c9..b3aef085 100644 --- a/backend/app/controller/chat_controller.py +++ b/backend/app/controller/chat_controller.py @@ -115,15 +115,12 @@ async def timeout_stream_wrapper(stream_generator, timeout_seconds: int = SSE_TI @router.post("/chat", name="start chat") @traceroot.trace() async def post(data: Chat, request: Request): - request_start_time = time.time() chat_logger.info( "Starting new chat session", extra={"project_id": data.project_id, "task_id": data.task_id, "user": data.email} ) task_lock = get_or_create_task_lock(data.project_id) - # Store request start time in task_lock for downstream timing - task_lock.request_start_time = request_start_time # Set user-specific environment path for this thread set_user_env_path(data.env_path) diff --git a/backend/app/service/chat_service.py b/backend/app/service/chat_service.py index e6e6918f..e37f9aa2 100644 --- a/backend/app/service/chat_service.py +++ b/backend/app/service/chat_service.py @@ -238,18 +238,9 @@ def build_context_for_workforce(task_lock: TaskLock, options: Chat) -> str: @sync_step @traceroot.trace() async def step_solve(options: Chat, request: Request, task_lock: TaskLock): - import time as time_module - - # === TIMING: step_solve started === - step_solve_start = time_module.time() - request_start_time = getattr(task_lock, 'request_start_time', step_solve_start) - time_since_request = (step_solve_start - request_start_time) * 1000 - logger.info(f"⏱️ [TIMING] step_solve started, {time_since_request:.2f}ms since request received") - start_event_loop = True - # === TIMING: Task lock initialization === - init_start = time_module.time() + # Initialize task_lock attributes if not hasattr(task_lock, 'conversation_history'): task_lock.conversation_history = [] if not hasattr(task_lock, 'last_task_result'): @@ -258,24 +249,19 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): task_lock.question_agent = None if not hasattr(task_lock, 'summary_generated'): task_lock.summary_generated = False - init_time = (time_module.time() - init_start) * 1000 - logger.info(f"⏱️ [TIMING] Task lock attrs initialized in {init_time:.2f}ms") # Create or reuse persistent question_agent - # === TIMING: question_agent creation === - question_agent_start = time_module.time() if task_lock.question_agent is None: task_lock.question_agent = question_confirm_agent(options) - question_agent_time = (time_module.time() - question_agent_start) * 1000 - logger.info(f"⏱️ [TIMING] question_confirm_agent created in {question_agent_time:.2f}ms") else: - logger.info(f"Reusing existing question_agent with {len(task_lock.conversation_history)} history entries") + logger.debug(f"Reusing existing question_agent with {len(task_lock.conversation_history)} history entries") question_agent = task_lock.question_agent # Other variables camel_task = None workforce = None + mcp = None last_completed_task_result = "" # Track the last completed task result summary_task_content = "" # Track task summary loop_iteration = 0 @@ -312,11 +298,7 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): logger.info(f"[LIFECYCLE] Breaking out of step_solve loop due to client disconnect") break try: - # === TIMING: Waiting for queue item === - queue_wait_start = time_module.time() item = await task_lock.get_queue() - queue_wait_time = (time_module.time() - queue_wait_start) * 1000 - logger.info(f"⏱️ [TIMING] Got item from queue in {queue_wait_time:.2f}ms, action={item.action}") except Exception as e: logger.error("Error getting item from queue", extra={"project_id": options.project_id, "task_id": options.task_id, "error": str(e)}, exc_info=True) # Continue waiting instead of breaking on queue error @@ -352,25 +334,13 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): }) continue - # === TIMING: Complexity determination === - complexity_start = time_module.time() - time_since_request_to_complexity = (complexity_start - request_start_time) * 1000 - logger.info(f"⏱️ [TIMING] Starting complexity check, {time_since_request_to_complexity:.2f}ms since request") - - # Simplified logic: attachments mean workforce, otherwise let agent decide + # Determine task complexity: attachments mean workforce, otherwise let agent decide is_complex_task: bool if len(options.attaches) > 0: - # Questions with attachments always need workforce is_complex_task = True logger.info(f"[NEW-QUESTION] Has attachments, treating as complex task") - complexity_time = (time_module.time() - complexity_start) * 1000 - logger.info(f"⏱️ [TIMING] Complexity check (has attachments) completed in {complexity_time:.2f}ms") else: - logger.info(f"[NEW-QUESTION] Calling question_confirm to determine complexity") - question_confirm_start = time_module.time() is_complex_task = await question_confirm(question_agent, question, task_lock) - question_confirm_time = (time_module.time() - question_confirm_start) * 1000 - logger.info(f"⏱️ [TIMING] question_confirm completed in {question_confirm_time:.2f}ms, is_complex={is_complex_task}") logger.info(f"[NEW-QUESTION] question_confirm result: is_complex={is_complex_task}") if not is_complex_task: @@ -409,83 +379,36 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): except Exception as e: logger.error(f"Error cleaning up folder: {e}") else: - # === TIMING: Complex task processing === - complex_task_start = time_module.time() - time_since_request_to_complex = (complex_task_start - request_start_time) * 1000 - logger.info(f"⏱️ [TIMING] Complex task processing started, {time_since_request_to_complex:.2f}ms since request") - - logger.info(f"[NEW-QUESTION] 🔧 Complex task, creating workforce and decomposing") + logger.info(f"[NEW-QUESTION] Complex task, creating workforce and decomposing") # Update the sync_step with new task_id if hasattr(item, 'new_task_id') and item.new_task_id: set_current_task_id(options.project_id, item.new_task_id) - # Reset summary generation flag for new tasks to ensure proper summaries task_lock.summary_generated = False - logger.info("[NEW-QUESTION] Reset summary_generated flag for new task", extra={"project_id": options.project_id, "new_task_id": item.new_task_id}) - logger.info(f"[NEW-QUESTION] Sending 'confirmed' SSE to frontend") yield sse_json("confirmed", {"question": question}) - # === TIMING: Context building === - context_build_start = time_module.time() - logger.info(f"[NEW-QUESTION] Building context for coordinator") context_for_coordinator = build_context_for_workforce(task_lock, options) - context_build_time = (time_module.time() - context_build_start) * 1000 - logger.info(f"⏱️ [TIMING] Context building completed in {context_build_time:.2f}ms") - # Check if workforce exists - if so, reuse it (agents are preserved) - # Otherwise create new workforce + # Check if workforce exists - if so, reuse it; otherwise create new workforce if workforce is not None: - logger.info(f"[NEW-QUESTION] 🔄 Workforce exists (id={id(workforce)}), state={workforce._state.name}, _running={workforce._running}") - logger.info(f"[NEW-QUESTION] ✅ Reusing existing workforce with preserved agents") - # Workforce is already stopped from skip_task, ready for new decomposition + logger.debug(f"[NEW-QUESTION] Reusing existing workforce (id={id(workforce)})") else: - # === TIMING: Workforce construction === - workforce_construct_start = time_module.time() - logger.info(f"[NEW-QUESTION] 🏭 Creating NEW workforce instance (workforce=None)") + logger.info(f"[NEW-QUESTION] Creating NEW workforce instance") (workforce, mcp) = await construct_workforce(options) - workforce_construct_time = (time_module.time() - workforce_construct_start) * 1000 - logger.info(f"⏱️ [TIMING] Workforce construction completed in {workforce_construct_time:.2f}ms") - logger.info(f"[NEW-QUESTION] ✅ NEW Workforce instance created, id={id(workforce)}") for new_agent in options.new_agents: workforce.add_single_agent_worker( format_agent_description(new_agent), await new_agent_model(new_agent, options) ) task_lock.status = Status.confirmed - # === TIMING: Task creation === - task_create_start = time_module.time() + # Create camel_task for the question + clean_task_content = question + options.summary_prompt + camel_task = Task(content=clean_task_content, id=options.task_id) + if len(options.attaches) > 0: + camel_task.additional_info = {Path(file_path).name: file_path for file_path in options.attaches} - # If camel_task already exists (from previous paused task), add new question as subtask - # Otherwise, create a new camel_task - if camel_task is not None: - logger.info(f"[NEW-QUESTION] 🔄 camel_task exists (id={camel_task.id}), adding new question as context") - # Update the task content with new question - clean_task_content = question + options.summary_prompt - logger.info(f"[NEW-QUESTION] Updating existing camel_task content with new question") - # We keep the existing task structure but update content for new decomposition - camel_task = Task(content=clean_task_content, id=options.task_id) - if len(options.attaches) > 0: - camel_task.additional_info = {Path(file_path).name: file_path for file_path in options.attaches} - else: - clean_task_content = question + options.summary_prompt - logger.info(f"[NEW-QUESTION] Creating NEW camel_task with id={options.task_id}") - camel_task = Task(content=clean_task_content, id=options.task_id) - if len(options.attaches) > 0: - camel_task.additional_info = {Path(file_path).name: file_path for file_path in options.attaches} - - task_create_time = (time_module.time() - task_create_start) * 1000 - logger.info(f"⏱️ [TIMING] Task object created in {task_create_time:.2f}ms") - - # === TIMING: Task decomposition start === - decomposition_start = time_module.time() - time_since_request_to_decompose = (decomposition_start - request_start_time) * 1000 - logger.info(f"⏱️ [TIMING] Starting task decomposition, {time_since_request_to_decompose:.2f}ms since request") - # Store decomposition start time in task_lock for downstream tracking - task_lock.decomposition_start_time = decomposition_start - - # Stream decomposition in background so queue items (decompose_text) are processed immediately - logger.info(f"[NEW-QUESTION] 🧩 Starting task decomposition via workforce.eigent_make_sub_tasks") - stream_state = {"subtasks": [], "seen_ids": set(), "last_content": "", "first_token_logged": False} + # Stream decomposition in background + stream_state = {"subtasks": [], "seen_ids": set(), "last_content": ""} state_holder: dict[str, Any] = {"sub_tasks": [], "summary_task": ""} def on_stream_batch(new_tasks: list[Task], is_final: bool = False): @@ -496,8 +419,6 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): def on_stream_text(chunk): try: - # With task_agent using stream_accumulate=True, chunk.msg.content is accumulated content - # We need to calculate the delta to send only new content to frontend accumulated_content = chunk.msg.content if hasattr(chunk, 'msg') and chunk.msg else str(chunk) last_content = stream_state["last_content"] @@ -510,12 +431,6 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): stream_state["last_content"] = accumulated_content if delta_content: - # === TIMING: Log TTFT (Time to First Token) === - if not stream_state["first_token_logged"]: - stream_state["first_token_logged"] = True - ttft = (time_module.time() - task_lock.decomposition_start_time) * 1000 - logger.info(f"⏱️ [TIMING] 🚀 TTFT (Time to First Token): {ttft:.2f}ms - First streaming token received for task decomposition") - asyncio.run_coroutine_threadsafe( task_lock.put_queue( ActionDecomposeTextData( @@ -534,10 +449,6 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): async def run_decomposition(): nonlocal camel_task, summary_task_content try: - # === TIMING: LLM decomposition call === - llm_decompose_start = time_module.time() - decomposition_start_time = getattr(task_lock, 'decomposition_start_time', llm_decompose_start) - sub_tasks = await asyncio.to_thread( workforce.eigent_make_sub_tasks, camel_task, @@ -546,60 +457,44 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): on_stream_text, ) - llm_decompose_time = (time_module.time() - llm_decompose_start) * 1000 - total_decompose_time = (time_module.time() - decomposition_start_time) * 1000 - logger.info(f"⏱️ [TIMING] LLM decomposition completed in {llm_decompose_time:.2f}ms (total decompose phase: {total_decompose_time:.2f}ms)") - if stream_state["subtasks"]: sub_tasks = stream_state["subtasks"] state_holder["sub_tasks"] = sub_tasks - logger.info(f"[NEW-QUESTION] ✅ Task decomposed into {len(sub_tasks)} subtasks") + logger.info(f"Task decomposed into {len(sub_tasks)} subtasks") try: setattr(task_lock, "decompose_sub_tasks", sub_tasks) except Exception: pass - # === TIMING: Summary generation === - summary_start = time_module.time() - logger.info(f"[NEW-QUESTION] Generating task summary") + # Generate task summary summary_task_agent = task_summary_agent(options) try: summary_task_content = await asyncio.wait_for( summary_task(summary_task_agent, camel_task), timeout=10 ) - summary_time = (time_module.time() - summary_start) * 1000 task_lock.summary_generated = True - logger.info(f"⏱️ [TIMING] Summary generation completed in {summary_time:.2f}ms") - logger.info("[NEW-QUESTION] ✅ Summary generated successfully", extra={"project_id": options.project_id}) except asyncio.TimeoutError: logger.warning("summary_task timeout", extra={"project_id": options.project_id, "task_id": options.task_id}) task_lock.summary_generated = True - fallback_name = "Task" content_preview = camel_task.content if hasattr(camel_task, "content") else "" if content_preview is None: content_preview = "" - summary_task_content = ( - (content_preview[:80] + "...") if len(content_preview) > 80 else content_preview - ) - summary_task_content = f"{fallback_name}|{summary_task_content}" + summary_task_content = (content_preview[:80] + "...") if len(content_preview) > 80 else content_preview + summary_task_content = f"Task|{summary_task_content}" except Exception: task_lock.summary_generated = True - fallback_name = "Task" content_preview = camel_task.content if hasattr(camel_task, "content") else "" if content_preview is None: content_preview = "" - summary_task_content = ( - (content_preview[:80] + "...") if len(content_preview) > 80 else content_preview - ) - summary_task_content = f"{fallback_name}|{summary_task_content}" + summary_task_content = (content_preview[:80] + "...") if len(content_preview) > 80 else content_preview + summary_task_content = f"Task|{summary_task_content}" state_holder["summary_task"] = summary_task_content try: setattr(task_lock, "summary_task_content", summary_task_content) except Exception: pass - logger.info(f"[NEW-QUESTION] 📤 Sending to_sub_tasks SSE to frontend (task card)") - logger.info(f"[NEW-QUESTION] to_sub_tasks data: task_id={camel_task.id}, summary={summary_task_content[:50]}..., subtasks_count={len(camel_task.subtasks)}") + payload = { "project_id": options.project_id, "task_id": options.task_id, @@ -609,12 +504,6 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): "summary_task": summary_task_content, } await task_lock.put_queue(ActionDecomposeProgressData(data=payload)) - logger.info(f"[NEW-QUESTION] ✅ to_sub_tasks SSE sent") - - # === TIMING: Total time from request to decomposition complete === - request_start = getattr(task_lock, 'request_start_time', decomposition_start_time) - total_request_to_decompose = (time_module.time() - request_start) * 1000 - logger.info(f"⏱️ [TIMING] ===== TOTAL: Request → Decomposition Complete: {total_request_to_decompose:.2f}ms =====") except Exception as e: logger.error(f"Error in background decomposition: {e}", exc_info=True) @@ -854,9 +743,7 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): logger.info(f"[LIFECYCLE] Multi-turn: building context for workforce") context_for_multi_turn = build_context_for_workforce(task_lock, options) - logger.info(f"[LIFECYCLE] Multi-turn: calling workforce.handle_decompose_append_task for new task decomposition") - multi_turn_decompose_start = time_module.time() - stream_state = {"subtasks": [], "seen_ids": set(), "last_content": "", "first_token_logged": False, "start_time": multi_turn_decompose_start} + stream_state = {"subtasks": [], "seen_ids": set(), "last_content": ""} def on_stream_batch(new_tasks: list[Task], is_final: bool = False): fresh_tasks = [t for t in new_tasks if t.id not in stream_state["seen_ids"]] @@ -866,8 +753,6 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): def on_stream_text(chunk): try: - # With task_agent using stream_accumulate=True, chunk.msg.content is accumulated content - # We need to calculate the delta to send only new content to frontend accumulated_content = chunk.msg.content if hasattr(chunk, 'msg') and chunk.msg else str(chunk) last_content = stream_state["last_content"] @@ -879,12 +764,6 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): stream_state["last_content"] = accumulated_content if delta_content: - # === TIMING: Log TTFT (Time to First Token) for multi-turn === - if not stream_state["first_token_logged"]: - stream_state["first_token_logged"] = True - ttft = (time_module.time() - stream_state["start_time"]) * 1000 - logger.info(f"⏱️ [TIMING] 🚀 TTFT (Time to First Token): {ttft:.2f}ms - First streaming token received for multi-turn task decomposition") - asyncio.run_coroutine_threadsafe( task_lock.put_queue( ActionDecomposeTextData( @@ -987,6 +866,10 @@ async def step_solve(options: Chat, request: Request, task_lock: TaskLock): elif item.action == Action.search_mcp: yield sse_json("search_mcp", item.data) elif item.action == Action.install_mcp: + if mcp is None: + logger.error(f"Cannot install MCP: mcp agent not initialized for project {options.project_id}") + yield sse_json("error", {"message": "MCP agent not initialized. Please start a complex task first."}) + continue task = asyncio.create_task(install_mcp(mcp, item)) task_lock.add_background_task(task) elif item.action == Action.terminal: diff --git a/backend/app/utils/workforce.py b/backend/app/utils/workforce.py index 0d17b965..362eb0d4 100644 --- a/backend/app/utils/workforce.py +++ b/backend/app/utils/workforce.py @@ -355,6 +355,7 @@ class Workforce(BaseWorkforce): f"Task {task.id} will not be properly tracked on frontend. " f"Available workers: {[c.node_id for c in self._children if hasattr(c, 'node_id')]}" ) + else: await task_lock.put_queue( ActionAssignTaskData( action=Action.assign_task, From b49b3c50a7e92c9796aa4561a72314cc0a4bb212 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 08:07:22 +0800 Subject: [PATCH 35/63] add install_dependencies back --- backend/app/utils/toolkit/terminal_toolkit.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/app/utils/toolkit/terminal_toolkit.py b/backend/app/utils/toolkit/terminal_toolkit.py index 91cfd593..d3ca259d 100644 --- a/backend/app/utils/toolkit/terminal_toolkit.py +++ b/backend/app/utils/toolkit/terminal_toolkit.py @@ -64,6 +64,13 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): safe_mode=safe_mode, allowed_commands=allowed_commands, clone_current_env=clone_current_env, + install_dependencies=[ + "pandas", + "numpy", + "matplotlib", + "requests", + "openpyxl", + ], ) # Auto-register with TaskLock for cleanup when task ends From f45be7d7b78eb086db2700506654b854a9e8ab14 Mon Sep 17 00:00:00 2001 From: puzhen <1303385763@qq.com> Date: Tue, 20 Jan 2026 00:15:20 +0000 Subject: [PATCH 36/63] fix agent order --- src/components/WorkFlow/index.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/WorkFlow/index.tsx b/src/components/WorkFlow/index.tsx index f23c7975..806760a6 100644 --- a/src/components/WorkFlow/index.tsx +++ b/src/components/WorkFlow/index.tsx @@ -233,11 +233,21 @@ export default function Workflow({ // console.log("workerList ", workerList); setNodes((prev: CustomNode[]) => { if (!taskAssigning) return prev; + // Agents not yet in taskAssigning (from baseWorker or workerList) const base = [...baseWorker, ...workerList].filter( (worker) => !taskAssigning.find((agent) => agent.type === worker.type) ); let targetData = [...prev]; - taskAssigning = [...base, ...taskAssigning]; + // Merge all agents + const allAgents = [...taskAssigning, ...base]; + // Sort: agents with tasks come first, then agents without tasks + taskAssigning = allAgents.sort((a, b) => { + const aHasTasks = a.tasks && a.tasks.length > 0; + const bHasTasks = b.tasks && b.tasks.length > 0; + if (aHasTasks && !bHasTasks) return -1; + if (!aHasTasks && bHasTasks) return 1; + return 0; // Keep original order for agents with same task status + }); // taskAssigning = taskAssigning.filter((agent) => agent.tasks.length > 0); targetData = taskAssigning.map((agent, index) => { const node = targetData.find((node) => node.id === agent.agent_id); From b1863358459c3391481fb3c450ac2790959b00f1 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 08:19:58 +0800 Subject: [PATCH 37/63] use instead of empty str --- src/components/AddWorker/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddWorker/index.tsx b/src/components/AddWorker/index.tsx index f824903a..d5321424 100644 --- a/src/components/AddWorker/index.tsx +++ b/src/components/AddWorker/index.tsx @@ -310,7 +310,7 @@ export function AddWorker({ type: workerName as AgentNameType, log: [], tools: [ - ...selectedTools.map((tool) => tool?.key || tool?.mcp_name || ""), + ...selectedTools.map((tool) => tool.name || tool.mcp_name || tool.key || `tool_${tool.id}`), ], activeWebviewIds: [], workerInfo: { From 15c40f7a08d014580ef73dc815242dd3b21e72a2 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 08:29:14 +0800 Subject: [PATCH 38/63] minor update --- src/components/WorkFlow/index.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/WorkFlow/index.tsx b/src/components/WorkFlow/index.tsx index 806760a6..b5f6ea46 100644 --- a/src/components/WorkFlow/index.tsx +++ b/src/components/WorkFlow/index.tsx @@ -241,15 +241,14 @@ export default function Workflow({ // Merge all agents const allAgents = [...taskAssigning, ...base]; // Sort: agents with tasks come first, then agents without tasks - taskAssigning = allAgents.sort((a, b) => { + const sortedAgents = allAgents.sort((a, b) => { const aHasTasks = a.tasks && a.tasks.length > 0; const bHasTasks = b.tasks && b.tasks.length > 0; if (aHasTasks && !bHasTasks) return -1; if (!aHasTasks && bHasTasks) return 1; - return 0; // Keep original order for agents with same task status + return 0; }); - // taskAssigning = taskAssigning.filter((agent) => agent.tasks.length > 0); - targetData = taskAssigning.map((agent, index) => { + targetData = sortedAgents.map((agent, index) => { const node = targetData.find((node) => node.id === agent.agent_id); if (node) { return { From 6dba7e06d499fb2530a4655680f7a9a96920ac8e Mon Sep 17 00:00:00 2001 From: puzhen <1303385763@qq.com> Date: Tue, 20 Jan 2026 00:35:26 +0000 Subject: [PATCH 39/63] update readme --- README.md | 13 +++++++++++++ README_CN.md | 13 +++++++++++++ README_JA.md | 13 +++++++++++++ README_PT-BR.md | 13 +++++++++++++ 4 files changed, 52 insertions(+) diff --git a/README.md b/README.md index b2b627b8..877e0525 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,19 @@ npm run dev > Note: This mode connects to Eigent cloud services and requires account registration. For a fully standalone experience, use [Local Deployment](#-local-deployment-recommended) instead. +#### Updating Dependencies + +After pulling new code (`git pull`), update both frontend and backend dependencies: + +```bash +# 1. Update frontend dependencies (in project root) +npm install + +# 2. Update backend/Python dependencies (in backend directory) +cd backend +uv sync +``` + ### 🏢 Enterprise For organizations requiring maximum security, customization, and control: diff --git a/README_CN.md b/README_CN.md index e71d3054..c2c90f16 100644 --- a/README_CN.md +++ b/README_CN.md @@ -124,6 +124,19 @@ npm run dev #### 3. 本地开发(使用完全和云端服务分离的版本) [server/README_CN.md](./server/README_CN.md) +#### 4. 更新依赖 + +拉取新代码(`git pull`)后,需要分别更新前端和后端依赖: + +```bash +# 1. 更新前端依赖(在项目根目录) +npm install + +# 2. 更新后端/Python 依赖(在 backend 目录) +cd backend +uv sync +``` + ### 🏢 企业版 适合需要最高安全性、定制化和控制的组织: diff --git a/README_JA.md b/README_JA.md index 93079536..08f73105 100644 --- a/README_JA.md +++ b/README_JA.md @@ -114,6 +114,19 @@ npm run dev > 注:このモードはEigentクラウドサービスに接続し、アカウント登録が必要です。完全にスタンドアロンで使用する場合は、代わりに[ローカルデプロイメント](#-ローカルデプロイメント推奨)を使用してください。 +#### 依存関係の更新 + +新しいコードを取得(`git pull`)した後、フロントエンドとバックエンドの両方の依存関係を更新します: + +```bash +# 1. フロントエンド依存関係を更新(プロジェクトルートで) +npm install + +# 2. バックエンド/Python依存関係を更新(backendディレクトリで) +cd backend +uv sync +``` + ### 🏢 エンタープライズ 最大限のセキュリティ、カスタマイズ、制御を必要とする組織向け: diff --git a/README_PT-BR.md b/README_PT-BR.md index e727366e..a26c2a2a 100644 --- a/README_PT-BR.md +++ b/README_PT-BR.md @@ -115,6 +115,19 @@ npm run dev > Nota: Este modo se conecta aos serviços em nuvem do Eigent e requer registro de conta. Para uma experiência totalmente independente, utilize a [Implantação Local](#-implantação-local-recomendado) em vez disso. +#### Atualizando Dependências + +Após baixar novo código (`git pull`), atualize as dependências do frontend e do backend: + +```bash +# 1. Atualizar dependências do frontend (no diretório raiz do projeto) +npm install + +# 2. Atualizar dependências do backend/Python (no diretório backend) +cd backend +uv sync +``` + ### 🏢 Empresarial Para organizações que requerem máxima segurança, personalização e controle: From 315d0c9e89e48d1ec57f8144fefb65bd4db6d1a2 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 08:56:50 +0800 Subject: [PATCH 40/63] fix: terminal toolkit env setting --- backend/app/utils/toolkit/terminal_toolkit.py | 159 +++++++++++++++--- electron/main/install-deps.ts | 134 +++++++++++++++ electron/main/utils/process.ts | 70 ++++++-- 3 files changed, 333 insertions(+), 30 deletions(-) diff --git a/backend/app/utils/toolkit/terminal_toolkit.py b/backend/app/utils/toolkit/terminal_toolkit.py index d3ca259d..1199ec4a 100644 --- a/backend/app/utils/toolkit/terminal_toolkit.py +++ b/backend/app/utils/toolkit/terminal_toolkit.py @@ -1,7 +1,9 @@ import asyncio import logging import os +import platform import shutil +import subprocess import threading import time from concurrent.futures import ThreadPoolExecutor @@ -17,6 +19,20 @@ from utils import traceroot_wrapper as traceroot logger = traceroot.get_logger("terminal_toolkit") +# App version - should match electron app version +# TODO: Consider getting this from a shared config +APP_VERSION = "0.0.80" + + +def get_terminal_base_venv_path() -> str: + """Get the path to the terminal base venv created during app installation.""" + return os.path.join( + os.path.expanduser("~"), + ".eigent", + "venvs", + f"terminal_base-{APP_VERSION}" + ) + @auto_listen_toolkit(BaseTerminalToolkit) class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): @@ -41,12 +57,14 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): if agent_name is not None: self.agent_name = agent_name if working_directory is None: - working_directory = env("file_save_path", os.path.expanduser("~/.eigent/terminal/")) + base_dir = env("file_save_path", os.path.expanduser("~/.eigent/terminal/")) + # Each agent gets its own subdirectory to avoid race conditions when + # multiple agents create .venv simultaneously during parallel initialization + working_directory = os.path.join(base_dir, self.agent_name) logger.debug(f"Initializing TerminalToolkit for agent={self.agent_name}", extra={ "api_task_id": api_task_id, "working_directory": working_directory, - "clone_current_env": clone_current_env }) if TerminalToolkit._thread_pool is None: @@ -63,16 +81,10 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): session_logs_dir=session_logs_dir, safe_mode=safe_mode, allowed_commands=allowed_commands, - clone_current_env=clone_current_env, - install_dependencies=[ - "pandas", - "numpy", - "matplotlib", - "requests", - "openpyxl", - ], + clone_current_env=True, + install_dependencies=[], ) - + # Auto-register with TaskLock for cleanup when task ends from app.service.task import get_task_lock_if_exists task_lock = get_task_lock_if_exists(api_task_id) @@ -83,6 +95,113 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): "working_directory": working_directory }) + def _setup_cloned_environment(self): + """Override to clone from terminal_base venv instead of current process venv. + + Creates a lightweight clone using symlinks to the terminal_base venv, + which contains pre-installed packages (pandas, numpy, matplotlib, etc.). + """ + self.cloned_env_path = os.path.join(self.working_dir, ".venv") + terminal_base_path = get_terminal_base_venv_path() + + # Check if terminal_base exists + if platform.system() == 'Windows': + base_python = os.path.join(terminal_base_path, "Scripts", "python.exe") + else: + base_python = os.path.join(terminal_base_path, "bin", "python") + + if not os.path.exists(base_python): + logger.warning( + f"Terminal base venv not found at {terminal_base_path}, " + "falling back to system Python" + ) + return + + # Check if cloned env already exists + if platform.system() == 'Windows': + cloned_python = os.path.join(self.cloned_env_path, "Scripts", "python.exe") + else: + cloned_python = os.path.join(self.cloned_env_path, "bin", "python") + + if os.path.exists(cloned_python): + logger.info(f"Using existing cloned environment: {self.cloned_env_path}") + self.python_executable = cloned_python + return + + logger.info(f"Cloning terminal_base venv to: {self.cloned_env_path}") + + try: + # Create the cloned venv directory + os.makedirs(self.cloned_env_path, exist_ok=True) + + # Clone using symlinks for efficiency + # We need to create proper venv structure with symlinks to terminal_base + self._clone_venv_with_symlinks(terminal_base_path, self.cloned_env_path) + + self.python_executable = cloned_python + logger.info(f"Successfully cloned environment to: {self.cloned_env_path}") + + except Exception as e: + logger.error(f"Failed to clone terminal_base venv: {e}", exc_info=True) + # Cleanup partial clone + if os.path.exists(self.cloned_env_path): + shutil.rmtree(self.cloned_env_path, ignore_errors=True) + logger.warning("Falling back to system Python") + + def _clone_venv_with_symlinks(self, source_venv: str, target_venv: str): + """Clone a venv using symlinks for efficiency. + + Only creates the minimum structure needed: pyvenv.cfg, bin/python, and lib symlink. + Activation scripts are not needed since we use python_executable directly. + """ + is_windows = platform.system() == 'Windows' + + # Read source pyvenv.cfg to get Python home + source_cfg = os.path.join(source_venv, "pyvenv.cfg") + python_home = None + + with open(source_cfg, 'r') as f: + for line in f: + if line.startswith('home = '): + python_home = line.split('=', 1)[1].strip() + break + + if not python_home: + raise RuntimeError(f"Could not determine Python home from {source_cfg}") + + # Copy pyvenv.cfg (simpler than recreating) + shutil.copy2(source_cfg, os.path.join(target_venv, "pyvenv.cfg")) + + if is_windows: + # Windows: copy executables from source + target_bin = os.path.join(target_venv, "Scripts") + os.makedirs(target_bin, exist_ok=True) + source_scripts = os.path.join(source_venv, "Scripts") + for exe in ["python.exe", "pythonw.exe"]: + src = os.path.join(source_scripts, exe) + if os.path.exists(src): + shutil.copy2(src, os.path.join(target_bin, exe)) + # Use directory junction for Lib (no admin rights needed, unlike symlink) + source_lib = os.path.join(source_venv, "Lib") + target_lib = os.path.join(target_venv, "Lib") + subprocess.run(["cmd", "/c", "mklink", "/J", target_lib, source_lib], + check=True, capture_output=True) + else: + # Unix: symlink python executable and lib directory + target_bin = os.path.join(target_venv, "bin") + os.makedirs(target_bin, exist_ok=True) + + # Symlink python to the base Python + python_exe = os.path.join(python_home, "python3") + if not os.path.exists(python_exe): + python_exe = os.path.join(python_home, "python") + os.symlink(python_exe, os.path.join(target_bin, "python")) + os.symlink("python", os.path.join(target_bin, "python3")) + + # Symlink lib directory + source_lib = os.path.join(source_venv, "lib") + os.symlink(source_lib, os.path.join(target_venv, "lib")) + def _write_to_log(self, log_file: str, content: str) -> None: r"""Write content to log file with optional ANSI stripping. @@ -198,32 +317,34 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): return # Remove cloned env (.venv) if it exists - if self.cloned_env_path and os.path.exists(self.cloned_env_path): + cloned_env_path = getattr(self, 'cloned_env_path', None) + if cloned_env_path and os.path.exists(cloned_env_path): try: - shutil.rmtree(self.cloned_env_path) + shutil.rmtree(cloned_env_path) logger.info("Removed cloned venv", extra={ "api_task_id": self.api_task_id, - "path": self.cloned_env_path + "path": cloned_env_path }) except Exception as e: logger.warning("Failed to remove cloned venv", extra={ "api_task_id": self.api_task_id, - "path": self.cloned_env_path, + "path": cloned_env_path, "error": str(e) }) # Remove initial env (.initial_env) if it exists - if self.initial_env_path and os.path.exists(self.initial_env_path): + initial_env_path = getattr(self, 'initial_env_path', None) + if initial_env_path and os.path.exists(initial_env_path): try: - shutil.rmtree(self.initial_env_path) + shutil.rmtree(initial_env_path) logger.info("Removed initial env", extra={ "api_task_id": self.api_task_id, - "path": self.initial_env_path + "path": initial_env_path }) except Exception as e: logger.warning("Failed to remove initial env", extra={ "api_task_id": self.api_task_id, - "path": self.initial_env_path, + "path": initial_env_path, "error": str(e) }) diff --git a/electron/main/install-deps.ts b/electron/main/install-deps.ts index daaebb0f..e5babcc7 100644 --- a/electron/main/install-deps.ts +++ b/electron/main/install-deps.ts @@ -8,10 +8,12 @@ import { getBinaryPath, getCachePath, getVenvPath, + getTerminalVenvPath, getUvEnv, cleanupOldVenvs, isBinaryExists, runInstallScript, + TERMINAL_BASE_PACKAGES, } from './utils/process'; import { spawn } from 'child_process'; import { safeMainWindowSend } from './utils/safeWebContentsSend'; @@ -482,6 +484,124 @@ const runInstall = (extraArgs: string[], version: string) => { }); }; +/** + * Install terminal base venv with common packages for terminal tasks. + * This is a lightweight venv separate from the backend venv. + */ +async function installTerminalBaseVenv(version: string): Promise { + const terminalVenvPath = getTerminalVenvPath(version); + const pythonPath = process.platform === 'win32' + ? path.join(terminalVenvPath, 'Scripts', 'python.exe') + : path.join(terminalVenvPath, 'bin', 'python'); + + // Check if terminal base venv already exists and is valid + if (fs.existsSync(pythonPath)) { + log.info('[DEPS INSTALL] Terminal base venv already exists, skipping creation'); + return { message: 'Terminal base venv already exists', success: true }; + } + + log.info('[DEPS INSTALL] Creating terminal base venv...'); + safeMainWindowSend('install-dependencies-log', { + type: 'stdout', + data: 'Creating terminal base environment...\n', + }); + + try { + // Create the venv using uv + await new Promise((resolve, reject) => { + const createVenv = spawn( + uv_path, + ['venv', '--python', '3.10', terminalVenvPath], + { + env: { + ...process.env, + UV_PYTHON_INSTALL_DIR: getCachePath('uv_python'), + }, + } + ); + + createVenv.stdout.on('data', (data) => { + log.info(`[DEPS INSTALL] terminal venv: ${data}`); + }); + + createVenv.stderr.on('data', (data) => { + log.info(`[DEPS INSTALL] terminal venv: ${data}`); + }); + + createVenv.on('close', (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`Failed to create terminal venv, exit code: ${code}`)); + } + }); + + createVenv.on('error', reject); + }); + + // Install base packages + log.info('[DEPS INSTALL] Installing terminal base packages...'); + safeMainWindowSend('install-dependencies-log', { + type: 'stdout', + data: `Installing packages: ${TERMINAL_BASE_PACKAGES.join(', ')}...\n`, + }); + + await new Promise((resolve, reject) => { + const installPkgs = spawn( + uv_path, + [ + 'pip', + 'install', + '--python', + pythonPath, + ...TERMINAL_BASE_PACKAGES, + ], + { + env: { + ...process.env, + UV_PYTHON_INSTALL_DIR: getCachePath('uv_python'), + }, + } + ); + + installPkgs.stdout.on('data', (data) => { + log.info(`[DEPS INSTALL] terminal packages: ${data}`); + safeMainWindowSend('install-dependencies-log', { + type: 'stdout', + data: data.toString(), + }); + }); + + installPkgs.stderr.on('data', (data) => { + log.info(`[DEPS INSTALL] terminal packages: ${data}`); + safeMainWindowSend('install-dependencies-log', { + type: 'stdout', + data: data.toString(), + }); + }); + + installPkgs.on('close', (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`Failed to install terminal packages, exit code: ${code}`)); + } + }); + + installPkgs.on('error', reject); + }); + + log.info('[DEPS INSTALL] Terminal base venv created successfully'); + return { message: 'Terminal base venv created successfully', success: true }; + } catch (error) { + log.error('[DEPS INSTALL] Failed to create terminal base venv:', error); + return { + message: `Failed to create terminal base venv: ${error}`, + success: false, + }; + } +} + export async function installDependencies( version: string ): Promise { @@ -890,6 +1010,13 @@ export async function installDependencies( // try default install const installSuccess = await runInstall([], version); if (installSuccess.success) { + // Install terminal base venv (lightweight venv for terminal tasks) + log.info('[DEPS INSTALL] Installing terminal base venv...'); + const terminalResult = await installTerminalBaseVenv(version); + if (!terminalResult.success) { + log.warn('[DEPS INSTALL] Terminal base venv installation failed, but continuing...', terminalResult.message); + } + // Install hybrid_browser_toolkit npm dependencies after Python packages are installed log.info( '[DEPS INSTALL] Installing hybrid_browser_toolkit dependencies...' @@ -922,6 +1049,13 @@ export async function installDependencies( : await runInstall([], version); if (mirrorInstallSuccess.success) { + // Install terminal base venv (lightweight venv for terminal tasks) + log.info('[DEPS INSTALL] Installing terminal base venv...'); + const terminalResult = await installTerminalBaseVenv(version); + if (!terminalResult.success) { + log.warn('[DEPS INSTALL] Terminal base venv installation failed, but continuing...', terminalResult.message); + } + // Install hybrid_browser_toolkit npm dependencies after Python packages are installed log.info( '[DEPS INSTALL] Installing hybrid_browser_toolkit dependencies...' diff --git a/electron/main/utils/process.ts b/electron/main/utils/process.ts index c8647e68..c6d861e3 100644 --- a/electron/main/utils/process.ts +++ b/electron/main/utils/process.ts @@ -185,6 +185,43 @@ export function getVenvsBaseDir(): string { return path.join(os.homedir(), '.eigent', 'venvs'); } +/** + * Packages to install in the terminal base venv. + * These are commonly used packages for terminal tasks (data processing, visualization, etc.) + * Keep this list minimal - users can install additional packages as needed. + */ +export const TERMINAL_BASE_PACKAGES = [ + 'pandas', + 'numpy', + 'matplotlib', + 'requests', + 'openpyxl', + 'beautifulsoup4', + 'pillow', +]; + +/** + * Get path to the terminal base venv. + * This is a lightweight venv with common packages for terminal tasks, + * separate from the backend venv. + */ +export function getTerminalVenvPath(version: string): string { + const venvDir = path.join( + os.homedir(), + '.eigent', + 'venvs', + `terminal_base-${version}` + ); + + // Ensure venvs directory exists + const venvsBaseDir = path.dirname(venvDir); + if (!fs.existsSync(venvsBaseDir)) { + fs.mkdirSync(venvsBaseDir, { recursive: true }); + } + + return venvDir; +} + export async function cleanupOldVenvs(currentVersion: string): Promise { const venvsBaseDir = getVenvsBaseDir(); @@ -193,23 +230,34 @@ export async function cleanupOldVenvs(currentVersion: string): Promise { return; } + // Patterns to match: backend-{version} and terminal_base-{version} + const venvPatterns = [ + { prefix: 'backend-', regex: /^backend-(.+)$/ }, + { prefix: 'terminal_base-', regex: /^terminal_base-(.+)$/ }, + ]; + try { const entries = fs.readdirSync(venvsBaseDir, { withFileTypes: true }); for (const entry of entries) { - if (entry.isDirectory() && entry.name.startsWith('backend-')) { - const versionMatch = entry.name.match(/^backend-(.+)$/); - if (versionMatch && versionMatch[1] !== currentVersion) { - const oldVenvPath = path.join(venvsBaseDir, entry.name); - console.log(`Cleaning up old venv: ${oldVenvPath}`); + if (!entry.isDirectory()) continue; - try { - // Remove old venv directory recursively - fs.rmSync(oldVenvPath, { recursive: true, force: true }); - console.log(`Successfully removed old venv: ${entry.name}`); - } catch (err) { - console.error(`Failed to remove old venv ${entry.name}:`, err); + for (const pattern of venvPatterns) { + if (entry.name.startsWith(pattern.prefix)) { + const versionMatch = entry.name.match(pattern.regex); + if (versionMatch && versionMatch[1] !== currentVersion) { + const oldVenvPath = path.join(venvsBaseDir, entry.name); + console.log(`Cleaning up old venv: ${oldVenvPath}`); + + try { + // Remove old venv directory recursively + fs.rmSync(oldVenvPath, { recursive: true, force: true }); + console.log(`Successfully removed old venv: ${entry.name}`); + } catch (err) { + console.error(`Failed to remove old venv ${entry.name}:`, err); + } } + break; // Found matching pattern, no need to check others } } } From d373a8364a58b51c734daa73d064dbdb9d005492 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 09:10:29 +0800 Subject: [PATCH 41/63] update --- backend/app/utils/agent.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index 6c38c94e..95920af5 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -859,7 +859,8 @@ async def developer_agent(options: Chat): terminal_toolkit = TerminalToolkit( options.project_id, - Agents.document_agent, + Agents.developer_agent, + working_directory=working_directory, safe_mode=True, clone_current_env=True, ) @@ -1069,6 +1070,7 @@ def browser_agent(options: Chat): terminal_toolkit = TerminalToolkit( options.project_id, Agents.browser_agent, + working_directory=working_directory, safe_mode=True, clone_current_env=True, ) @@ -1259,6 +1261,7 @@ async def document_agent(options: Chat): terminal_toolkit = TerminalToolkit( options.project_id, Agents.document_agent, + working_directory=working_directory, safe_mode=True, clone_current_env=True, ) @@ -1482,6 +1485,7 @@ def multi_modal_agent(options: Chat): terminal_toolkit = TerminalToolkit( options.project_id, agent_name=Agents.multi_modal_agent, + working_directory=working_directory, safe_mode=True, clone_current_env=True, ) @@ -1676,6 +1680,7 @@ async def social_medium_agent(options: Chat): *TerminalToolkit( options.project_id, agent_name=Agents.social_medium_agent, + working_directory=working_directory, clone_current_env=True, ).get_tools(), *NoteTakingToolkit( From 241115de5bb91fe74c6c0158235e7d8e74b52a48 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 09:36:55 +0800 Subject: [PATCH 42/63] update --- backend/app/utils/toolkit/terminal_toolkit.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/backend/app/utils/toolkit/terminal_toolkit.py b/backend/app/utils/toolkit/terminal_toolkit.py index 1199ec4a..07733239 100644 --- a/backend/app/utils/toolkit/terminal_toolkit.py +++ b/backend/app/utils/toolkit/terminal_toolkit.py @@ -56,15 +56,18 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): self.api_task_id = api_task_id if agent_name is not None: self.agent_name = agent_name + + # Get base directory from environment + base_dir = env("file_save_path", os.path.expanduser("~/.eigent/terminal/")) + if working_directory is None: - base_dir = env("file_save_path", os.path.expanduser("~/.eigent/terminal/")) - # Each agent gets its own subdirectory to avoid race conditions when - # multiple agents create .venv simultaneously during parallel initialization - working_directory = os.path.join(base_dir, self.agent_name) + working_directory = base_dir + self._agent_venv_dir = os.path.join(base_dir, self.agent_name) logger.debug(f"Initializing TerminalToolkit for agent={self.agent_name}", extra={ "api_task_id": api_task_id, "working_directory": working_directory, + "agent_venv_dir": self._agent_venv_dir, }) if TerminalToolkit._thread_pool is None: @@ -101,7 +104,7 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): Creates a lightweight clone using symlinks to the terminal_base venv, which contains pre-installed packages (pandas, numpy, matplotlib, etc.). """ - self.cloned_env_path = os.path.join(self.working_dir, ".venv") + self.cloned_env_path = os.path.join(self._agent_venv_dir, ".venv") terminal_base_path = get_terminal_base_venv_path() # Check if terminal_base exists @@ -148,6 +151,9 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): shutil.rmtree(self.cloned_env_path, ignore_errors=True) logger.warning("Falling back to system Python") + def _get_venv_path(self): + return None + def _clone_venv_with_symlinks(self, source_venv: str, target_venv: str): """Clone a venv using symlinks for efficiency. From 140991a7c82b404bb9d03a62e5e9851f85b22f6f Mon Sep 17 00:00:00 2001 From: LuoPengcheng <2653972504@qq.com> Date: Tue, 20 Jan 2026 11:57:25 +0800 Subject: [PATCH 43/63] =?UTF-8?q?chore=EF=BC=9Aadd=20kimi=20provider?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/llm.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lib/llm.ts b/src/lib/llm.ts index 7d673993..20020edf 100644 --- a/src/lib/llm.ts +++ b/src/lib/llm.ts @@ -73,6 +73,15 @@ export const INIT_PROVODERS: Provider[] = [ is_valid: false, model_type: "" }, + { + id: 'kimi', + name: 'Kimi', + apiKey: '', + apiHost: 'https://api.moonshot.cn/v1', + description: "Kimi model configuration.", + is_valid: false, + model_type: "" + }, { id: 'ModelArk', name: 'ModelArk', From 23fbe014762a36a43fa989f5f0892d07e44f4b3b Mon Sep 17 00:00:00 2001 From: LuoPengcheng <2653972504@qq.com> Date: Tue, 20 Jan 2026 12:04:06 +0800 Subject: [PATCH 44/63] chore --- src/lib/llm.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/llm.ts b/src/lib/llm.ts index 20020edf..6ae5cf6b 100644 --- a/src/lib/llm.ts +++ b/src/lib/llm.ts @@ -74,8 +74,8 @@ export const INIT_PROVODERS: Provider[] = [ model_type: "" }, { - id: 'kimi', - name: 'Kimi', + id: 'moonshot', + name: 'Moonshot', apiKey: '', apiHost: 'https://api.moonshot.cn/v1', description: "Kimi model configuration.", From 8d2f06a8fdfbc19919c1a776b57f0621fe7256bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E9=B9=8F=E9=93=96?= <104722516+LuoPengcheng12138@users.noreply.github.com> Date: Tue, 20 Jan 2026 15:06:11 +0800 Subject: [PATCH 45/63] chore --- src/lib/llm.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/llm.ts b/src/lib/llm.ts index 6ae5cf6b..eab1bbc6 100644 --- a/src/lib/llm.ts +++ b/src/lib/llm.ts @@ -77,7 +77,7 @@ export const INIT_PROVODERS: Provider[] = [ id: 'moonshot', name: 'Moonshot', apiKey: '', - apiHost: 'https://api.moonshot.cn/v1', + apiHost: 'https://api.moonshot.ai/v1', description: "Kimi model configuration.", is_valid: false, model_type: "" From 2826df6500aaca410487fc67e5fdbb23d446fa90 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 20:33:31 +0800 Subject: [PATCH 46/63] chore: update build view yml to release disk space for macos --- .github/workflows/build-view.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/build-view.yml b/.github/workflows/build-view.yml index 67f6cc44..d8d3b8ef 100644 --- a/.github/workflows/build-view.yml +++ b/.github/workflows/build-view.yml @@ -24,6 +24,34 @@ jobs: arch: x64 steps: + - name: Free Disk Space (macOS) + if: runner.os == 'macOS' + run: | + echo "Disk space before cleanup:" + df -h + # Remove iOS simulators + sudo rm -rf ~/Library/Developer/CoreSimulator/Devices/* || true + # Remove watchOS simulators + sudo rm -rf ~/Library/Developer/Xcode/watchOS\ DeviceSupport/* || true + # Remove tvOS simulators + sudo rm -rf ~/Library/Developer/Xcode/tvOS\ DeviceSupport/* || true + # Remove iOS DeviceSupport + sudo rm -rf ~/Library/Developer/Xcode/iOS\ DeviceSupport/* || true + # Remove derived data + sudo rm -rf ~/Library/Developer/Xcode/DerivedData/* || true + # Remove old archives + sudo rm -rf ~/Library/Developer/Xcode/Archives/* || true + # Remove Android SDK if present + sudo rm -rf ~/Library/Android/sdk || true + # Remove .NET + sudo rm -rf /usr/local/share/dotnet || true + # Remove Homebrew cache + rm -rf ~/Library/Caches/Homebrew/* || true + # Remove npm cache + npm cache clean --force || true + echo "Disk space after cleanup:" + df -h + - name: Checkout Code uses: actions/checkout@v4 From a19a3db3b91ac25adbc9734d77eb1c58f53d2193 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 21:11:41 +0800 Subject: [PATCH 47/63] chore: update discord link --- README.md | 14 +++++++------- README_CN.md | 14 +++++++------- README_JA.md | 14 +++++++------- README_PT-BR.md | 14 +++++++------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 877e0525..d244627b 100644 --- a/README.md +++ b/README.md @@ -307,13 +307,13 @@ Please add this signature image to the Signature Areas in the PDF. You could ins | Topics | Issues | Discord Channel | | ------------------------ | -- |-- | -| **Context Engineering** | - Prompt caching
- System prompt optimize
- Toolkit docstring optimize
- Context compression | [**Join Discord →**](https://discord.gg/D2e3rBWD) | -| **Multi-modal Enhancement** | - More accurate image understanding when using browser
- Advanced video generation | [**Join Discord →**](https://discord.gg/kyapNCeJ) | -| **Multi-agent system** | - Workforce support fixed workflow
- Workforce support multi-round conversion | [**Join Discord →**](https://discord.gg/bFRmPuDB) | -| **Browser Toolkit** | - BrowseComp integration
- Benchmark improvement
- Forbid repeated page visiting
- Automatic cache button clicking | [**Join Discord →**](https://discord.gg/NF73ze5v) | -| **Document Toolkit** | - Support dynamic file editing | [**Join Discord →**](https://discord.gg/4yAWJxYr) | -| **Terminal Toolkit** | - Benchmark improvement
- Terminal-Bench integration | [**Join Discord →**](https://discord.gg/FjQfnsrV) | -| **Environment & RL** | - Environment design
- Data-generation
- RL framework integration (VERL, TRL, OpenRLHF) | [**Join Discord →**](https://discord.gg/MaVZXEn8) | +| **Context Engineering** | - Prompt caching
- System prompt optimize
- Toolkit docstring optimize
- Context compression | [**Join Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Multi-modal Enhancement** | - More accurate image understanding when using browser
- Advanced video generation | [**Join Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Multi-agent system** | - Workforce support fixed workflow
- Workforce support multi-round conversion | [**Join Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Browser Toolkit** | - BrowseComp integration
- Benchmark improvement
- Forbid repeated page visiting
- Automatic cache button clicking | [**Join Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Document Toolkit** | - Support dynamic file editing | [**Join Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Terminal Toolkit** | - Benchmark improvement
- Terminal-Bench integration | [**Join Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Environment & RL** | - Environment design
- Data-generation
- RL framework integration (VERL, TRL, OpenRLHF) | [**Join Discord →**](https://discord.com/invite/CNcNpquyDc) | ## [🤝 Contributing][contribution-link] diff --git a/README_CN.md b/README_CN.md index c2c90f16..1bd95f97 100644 --- a/README_CN.md +++ b/README_CN.md @@ -294,13 +294,13 @@ Eigent 完全开源。您可以下载、检查和修改代码,确保透明度 | 主题 | 问题 | Discord 频道 | | ------------------------ | -- |-- | -| **上下文工程** | - 提示缓存
- 系统提示优化
- 工具包文档优化
- 上下文压缩 | [**加入 Discord →**](https://discord.gg/D2e3rBWD) | -| **多模态增强** | - 使用浏览器时更准确的图像理解
- 高级视频生成 | [**加入 Discord →**](https://discord.gg/kyapNCeJ) | -| **多智能体系统** | - 工作流支持固定流程
- 工作流支持多轮对话 | [**加入 Discord →**](https://discord.gg/bFRmPuDB) | -| **浏览器工具包** | - BrowseComp 集成
- 基准测试改进
- 禁止重复访问页面
- 自动缓存按钮点击 | [**加入 Discord →**](https://discord.gg/NF73ze5v) | -| **文档工具包** | - 支持动态文件编辑 | [**加入 Discord →**](https://discord.gg/4yAWJxYr) | -| **终端工具包** | - 基准测试改进
- Terminal-Bench 集成 | [**加入 Discord →**](https://discord.gg/FjQfnsrV) | -| **环境与强化学习** | - 环境设计
- 数据生成
- 强化学习框架集成(VERL, TRL, OpenRLHF) | [**加入 Discord →**](https://discord.gg/MaVZXEn8) | +| **上下文工程** | - 提示缓存
- 系统提示优化
- 工具包文档优化
- 上下文压缩 | [**加入 Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **多模态增强** | - 使用浏览器时更准确的图像理解
- 高级视频生成 | [**加入 Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **多智能体系统** | - 工作流支持固定流程
- 工作流支持多轮对话 | [**加入 Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **浏览器工具包** | - BrowseComp 集成
- 基准测试改进
- 禁止重复访问页面
- 自动缓存按钮点击 | [**加入 Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **文档工具包** | - 支持动态文件编辑 | [**加入 Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **终端工具包** | - 基准测试改进
- Terminal-Bench 集成 | [**加入 Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **环境与强化学习** | - 环境设计
- 数据生成
- 强化学习框架集成(VERL, TRL, OpenRLHF) | [**加入 Discord →**](https://discord.com/invite/CNcNpquyDc) | ## [🤝 贡献][contribution-link] diff --git a/README_JA.md b/README_JA.md index 08f73105..92f887a8 100644 --- a/README_JA.md +++ b/README_JA.md @@ -305,13 +305,13 @@ Documentsディレクトリにmydocsというフォルダがあります。ス | トピック | 課題 | Discordチャンネル | | ------------------------ | -- |-- | -| **コンテキストエンジニアリング** | - プロンプトキャッシング
- システムプロンプト最適化
- ツールキットdocstring最適化
- コンテキスト圧縮 | [**Discordに参加 →**](https://discord.gg/D2e3rBWD) | -| **マルチモーダル強化** | - ブラウザ使用時のより正確な画像理解
- 高度な動画生成 | [**Discordに参加 →**](https://discord.gg/kyapNCeJ) | -| **マルチエージェントシステム** | - 固定ワークフローをサポートするワークフォース
- マルチラウンド変換をサポートするワークフォース | [**Discordに参加 →**](https://discord.gg/bFRmPuDB) | -| **ブラウザツールキット** | - BrowseComp統合
- ベンチマーク改善
- 繰り返しページ訪問の禁止
- 自動キャッシュボタンクリック | [**Discordに参加 →**](https://discord.gg/NF73ze5v) | -| **ドキュメントツールキット** | - 動的ファイル編集のサポート | [**Discordに参加 →**](https://discord.gg/4yAWJxYr) | -| **ターミナルツールキット** | - ベンチマーク改善
- Terminal-Bench統合 | [**Discordに参加 →**](https://discord.gg/FjQfnsrV) | -| **環境 & RL** | - 環境設計
- データ生成
- RLフレームワーク統合(VERL、TRL、OpenRLHF) | [**Discordに参加 →**](https://discord.gg/MaVZXEn8) | +| **コンテキストエンジニアリング** | - プロンプトキャッシング
- システムプロンプト最適化
- ツールキットdocstring最適化
- コンテキスト圧縮 | [**Discordに参加 →**](https://discord.com/invite/CNcNpquyDc) | +| **マルチモーダル強化** | - ブラウザ使用時のより正確な画像理解
- 高度な動画生成 | [**Discordに参加 →**](https://discord.com/invite/CNcNpquyDc) | +| **マルチエージェントシステム** | - 固定ワークフローをサポートするワークフォース
- マルチラウンド変換をサポートするワークフォース | [**Discordに参加 →**](https://discord.com/invite/CNcNpquyDc) | +| **ブラウザツールキット** | - BrowseComp統合
- ベンチマーク改善
- 繰り返しページ訪問の禁止
- 自動キャッシュボタンクリック | [**Discordに参加 →**](https://discord.com/invite/CNcNpquyDc) | +| **ドキュメントツールキット** | - 動的ファイル編集のサポート | [**Discordに参加 →**](https://discord.com/invite/CNcNpquyDc) | +| **ターミナルツールキット** | - ベンチマーク改善
- Terminal-Bench統合 | [**Discordに参加 →**](https://discord.com/invite/CNcNpquyDc) | +| **環境 & RL** | - 環境設計
- データ生成
- RLフレームワーク統合(VERL、TRL、OpenRLHF) | [**Discordに参加 →**](https://discord.com/invite/CNcNpquyDc) | ## [🤝 コントリビューション][contribution-link] diff --git a/README_PT-BR.md b/README_PT-BR.md index a26c2a2a..12aee44d 100644 --- a/README_PT-BR.md +++ b/README_PT-BR.md @@ -302,13 +302,13 @@ Por favor, adicione esta imagem de assinatura às áreas de assinatura no PDF. V | Tópicos | Issues | Canal do Discord | | ------------------------- | -- |-- | -| **Engenharia de Contexto** | - Cache de prompts
- Otimização de prompt do sistema
- Otimização de docstrings do toolkit
- Compressão de contexto | [**Entrar no Discord →**](https://discord.gg/D2e3rBWD) | -| **Aprimoramento Multimodal** | - Compreensão de imagens mais precisa ao usar o navegador
- Geração avançada de vídeo | [**Entrar no Discord →**](https://discord.gg/kyapNCeJ) | -| **Sistema Multiagente** | - Suporte do Workforce a fluxos fixos
- Suporte do Workforce a conversas em múltiplas rodadas | [**Entrar no Discord →**](https://discord.gg/bFRmPuDB) | -| **Toolkit de Navegador** | - Integração com BrowseComp
- Melhoria de benchmark
- Proibir visitas repetidas a páginas
- Clique automático em botões de cache | [**Entrar no Discord →**](https://discord.gg/NF73ze5v) | -| **Toolkit de Documentos** | - Suporte à edição dinâmica de arquivos | [**Entrar no Discord →**](https://discord.gg/4yAWJxYr) | -| **Toolkit de Terminal** | - Melhoria de benchmark
- Integração com Terminal-Bench | [**Entrar no Discord →**](https://discord.gg/FjQfnsrV) | -| **Ambiente & RL** | - Design de ambiente
- Geração de dados
- Integração de frameworks de RL (VERL, TRL, OpenRLHF) | [**Entrar no Discord →**](https://discord.gg/MaVZXEn8) | +| **Engenharia de Contexto** | - Cache de prompts
- Otimização de prompt do sistema
- Otimização de docstrings do toolkit
- Compressão de contexto | [**Entrar no Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Aprimoramento Multimodal** | - Compreensão de imagens mais precisa ao usar o navegador
- Geração avançada de vídeo | [**Entrar no Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Sistema Multiagente** | - Suporte do Workforce a fluxos fixos
- Suporte do Workforce a conversas em múltiplas rodadas | [**Entrar no Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Toolkit de Navegador** | - Integração com BrowseComp
- Melhoria de benchmark
- Proibir visitas repetidas a páginas
- Clique automático em botões de cache | [**Entrar no Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Toolkit de Documentos** | - Suporte à edição dinâmica de arquivos | [**Entrar no Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Toolkit de Terminal** | - Melhoria de benchmark
- Integração com Terminal-Bench | [**Entrar no Discord →**](https://discord.com/invite/CNcNpquyDc) | +| **Ambiente & RL** | - Design de ambiente
- Geração de dados
- Integração de frameworks de RL (VERL, TRL, OpenRLHF) | [**Entrar no Discord →**](https://discord.com/invite/CNcNpquyDc) | ## [🤝 Contribuição][contribution-link] From f6b841c69044ab48f86770e2b113f8cd6f7bcbeb Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Tue, 20 Jan 2026 22:08:37 +0800 Subject: [PATCH 48/63] chore: update example task prompt --- src/i18n/locales/en-us/chat.json | 2 +- src/i18n/locales/en-us/layout.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/locales/en-us/chat.json b/src/i18n/locales/en-us/chat.json index e2f75f59..35a144f4 100644 --- a/src/i18n/locales/en-us/chat.json +++ b/src/i18n/locales/en-us/chat.json @@ -15,7 +15,7 @@ "you-are-using-self-hosted-mode": "You're in Self-hosted mode. Cloud models can't be used here — set up your own local cloud model to keep things running.", "you-are-using-self-hosted-mode-mcp": "You're using Self-hosted mode. Enter the Google Search Keys in “MCP and Tools” to ensure Eigent works properly.", "it-ticket-creation": "Help me complete an online form", - "it-ticket-creation-message": "Access the ticket management system at https://eiti.eigent.ai/ and add all these new tickets into our system with Browser Agent:\n''\nAffected User: Alice Johnson\nAssignment Group: Software Services Team\nAssigned To: Michael Brown\nPriority: 4 – Low | Urgency: 3 – Medium | Impact: 4 – Low\nAffected Service: Software Services\nIssue: Application Performance Degradation\nDescription:\nThe affected user reports slow response times and intermittent timeouts when accessing internal software applications during normal business hours.\n''\nOnce done, check the incoming tickets and generate a detailed statistical report analyzing which IT areas have the most issues and the highest financial impact. The report should include charts and diagrams for visualization.", + "it-ticket-creation-message": "Access the ticket management system at https://eiti.eigent.ai/ and add all these new tickets into our system with Browser Agent:\n''\nAffected User: Alice Johnson\nAssignment Group: Software Services Team\nAssigned To: Michael Brown\nPriority: 4 – Low | Urgency: 3 – Medium | Impact: 4 – Low\nAffected Service: Software Services\nIssue: Application Performance Degradation\nDescription:\nThe affected user reports slow response times and intermittent timeouts when accessing internal software applications during normal business hours.\n''\nOnce done, check the in progress and generate a detailed statistical report analyzing which IT areas have the most issues and the highest financial impact. The report should include charts and diagrams for visualization.", "bank-transfer-csv-analysis-and-visualization": "Bank Transfer CSV Analysis and Visualization", "bank-transfer-csv-analysis-and-visualization-message": "Create a mock bank transfer CSV file include 10 columns and 10 rows. Read the generated CSV file and summarize the data, generate a chart to visualize relevant trends or insights from the data.", "help-organize-my-desktop": "Please Help Organize My Desktop", diff --git a/src/i18n/locales/en-us/layout.json b/src/i18n/locales/en-us/layout.json index 860bcafe..69b2994b 100644 --- a/src/i18n/locales/en-us/layout.json +++ b/src/i18n/locales/en-us/layout.json @@ -126,7 +126,7 @@ "terms-of-use": "Terms of Use", "and": "and", "it-ticket-creation": "Help me complete an online form", - "it-ticket-creation-message": "Access the ticket management system at https://eiti.eigent.ai/ and add all these new tickets into our system with Browser Agent:\n''\nAffected User: Alice Johnson\nAssignment Group: Software Services Team\nAssigned To: Michael Brown\nPriority: 4 – Low | Urgency: 3 – Medium | Impact: 4 – Low\nAffected Service: Software Services\nIssue: Application Performance Degradation\nDescription:\nThe affected user reports slow response times and intermittent timeouts when accessing internal software applications during normal business hours.\n''\nOnce done, check the incoming tickets and generate a detailed statistical report analyzing which IT areas have the most issues and the highest financial impact. The report should include charts and diagrams for visualization.", + "it-ticket-creation-message": "Access the ticket management system at https://eiti.eigent.ai/ and add all these new tickets into our system with Browser Agent:\n''\nAffected User: Alice Johnson\nAssignment Group: Software Services Team\nAssigned To: Michael Brown\nPriority: 4 – Low | Urgency: 3 – Medium | Impact: 4 – Low\nAffected Service: Software Services\nIssue: Application Performance Degradation\nDescription:\nThe affected user reports slow response times and intermittent timeouts when accessing internal software applications during normal business hours.\n''\nOnce done, check the in progress and generate a detailed statistical report analyzing which IT areas have the most issues and the highest financial impact. The report should include charts and diagrams for visualization.", "bank-transfer-csv-analysis": "Bank Transfer CSV Analysis and Visualization", "bank-transfer-csv-analysis-message": "Create a mock bank transfer CSV file include 10 columns and 10 rows. Read the generated CSV file and summarize the data, generate a chart to visualize relevant trends or insights from the data.", "find-duplicate-files": "Please Help Organize My Desktop", From 44b6b55b9d473edf67ab2b3a94ef4134d4bc31ec Mon Sep 17 00:00:00 2001 From: Wendong-Fan <133094783+Wendong-Fan@users.noreply.github.com> Date: Tue, 20 Jan 2026 16:19:32 +0000 Subject: [PATCH 49/63] fix: win prebuilt (#987) Co-authored-by: 4pmtong --- electron-builder.json | 8 +- electron/main/init.ts | 19 ++- electron/main/utils/process.ts | 40 ++++- scripts/clean-symlinks.js | 10 +- scripts/preinstall-deps.js | 101 ++++++++++- scripts/test-notarization.js | 296 +++++++++++++++++++++++++++++++++ 6 files changed, 461 insertions(+), 13 deletions(-) create mode 100644 scripts/test-notarization.js diff --git a/electron-builder.json b/electron-builder.json index 0ff93ab7..4028cd46 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -29,7 +29,13 @@ { "from": "resources/prebuilt", "to": "prebuilt", - "filter": ["**/*", "!cache/**/*", "!**/.npm-cache/**/*"] + "filter": [ + "**/*", + "!cache/**/*", + "!**/.npm-cache/**/*", + "!uv_python/**/*.pyc", + "!uv_python/**/__pycache__" + ] } ], "protocols": [ diff --git a/electron/main/init.ts b/electron/main/init.ts index 1ee74eaa..2b0ace8c 100644 --- a/electron/main/init.ts +++ b/electron/main/init.ts @@ -1,4 +1,4 @@ -import { getBackendPath, getBinaryPath, getCachePath, getVenvPath, getUvEnv, isBinaryExists, runInstallScript, killProcessByName } from "./utils/process"; +import { getBackendPath, getBinaryPath, getCachePath, getVenvPath, getUvEnv, isBinaryExists, runInstallScript, killProcessByName, getPrebuiltPythonDir, getPrebuiltVenvPath } from "./utils/process"; import { spawn, exec } from 'child_process' import log from 'electron-log' import fs from 'fs' @@ -225,21 +225,34 @@ export async function startBackend(setPort?: (port: number) => void): Promise { return fs.existsSync(cmd); } +/** + * Get path to prebuilt Python installation (if available in packaged app) + */ +export function getPrebuiltPythonDir(): string | null { + if (!app.isPackaged) { + return null; + } + + const prebuiltPythonDir = path.join(process.resourcesPath, 'prebuilt', 'uv_python'); + if (fs.existsSync(prebuiltPythonDir)) { + log.info(`Using prebuilt Python: ${prebuiltPythonDir}`); + return prebuiltPythonDir; + } + + return null; +} + /** * Get unified UV environment variables for consistent Python environment management. * This ensures both installation and runtime use the same paths. @@ -279,8 +309,12 @@ export async function isBinaryExists(name: string): Promise { * @returns Environment variables for UV commands */ export function getUvEnv(version: string): Record { + // Use prebuilt Python if available (packaged app) + const prebuiltPython = getPrebuiltPythonDir(); + const pythonInstallDir = prebuiltPython || getCachePath('uv_python'); + return { - UV_PYTHON_INSTALL_DIR: getCachePath('uv_python'), + UV_PYTHON_INSTALL_DIR: pythonInstallDir, UV_TOOL_DIR: getCachePath('uv_tool'), UV_PROJECT_ENVIRONMENT: getVenvPath(version), UV_HTTP_TIMEOUT: '300', diff --git a/scripts/clean-symlinks.js b/scripts/clean-symlinks.js index e011ba45..716a4c40 100644 --- a/scripts/clean-symlinks.js +++ b/scripts/clean-symlinks.js @@ -46,7 +46,7 @@ function isValidSymlink(symlinkPath, bundleRoot) { } /** - * Fix Python symlinks in venv/bin + * Fix Python symlinks in venv/bin (Unix) or venv/Scripts (Windows) * Remove symlinks that point outside the bundle (to cache directory) */ function fixPythonSymlinks(venvBinDir, bundleRoot) { @@ -55,7 +55,10 @@ function fixPythonSymlinks(venvBinDir, bundleRoot) { } const bundlePath = path.resolve(bundleRoot); - const pythonNames = ['python', 'python3', 'python3.10', 'python3.11', 'python3.12']; + const isWindows = process.platform === 'win32'; + const pythonNames = isWindows + ? ['python.exe', 'python3.exe', 'python3.10.exe', 'python3.11.exe', 'python3.12.exe'] + : ['python', 'python3', 'python3.10', 'python3.11', 'python3.12']; for (const pythonName of pythonNames) { const pythonSymlink = path.join(venvBinDir, pythonName); @@ -127,7 +130,8 @@ function main() { console.log('🧹 Cleaning invalid symbolic links...'); const bundleRoot = path.join(projectRoot, 'resources', 'prebuilt'); - const venvBinDir = path.join(bundleRoot, 'venv', 'bin'); + const isWindows = process.platform === 'win32'; + const venvBinDir = path.join(bundleRoot, 'venv', isWindows ? 'Scripts' : 'bin'); // First, try to fix Python symlinks specifically if (fs.existsSync(venvBinDir)) { diff --git a/scripts/preinstall-deps.js b/scripts/preinstall-deps.js index a5ef3311..ad04989f 100644 --- a/scripts/preinstall-deps.js +++ b/scripts/preinstall-deps.js @@ -17,8 +17,9 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const projectRoot = path.resolve(__dirname, '..'); -const BIN_DIR = path.join(projectRoot, 'resources', 'prebuilt', 'bin'); -const VENV_DIR = path.join(projectRoot, 'resources', 'prebuilt', 'venv'); +const PREBUILT_DIR = path.join(projectRoot, 'resources', 'prebuilt'); +const BIN_DIR = path.join(PREBUILT_DIR, 'bin'); +const VENV_DIR = path.join(PREBUILT_DIR, 'venv'); const BACKEND_DIR = path.join(projectRoot, 'backend'); console.log('🚀 Starting pre-installation of dependencies...'); @@ -197,6 +198,45 @@ async function downloadFileWithValidation(urlsToTry, dest, validateFn, fileType throw new Error(`Failed to download ${fileType} from all sources`); } +/** + * Recursively copy directory, handling symlinks properly + */ +function copyDirRecursiveSync(src, dest) { + if (!fs.existsSync(src)) { + return; + } + + // Create destination directory + fs.mkdirSync(dest, { recursive: true }); + + // Get all files and directories + const entries = fs.readdirSync(src, { withFileTypes: true }); + + for (const entry of entries) { + const srcPath = path.join(src, entry.name); + const destPath = path.join(dest, entry.name); + + if (entry.isDirectory()) { + copyDirRecursiveSync(srcPath, destPath); + } else if (entry.isSymbolicLink()) { + try { + const realPath = fs.realpathSync(srcPath); + const realStat = fs.statSync(realPath); + if (realStat.isDirectory()) { + copyDirRecursiveSync(realPath, destPath); + } else { + fs.copyFileSync(realPath, destPath); + } + } catch (err) { + // If symlink target doesn't exist, skip it + console.log(` Skipping broken symlink: ${srcPath}`); + } + } else { + fs.copyFileSync(srcPath, destPath); + } + } +} + /** * Get Bun download URL list */ @@ -613,11 +653,66 @@ async function installPythonDeps(uvPath) { console.log('📦 Creating Python venv...'); } + // Ensure Python is installed before syncing + // This is critical for Windows where Python might not be in the venv + console.log('🐍 Ensuring Python is installed...'); + try { + execSync( + `"${uvPath}" python install 3.10`, + { cwd: BACKEND_DIR, env: env, stdio: 'inherit' } + ); + } catch (error) { + console.log('⚠️ Python install command failed, continuing with sync (Python may already be installed)...'); + } + + // Use --python-preference only-managed to ensure uv uses its own managed Python + // This makes the venv more portable execSync( - `"${uvPath}" sync --no-dev --cache-dir "${cacheDir}"`, + `"${uvPath}" sync --no-dev --cache-dir "${cacheDir}" --python-preference only-managed`, { cwd: BACKEND_DIR, env: env, stdio: 'inherit' } ); + // Verify Python executable exists in the virtual environment + const isWindows = process.platform === 'win32'; + const pythonExePath = isWindows + ? path.join(venvPath, 'Scripts', 'python.exe') + : path.join(venvPath, 'bin', 'python'); + + if (!fs.existsSync(pythonExePath)) { + throw new Error( + `Python executable not found in virtual environment at: ${pythonExePath}\n` + + `Virtual environment may be corrupted. Please ensure uv sync completed successfully.` + ); + } + + console.log(`✅ Python executable verified: ${pythonExePath}`); + + // Bundle the actual Python installation from UV cache into prebuilt + console.log('📦 Bundling Python installation...'); + try { + const uvPythonDir = pythonCacheDir; + const prebuiltPythonDir = path.join(PREBUILT_DIR, 'uv_python'); + + if (fs.existsSync(uvPythonDir)) { + console.log(` Copying from: ${uvPythonDir}`); + console.log(` Copying to: ${prebuiltPythonDir}`); + + // Remove existing python dir if it exists + if (fs.existsSync(prebuiltPythonDir)) { + fs.rmSync(prebuiltPythonDir, { recursive: true, force: true }); + } + + // Copy the Python installation + copyDirRecursiveSync(uvPythonDir, prebuiltPythonDir); + console.log('✅ Python installation bundled'); + } else { + console.log('⚠️ UV Python cache not found, venv may not be portable'); + } + } catch (error) { + console.log(`⚠️ Failed to bundle Python: ${error.message}`); + console.log(' The app may fail to start without internet connection'); + } + console.log('✅ Python dependencies installed'); console.log('📝 Compiling babel...'); diff --git a/scripts/test-notarization.js b/scripts/test-notarization.js new file mode 100644 index 00000000..672b44a5 --- /dev/null +++ b/scripts/test-notarization.js @@ -0,0 +1,296 @@ +#!/usr/bin/env node +/** + * Test script for macOS notarization issues + * This script checks for common issues that cause notarization to fail: + * 1. .npm-cache directories + * 2. flac-mac binary (outdated SDK) + * 3. Unsigned native binaries (.node files) + * 4. Other problematic files + */ + +import fs from 'fs'; +import path from 'path'; +import { execSync } from 'child_process'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const projectRoot = path.resolve(__dirname, '..'); + +const RELEASE_DIR = path.join(projectRoot, 'release'); +const APP_BUNDLE_PATTERN = /Eigent\.app$/; + +/** + * Find the app bundle in release directory + */ +function findAppBundle() { + if (!fs.existsSync(RELEASE_DIR)) { + console.log('❌ Release directory does not exist. Please build the app first.'); + console.log(' Run: npm run build:mac'); + return null; + } + + const entries = fs.readdirSync(RELEASE_DIR, { withFileTypes: true }); + + for (const entry of entries) { + if (entry.isDirectory() && entry.name.match(APP_BUNDLE_PATTERN)) { + return path.join(RELEASE_DIR, entry.name); + } + + // Check subdirectories (e.g., mac-arm64/Eigent.app) + if (entry.isDirectory()) { + const subDir = path.join(RELEASE_DIR, entry.name); + const subEntries = fs.readdirSync(subDir, { withFileTypes: true }); + for (const subEntry of subEntries) { + if (subEntry.isDirectory() && subEntry.name.match(APP_BUNDLE_PATTERN)) { + return path.join(subDir, subEntry.name); + } + } + } + } + + return null; +} + +/** + * Check for .npm-cache directories + */ +function checkNpmCache(bundlePath) { + console.log('\n🔍 Checking for .npm-cache directories...'); + const issues = []; + + function scanDir(dir) { + if (!fs.existsSync(dir)) { + return; + } + + try { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + + if (entry.name === '.npm-cache' && entry.isDirectory()) { + issues.push(fullPath); + } else if (entry.isDirectory()) { + // Skip node_modules to avoid deep scanning + if (entry.name !== 'node_modules' && entry.name !== '__pycache__') { + scanDir(fullPath); + } + } + } + } catch (error) { + // Ignore errors + } + } + + const resourcesPath = path.join(bundlePath, 'Contents', 'Resources'); + const prebuiltPath = path.join(resourcesPath, 'prebuilt'); + + if (fs.existsSync(prebuiltPath)) { + scanDir(prebuiltPath); + } + + if (issues.length > 0) { + console.log(`❌ Found ${issues.length} .npm-cache directory(ies):`); + issues.forEach(issue => console.log(` - ${issue}`)); + return false; + } else { + console.log('✅ No .npm-cache directories found'); + return true; + } +} + +/** + * Check for flac-mac binary + */ +function checkFlacMac(bundlePath) { + console.log('\n🔍 Checking for flac-mac binary...'); + const issues = []; + + const resourcesPath = path.join(bundlePath, 'Contents', 'Resources'); + const prebuiltPath = path.join(resourcesPath, 'prebuilt'); + const venvLibPath = path.join(prebuiltPath, 'venv', 'lib'); + + if (fs.existsSync(venvLibPath)) { + try { + const entries = fs.readdirSync(venvLibPath, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isDirectory() && entry.name.startsWith('python')) { + const flacMacPath = path.join(venvLibPath, entry.name, 'site-packages', 'speech_recognition', 'flac-mac'); + if (fs.existsSync(flacMacPath)) { + issues.push(flacMacPath); + } + } + } + } catch (error) { + // Ignore errors + } + } + + if (issues.length > 0) { + console.log(`❌ Found ${issues.length} flac-mac binary(ies) (outdated SDK):`); + issues.forEach(issue => console.log(` - ${issue}`)); + return false; + } else { + console.log('✅ No flac-mac binaries found'); + return true; + } +} + +/** + * Check for unsigned native binaries + */ +function checkUnsignedBinaries(bundlePath) { + console.log('\n🔍 Checking for unsigned native binaries (.node files)...'); + const issues = []; + + function scanForNodeFiles(dir) { + if (!fs.existsSync(dir)) { + return; + } + + try { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + + if (entry.isFile() && entry.name.endsWith('.node')) { + // Check if file is signed + try { + const output = execSync(`codesign -dv "${fullPath}" 2>&1 || true`, { encoding: 'utf-8' }); + if (output.includes('code object is not signed')) { + issues.push({ + path: fullPath, + reason: 'Not signed' + }); + } + } catch (error) { + // If codesign fails, assume it's not signed + issues.push({ + path: fullPath, + reason: 'Could not verify signature' + }); + } + } else if (entry.isDirectory()) { + // Skip certain directories + if (entry.name !== 'node_modules' && entry.name !== '__pycache__' && !entry.name.startsWith('.')) { + scanForNodeFiles(fullPath); + } + } + } + } catch (error) { + // Ignore errors + } + } + + const resourcesPath = path.join(bundlePath, 'Contents', 'Resources'); + const prebuiltPath = path.join(resourcesPath, 'prebuilt'); + + if (fs.existsSync(prebuiltPath)) { + scanForNodeFiles(prebuiltPath); + } + + if (issues.length > 0) { + console.log(`❌ Found ${issues.length} unsigned .node file(s):`); + issues.forEach(issue => { + console.log(` - ${issue.path}`); + console.log(` Reason: ${issue.reason}`); + }); + return false; + } else { + console.log('✅ No unsigned .node files found'); + return true; + } +} + +/** + * Check app bundle size + */ +function checkBundleSize(bundlePath) { + console.log('\n🔍 Checking app bundle size...'); + + try { + function getDirSize(dir) { + let size = 0; + try { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isFile()) { + size += fs.statSync(fullPath).size; + } else if (entry.isDirectory()) { + size += getDirSize(fullPath); + } + } + } catch (error) { + // Ignore errors + } + return size; + } + + const size = getDirSize(bundlePath); + const sizeInMB = (size / (1024 * 1024)).toFixed(2); + console.log(` App bundle size: ${sizeInMB} MB`); + + if (size > 500 * 1024 * 1024) { + console.log(` ⚠️ Large bundle size (>500MB) may cause slow notarization (30-60 minutes)`); + } else if (size > 200 * 1024 * 1024) { + console.log(` ⚠️ Medium bundle size (200-500MB) may take 15-30 minutes to notarize`); + } else { + console.log(` ✅ Bundle size is reasonable for notarization`); + } + + return true; + } catch (error) { + console.log(` ⚠️ Could not calculate bundle size: ${error.message}`); + return true; + } +} + +/** + * Main function + */ +function main() { + console.log('🧪 macOS Notarization Test Script\n'); + + const appBundle = findAppBundle(); + + if (!appBundle) { + console.log('\n💡 To build the app for testing:'); + console.log(' npm run build:mac'); + process.exit(1); + } + + console.log(`📦 Found app bundle: ${appBundle}\n`); + + const results = { + npmCache: checkNpmCache(appBundle), + flacMac: checkFlacMac(appBundle), + unsignedBinaries: checkUnsignedBinaries(appBundle), + bundleSize: checkBundleSize(appBundle), + }; + + console.log('\n📊 Summary:'); + console.log(` .npm-cache directories: ${results.npmCache ? '✅' : '❌'}`); + console.log(` flac-mac binaries: ${results.flacMac ? '✅' : '❌'}`); + console.log(` Unsigned .node files: ${results.unsignedBinaries ? '✅' : '❌'}`); + console.log(` Bundle size: ${results.bundleSize ? '✅' : '⚠️'}`); + + const allPassed = Object.values(results).every(r => r); + + if (allPassed) { + console.log('\n✅ All checks passed! The app should be ready for notarization.'); + console.log('\n💡 Note: This script only checks for common issues.'); + console.log(' Actual notarization may still fail for other reasons.'); + console.log(' To test actual notarization, you need:'); + console.log(' - Valid Apple Developer ID certificate'); + console.log(' - APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID environment variables'); + } else { + console.log('\n❌ Some checks failed. Please fix the issues above before notarization.'); + process.exit(1); + } +} + +main(); From 3946c413562b11236539183d89c0bf4d69726171 Mon Sep 17 00:00:00 2001 From: Puzhen Zhang <91596298+nitpicker55555@users.noreply.github.com> Date: Tue, 20 Jan 2026 18:11:46 +0000 Subject: [PATCH 50/63] fix:duplicate actions panel (#988) Co-authored-by: Wendong-Fan <133094783+Wendong-Fan@users.noreply.github.com> Co-authored-by: Wendong-Fan --- backend/app/utils/agent.py | 55 ++++++------ backend/app/utils/listen/toolkit_listen.py | 15 ++-- backend/app/utils/toolkit/terminal_toolkit.py | 30 ++++++- backend/pyproject.toml | 2 +- backend/uv.lock | 14 ++-- electron/main/install-deps.ts | 83 +++++++++++-------- server/pyproject.toml | 2 +- server/uv.lock | 8 +- 8 files changed, 128 insertions(+), 81 deletions(-) diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index 95920af5..fa4bee25 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -425,7 +425,9 @@ class ListenChatAgent(ChatAgent): # Check if tool is wrapped by @listen_toolkit decorator # If so, the decorator will handle activate/deactivate events - has_listen_decorator = hasattr(tool.func, "__wrapped__") + # TODO: Refactor - current marker detection is a workaround. The proper fix is to + # unify event sending: remove activate/deactivate from @listen_toolkit, only send here + has_listen_decorator = getattr(tool.func, "__listen_toolkit__", False) try: task_lock = get_task_lock(self.api_task_id) @@ -563,19 +565,23 @@ class ListenChatAgent(ChatAgent): f"Agent {self.agent_name} executing async tool: {func_name} from toolkit: {toolkit_name} with args: {json.dumps(args, ensure_ascii=False)}" ) - # Always send activate event from agent to ensure consistent logging - # This ensures all tool calls are logged, regardless of decorator detection issues - await task_lock.put_queue( - ActionActivateToolkitData( - data={ - "agent_name": self.agent_name, - "process_task_id": self.process_task_id, - "toolkit_name": toolkit_name, - "method_name": func_name, - "message": json.dumps(args, ensure_ascii=False), - }, + # Check if tool is wrapped by @listen_toolkit decorator + # If so, the decorator will handle activate/deactivate events + has_listen_decorator = getattr(tool.func, "__listen_toolkit__", False) + + # Only send activate event if tool is NOT wrapped by @listen_toolkit + if not has_listen_decorator: + await task_lock.put_queue( + ActionActivateToolkitData( + data={ + "agent_name": self.agent_name, + "process_task_id": self.process_task_id, + "toolkit_name": toolkit_name, + "method_name": func_name, + "message": json.dumps(args, ensure_ascii=False), + }, + ) ) - ) try: # Set process_task context for all tool executions with set_process_task(self.process_task_id): @@ -643,18 +649,19 @@ class ListenChatAgent(ChatAgent): else: result_msg = result_str - # Always send deactivate event from agent to ensure consistent logging - await task_lock.put_queue( - ActionDeactivateToolkitData( - data={ - "agent_name": self.agent_name, - "process_task_id": self.process_task_id, - "toolkit_name": toolkit_name, - "method_name": func_name, - "message": result_msg, - }, + # Only send deactivate event if tool is NOT wrapped by @listen_toolkit + if not has_listen_decorator: + await task_lock.put_queue( + ActionDeactivateToolkitData( + data={ + "agent_name": self.agent_name, + "process_task_id": self.process_task_id, + "toolkit_name": toolkit_name, + "method_name": func_name, + "message": result_msg, + }, + ) ) - ) return self._record_tool_calling( func_name, args, diff --git a/backend/app/utils/listen/toolkit_listen.py b/backend/app/utils/listen/toolkit_listen.py index f8cff0c3..beb7f9d7 100644 --- a/backend/app/utils/listen/toolkit_listen.py +++ b/backend/app/utils/listen/toolkit_listen.py @@ -185,6 +185,8 @@ def listen_toolkit( raise error return res + # Mark this wrapper as decorated by @listen_toolkit for detection in agent.py + async_wrapper.__listen_toolkit__ = True return async_wrapper else: @@ -291,6 +293,8 @@ def listen_toolkit( raise error return res + # Mark this wrapper as decorated by @listen_toolkit for detection in agent.py + sync_wrapper.__listen_toolkit__ = True return sync_wrapper return decorator @@ -350,14 +354,9 @@ def auto_listen_toolkit(base_toolkit_class: Type[T]) -> Callable[[Type[T]], Type # Method is overridden, check if it already has @listen_toolkit decorator overridden_method = cls.__dict__[method_name] - # Check if already decorated by looking for the wrapper attributes - # that listen_toolkit adds (like __wrapped__ or specific markers) - is_already_decorated = ( - hasattr(overridden_method, '__wrapped__') or - (hasattr(overridden_method, '__name__') and - hasattr(getattr(overridden_method, '__code__', None), 'co_freevars') and - 'toolkit' in getattr(overridden_method.__code__, 'co_freevars', [])) - ) + # Check if already decorated by looking for the __listen_toolkit__ marker + # that listen_toolkit adds to its wrappers + is_already_decorated = getattr(overridden_method, '__listen_toolkit__', False) if is_already_decorated: # Already has @listen_toolkit, skip diff --git a/backend/app/utils/toolkit/terminal_toolkit.py b/backend/app/utils/toolkit/terminal_toolkit.py index 07733239..9109dcab 100644 --- a/backend/app/utils/toolkit/terminal_toolkit.py +++ b/backend/app/utils/toolkit/terminal_toolkit.py @@ -152,13 +152,16 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): logger.warning("Falling back to system Python") def _get_venv_path(self): + """Return the cloned venv path for shell activation.""" + cloned_env_path = getattr(self, 'cloned_env_path', None) + if cloned_env_path and os.path.exists(cloned_env_path): + return cloned_env_path return None def _clone_venv_with_symlinks(self, source_venv: str, target_venv: str): """Clone a venv using symlinks for efficiency. - Only creates the minimum structure needed: pyvenv.cfg, bin/python, and lib symlink. - Activation scripts are not needed since we use python_executable directly. + Creates the structure needed: pyvenv.cfg, bin/python, lib symlink, and activate scripts. """ is_windows = platform.system() == 'Windows' @@ -187,6 +190,16 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): src = os.path.join(source_scripts, exe) if os.path.exists(src): shutil.copy2(src, os.path.join(target_bin, exe)) + # Copy activate scripts (need to modify VIRTUAL_ENV path) + for script in ["activate.bat", "activate.ps1", "deactivate.bat"]: + src = os.path.join(source_scripts, script) + if os.path.exists(src): + with open(src, 'r', encoding='utf-8') as f: + content = f.read() + content = content.replace(source_venv, target_venv) + dst = os.path.join(target_bin, script) + with open(dst, 'w', encoding='utf-8') as f: + f.write(content) # Use directory junction for Lib (no admin rights needed, unlike symlink) source_lib = os.path.join(source_venv, "Lib") target_lib = os.path.join(target_venv, "Lib") @@ -204,6 +217,19 @@ class TerminalToolkit(BaseTerminalToolkit, AbstractToolkit): os.symlink(python_exe, os.path.join(target_bin, "python")) os.symlink("python", os.path.join(target_bin, "python3")) + # Copy activate scripts (need to modify VIRTUAL_ENV path) + source_bin = os.path.join(source_venv, "bin") + for script in ["activate", "activate.csh", "activate.fish"]: + src = os.path.join(source_bin, script) + if os.path.exists(src): + with open(src, 'r') as f: + content = f.read() + # Replace source venv path with target venv path + content = content.replace(source_venv, target_venv) + dst = os.path.join(target_bin, script) + with open(dst, 'w') as f: + f.write(content) + # Symlink lib directory source_lib = os.path.join(source_venv, "lib") os.symlink(source_lib, os.path.join(target_venv, "lib")) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 172a1ea5..4a54a93a 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -6,7 +6,7 @@ readme = "README.md" requires-python = ">=3.10,<3.11" dependencies = [ "pip>=23.0", - "camel-ai[eigent]==0.2.83", + "camel-ai[eigent]==0.2.84", "fastapi>=0.115.12", "fastapi-babel>=1.0.0", "uvicorn[standard]>=0.34.2", diff --git a/backend/uv.lock b/backend/uv.lock index 4259346e..7a2095e9 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -261,7 +261,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "aiofiles", specifier = ">=24.1.0" }, - { name = "camel-ai", extras = ["eigent"], specifier = "==0.2.83" }, + { name = "camel-ai", extras = ["eigent"], specifier = "==0.2.84" }, { name = "debugpy", specifier = ">=1.8.17" }, { name = "fastapi", specifier = ">=0.115.12" }, { name = "fastapi-babel", specifier = ">=1.0.0" }, @@ -337,7 +337,7 @@ wheels = [ [[package]] name = "camel-ai" -version = "0.2.83" +version = "0.2.84" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astor" }, @@ -354,9 +354,9 @@ dependencies = [ { name = "tiktoken" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/d1/36f0982862ba2b992968ace43b1c04dd72f7114ce3954342a99e18619d6a/camel_ai-0.2.83.tar.gz", hash = "sha256:c25eb414e9353aab166021852fb54d1d3a0c0e17485fefa996de2cccdf4c8eb9", size = 1125708, upload-time = "2026-01-19T20:37:45.197Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9b/62/96d922750b304ab2dd0ac1ef35dd3fbbf0e9a44f147e08a1ddfeb94c51c6/camel_ai-0.2.84.tar.gz", hash = "sha256:173c79755fc986e3fa8e27523606222c5f8816fc085abb24831912dcd4a0dec3", size = 1125724, upload-time = "2026-01-20T17:23:13.524Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/e2/4e2964059794af9161889223fa7d17630c1bcc74005c9892cd1e1627650c/camel_ai-0.2.83-py3-none-any.whl", hash = "sha256:3a183efdcccd211ae216b2a7903d48a8811ad0f4541223cacc05cb25a11279a6", size = 1599355, upload-time = "2026-01-19T20:37:41.985Z" }, + { url = "https://files.pythonhosted.org/packages/ec/8b/246abd2c47154de6220fd0a286c3fe50f343d49943ae17e26b9f824a1ca0/camel_ai-0.2.84-py3-none-any.whl", hash = "sha256:63bfbd09e605f9087bb73eb9b929e162fbc6778084ce50e43a367fc0e98cbc65", size = 1599378, upload-time = "2026-01-20T17:23:11.216Z" }, ] [package.optional-dependencies] @@ -2455,11 +2455,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.8.2" +version = "2.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/93/f2/21d6ca70c3cf35d01ae9e01be534bf6b6b103c157a728082a5028350c310/soupsieve-2.8.2.tar.gz", hash = "sha256:78a66b0fdee2ab40b7199dc3e747ee6c6e231899feeaae0b9b98a353afd48fd8", size = 118601, upload-time = "2026-01-18T16:21:31.09Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/9a/b4450ccce353e2430621b3bb571899ffe1033d5cd72c9e065110f95b1a63/soupsieve-2.8.2-py3-none-any.whl", hash = "sha256:0f4c2f6b5a5fb97a641cf69c0bd163670a0e45e6d6c01a2107f93a6a6f93c51a", size = 37016, upload-time = "2026-01-18T16:21:29.7Z" }, + { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, ] [[package]] diff --git a/electron/main/install-deps.ts b/electron/main/install-deps.ts index e5babcc7..88307d6c 100644 --- a/electron/main/install-deps.ts +++ b/electron/main/install-deps.ts @@ -493,51 +493,64 @@ async function installTerminalBaseVenv(version: string): Promise((resolve, reject) => { - const createVenv = spawn( - uv_path, - ['venv', '--python', '3.10', terminalVenvPath], - { - env: { - ...process.env, - UV_PYTHON_INSTALL_DIR: getCachePath('uv_python'), - }, - } - ); + // Create the venv using uv (skip if only need package install) + if (!needsPackageInstall) { + await new Promise((resolve, reject) => { + const createVenv = spawn( + uv_path, + ['venv', '--python', '3.10', terminalVenvPath], + { + env: { + ...process.env, + UV_PYTHON_INSTALL_DIR: getCachePath('uv_python'), + }, + } + ); - createVenv.stdout.on('data', (data) => { - log.info(`[DEPS INSTALL] terminal venv: ${data}`); + createVenv.stdout.on('data', (data) => { + log.info(`[DEPS INSTALL] terminal venv: ${data}`); + }); + + createVenv.stderr.on('data', (data) => { + log.info(`[DEPS INSTALL] terminal venv: ${data}`); + }); + + createVenv.on('close', (code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`Failed to create terminal venv, exit code: ${code}`)); + } + }); + + createVenv.on('error', reject); }); - - createVenv.stderr.on('data', (data) => { - log.info(`[DEPS INSTALL] terminal venv: ${data}`); - }); - - createVenv.on('close', (code) => { - if (code === 0) { - resolve(); - } else { - reject(new Error(`Failed to create terminal venv, exit code: ${code}`)); - } - }); - - createVenv.on('error', reject); - }); + } // Install base packages log.info('[DEPS INSTALL] Installing terminal base packages...'); @@ -591,6 +604,8 @@ async function installTerminalBaseVenv(version: string): Promise=1.15.2", "openai>=1.99.3,<2", - "camel-ai==0.2.83", + "camel-ai==0.2.84", "pydantic[email]>=2.11.1", "click>=8.1.8", "fastapi>=0.115.12", diff --git a/server/uv.lock b/server/uv.lock index 5cefc7f7..25688bc7 100644 --- a/server/uv.lock +++ b/server/uv.lock @@ -145,7 +145,7 @@ wheels = [ [[package]] name = "camel-ai" -version = "0.2.83" +version = "0.2.84" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "astor" }, @@ -162,9 +162,9 @@ dependencies = [ { name = "tiktoken" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/d1/36f0982862ba2b992968ace43b1c04dd72f7114ce3954342a99e18619d6a/camel_ai-0.2.83.tar.gz", hash = "sha256:c25eb414e9353aab166021852fb54d1d3a0c0e17485fefa996de2cccdf4c8eb9", size = 1125708, upload-time = "2026-01-19T20:37:45.197Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9b/62/96d922750b304ab2dd0ac1ef35dd3fbbf0e9a44f147e08a1ddfeb94c51c6/camel_ai-0.2.84.tar.gz", hash = "sha256:173c79755fc986e3fa8e27523606222c5f8816fc085abb24831912dcd4a0dec3", size = 1125724, upload-time = "2026-01-20T17:23:13.524Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/e2/4e2964059794af9161889223fa7d17630c1bcc74005c9892cd1e1627650c/camel_ai-0.2.83-py3-none-any.whl", hash = "sha256:3a183efdcccd211ae216b2a7903d48a8811ad0f4541223cacc05cb25a11279a6", size = 1599355, upload-time = "2026-01-19T20:37:41.985Z" }, + { url = "https://files.pythonhosted.org/packages/ec/8b/246abd2c47154de6220fd0a286c3fe50f343d49943ae17e26b9f824a1ca0/camel_ai-0.2.84-py3-none-any.whl", hash = "sha256:63bfbd09e605f9087bb73eb9b929e162fbc6778084ce50e43a367fc0e98cbc65", size = 1599378, upload-time = "2026-01-20T17:23:11.216Z" }, ] [[package]] @@ -364,7 +364,7 @@ requires-dist = [ { name = "alembic", specifier = ">=1.15.2" }, { name = "arrow", specifier = ">=1.3.0" }, { name = "bcrypt", specifier = "==4.0.1" }, - { name = "camel-ai", specifier = "==0.2.83" }, + { name = "camel-ai", specifier = "==0.2.84" }, { name = "click", specifier = ">=8.1.8" }, { name = "convert-case", specifier = ">=1.2.3" }, { name = "cryptography", specifier = ">=45.0.4" }, From 88e7cc8c4c8d1a65bdaf04ea80340058402ee3c7 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Wed, 21 Jan 2026 02:19:07 +0800 Subject: [PATCH 51/63] chore: update build file to save storage --- .github/workflows/build-view.yml | 44 +++++++++++++++++++++------- .github/workflows/build.yml | 50 ++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-view.yml b/.github/workflows/build-view.yml index d8d3b8ef..dc79be08 100644 --- a/.github/workflows/build-view.yml +++ b/.github/workflows/build-view.yml @@ -29,26 +29,38 @@ jobs: run: | echo "Disk space before cleanup:" df -h + # Remove Xcode completely (not needed for Electron builds) - saves ~15GB + sudo rm -rf /Applications/Xcode.app || true + sudo rm -rf /Applications/Xcode_*.app || true + # Note: Keep /Library/Developer/CommandLineTools as codesign needs it # Remove iOS simulators - sudo rm -rf ~/Library/Developer/CoreSimulator/Devices/* || true - # Remove watchOS simulators - sudo rm -rf ~/Library/Developer/Xcode/watchOS\ DeviceSupport/* || true - # Remove tvOS simulators - sudo rm -rf ~/Library/Developer/Xcode/tvOS\ DeviceSupport/* || true - # Remove iOS DeviceSupport - sudo rm -rf ~/Library/Developer/Xcode/iOS\ DeviceSupport/* || true - # Remove derived data - sudo rm -rf ~/Library/Developer/Xcode/DerivedData/* || true - # Remove old archives - sudo rm -rf ~/Library/Developer/Xcode/Archives/* || true + sudo rm -rf ~/Library/Developer/CoreSimulator || true + # Remove all Xcode Developer files + sudo rm -rf ~/Library/Developer/Xcode || true + sudo rm -rf /Library/Developer/Xcode || true + # Remove provisioning profiles + sudo rm -rf ~/Library/MobileDevice/Provisioning\ Profiles || true # Remove Android SDK if present sudo rm -rf ~/Library/Android/sdk || true + sudo rm -rf /usr/local/lib/android || true # Remove .NET sudo rm -rf /usr/local/share/dotnet || true + # Remove Go + sudo rm -rf /usr/local/go || true + sudo rm -rf ~/go || true + # Remove Ruby + sudo rm -rf /usr/local/lib/ruby || true + sudo rm -rf ~/.gem || true + # Remove Swift toolchains + sudo rm -rf /Library/Developer/Toolchains || true # Remove Homebrew cache rm -rf ~/Library/Caches/Homebrew/* || true + brew cleanup --prune=all 2>/dev/null || true # Remove npm cache npm cache clean --force || true + # Remove pip cache + pip cache purge 2>/dev/null || true + # Note: Don't delete ~/Library/Caches/* as subsequent steps may need it echo "Disk space after cleanup:" df -h @@ -83,6 +95,16 @@ jobs: sudo apt-get update sudo apt-get install -y libfuse2 + # Verify disk space before build + - name: Check Disk Space Before Build (macOS) + if: runner.os == 'macOS' + run: | + echo "Disk space available before build:" + df -h + echo "" + echo "Largest directories in home:" + du -sh ~/* 2>/dev/null | sort -rh | head -10 || true + # Step for macOS builds with signing - name: Build Release Files (macOS with signing) if: runner.os == 'macOS' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1dd0b679..bca30793 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,6 +35,46 @@ jobs: arch: x64 steps: + - name: Free Disk Space (macOS) + if: runner.os == 'macOS' + run: | + echo "Disk space before cleanup:" + df -h + # Remove Xcode completely (not needed for Electron builds) - saves ~15GB + sudo rm -rf /Applications/Xcode.app || true + sudo rm -rf /Applications/Xcode_*.app || true + # Note: Keep /Library/Developer/CommandLineTools as codesign needs it + # Remove iOS simulators + sudo rm -rf ~/Library/Developer/CoreSimulator || true + # Remove all Xcode Developer files + sudo rm -rf ~/Library/Developer/Xcode || true + sudo rm -rf /Library/Developer/Xcode || true + # Remove provisioning profiles + sudo rm -rf ~/Library/MobileDevice/Provisioning\ Profiles || true + # Remove Android SDK if present + sudo rm -rf ~/Library/Android/sdk || true + sudo rm -rf /usr/local/lib/android || true + # Remove .NET + sudo rm -rf /usr/local/share/dotnet || true + # Remove Go + sudo rm -rf /usr/local/go || true + sudo rm -rf ~/go || true + # Remove Ruby + sudo rm -rf /usr/local/lib/ruby || true + sudo rm -rf ~/.gem || true + # Remove Swift toolchains + sudo rm -rf /Library/Developer/Toolchains || true + # Remove Homebrew cache + rm -rf ~/Library/Caches/Homebrew/* || true + brew cleanup --prune=all 2>/dev/null || true + # Remove npm cache + npm cache clean --force || true + # Remove pip cache + pip cache purge 2>/dev/null || true + # Note: Don't delete ~/Library/Caches/* as subsequent steps may need it + echo "Disk space after cleanup:" + df -h + - name: Checkout Code uses: actions/checkout@v4 @@ -63,6 +103,16 @@ jobs: sudo apt-get update sudo apt-get install -y libfuse2 + # Verify disk space before build + - name: Check Disk Space Before Build (macOS) + if: runner.os == 'macOS' + run: | + echo "Disk space available before build:" + df -h + echo "" + echo "Largest directories in home:" + du -sh ~/* 2>/dev/null | sort -rh | head -10 || true + # Step for macOS builds with signing - name: Build Release Files (macOS with signing) if: runner.os == 'macOS' From 60aa0eb07e6cc98a9197ede2b4c8c9807bceb5bc Mon Sep 17 00:00:00 2001 From: Douglas Lai <115660088+Douglasymlai@users.noreply.github.com> Date: Tue, 20 Jan 2026 18:34:42 +0000 Subject: [PATCH 52/63] Documentation edits made through Mintlify web editor --- docs/core/models/byok.md | 84 +++++++++--------- .../images/Screenshot2026-01-20at18.12.10.png | Bin 0 -> 122319 bytes .../images/Screenshot2026-01-20at18.13.45.png | Bin 0 -> 119859 bytes .../images/Screenshot2026-01-20at18.14.03.png | Bin 0 -> 144176 bytes 4 files changed, 41 insertions(+), 43 deletions(-) create mode 100644 docs/images/Screenshot2026-01-20at18.12.10.png create mode 100644 docs/images/Screenshot2026-01-20at18.13.45.png create mode 100644 docs/images/Screenshot2026-01-20at18.14.03.png diff --git a/docs/core/models/byok.md b/docs/core/models/byok.md index 88a0a86d..99545dc5 100644 --- a/docs/core/models/byok.md +++ b/docs/core/models/byok.md @@ -11,8 +11,6 @@ description: "Configure your own API keys to use various LLM providers with Eige - **Direct access** to the latest models from each provider - **Privacy** - your requests go directly to the provider ---- - ## OpenAI Configuration (Example) ### Step 1: Get Your API Key @@ -23,70 +21,70 @@ description: "Configure your own API keys to use various LLM providers with Eige ### Step 2: Configure in Eigent -1. Launch Eigent and go to **Settings** > **Models** +1. Launch Eigent and go to **Settings** \> **Models** 2. Find the **OpenAI** card in the Custom Model section + + Screenshot 2026 01 20 At 18 13 45 3. Fill in the following fields: -| Field | Value | Example | -|-------|-------|---------| -| **API Key** | Your OpenAI secret key | `sk-proj-xxxx...` | -| **API Host** | OpenAI API endpoint | `https://api.openai.com/v1` | -| **Model Type** | The model you want to use | `gpt-4o`, `gpt-4o-mini` | +| Field | Value | Example | +| -------------- | ------------------------- | --------------------------- | +| **API Key** | Your OpenAI secret key | `sk-proj-xxxx...` | +| **API Host** | OpenAI API endpoint | `https://api.openai.com/v1` | +| **Model Type** | The model you want to use | `gpt-4o`, `gpt-4o-mini` | 4. Click **Save** to validate and store your configuration 5. Click **Set as Default** to use this provider for your agents ---- - ## Configuration Fields -| Field | Description | Required | -|-------|-------------|----------| -| **API Key** | Your authentication key from the provider | Yes | -| **API Host** | The API endpoint URL | Yes (pre-filled for most providers) | -| **Model Type** | The specific model variant to use | Yes | -| **External Config** | Provider-specific settings (e.g., Azure deployment name) | Only for certain providers | +| Field | Description | Required | +| ------------------- | -------------------------------------------------------- | ----------------------------------- | +| **API Key** | Your authentication key from the provider | Yes | +| **API Host** | The API endpoint URL | Yes (pre-filled for most providers) | +| **Model Type** | The specific model variant to use | Yes | +| **External Config** | Provider-specific settings (e.g., Azure deployment name) | Only for certain providers | ### Azure-Specific Fields -| Field | Description | Example | -|-------|-------------|---------| -| **API Version** | Azure OpenAI API version | `2024-02-15-preview` | +| Field | Description | Example | +| ------------------- | -------------------------- | -------------------- | +| **API Version** | Azure OpenAI API version | `2024-02-15-preview` | | **Deployment Name** | Your Azure deployment name | `my-gpt4-deployment` | ---- - ## Common Errors When saving your configuration, Eigent validates your API key and model. Here are the errors you may encounter: -| Error | Cause | Solution | -|-------|-------|----------| -| **Invalid key. Validation failed.** | API key is incorrect, expired, or malformed | Double-check your API key. Regenerate a new key if needed. | -| **Invalid model name. Validation failed.** | The specified model does not exist or is not available for your account | Verify the model name is correct. Check if you have access to that model. | -| **You exceeded your current quota** | API quota exhausted or billing issue | Check your provider's billing dashboard. Add credits or upgrade your plan. | - ---- +| Error | Cause | Solution | +| ------------------------------------------ | ----------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| **Invalid key. Validation failed.** | API key is incorrect, expired, or malformed | Double-check your API key. Regenerate a new key if needed. | +| **Invalid model name. Validation failed.** | The specified model does not exist or is not available for your account | Verify the model name is correct. Check if you have access to that model. | +| **You exceeded your current quota** | API quota exhausted or billing issue | Check your provider's billing dashboard. Add credits or upgrade your plan. | ## Supported Providers Eigent supports the following BYOK providers: -| Provider | Default API Host | Official Documentation | -|----------|------------------|------------------------| -| **OpenAI** | `https://api.openai.com/v1` | [OpenAI API Docs](https://platform.openai.com/docs/api-reference) | -| **Anthropic** | `https://api.anthropic.com/v1/` | [Anthropic API Docs](https://docs.anthropic.com/en/api/getting-started) | -| **Google Gemini** | `https://generativelanguage.googleapis.com/v1beta/openai/` | [Gemini API Docs](https://ai.google.dev/gemini-api/docs) | -| **OpenRouter** | `https://openrouter.ai/api/v1` | [OpenRouter Docs](https://openrouter.ai/docs) | -| **Qwen (Alibaba)** | `https://dashscope.aliyuncs.com/compatible-mode/v1` | [Qwen API Docs](https://help.aliyun.com/zh/dashscope/developer-reference/api-details) | -| **DeepSeek** | `https://api.deepseek.com` | [DeepSeek API Docs](https://platform.deepseek.com/api-docs) | -| **Minimax** | `https://api.minimax.io/v1` | [Minimax API Docs](https://platform.minimaxi.com/document/Announcement) | -| **Z.ai** | `https://api.z.ai/api/coding/paas/v4/` | [Z.ai Platform](https://z.ai) | -| **Azure OpenAI** | *(user-provided)* | [Azure OpenAI Docs](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference) | -| **AWS Bedrock** | *(user-provided)* | [AWS Bedrock Docs](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html) | -| **OpenAI Compatible** | *(user-provided)* | For custom endpoints (e.g., xAI, local servers) | - ---- +| Provider | Default API Host | Official Documentation | +| --------------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| **OpenAI** | `https://api.openai.com/v1` | [OpenAI API Docs](https://platform.openai.com/docs/api-reference) | +| **Anthropic** | `https://api.anthropic.com/v1/` | [Anthropic API Docs](https://docs.anthropic.com/en/api/getting-started) | +| **Google Gemini** | `https://generativelanguage.googleapis.com/v1beta/openai/` | [Gemini API Docs](https://ai.google.dev/gemini-api/docs) | +| **OpenRouter** | `https://openrouter.ai/api/v1` | [OpenRouter Docs](https://openrouter.ai/docs) | +| **Qwen (Alibaba)** | `https://dashscope.aliyuncs.com/compatible-mode/v1` | [Qwen API Docs](https://help.aliyun.com/zh/dashscope/developer-reference/api-details) | +| **DeepSeek** | `https://api.deepseek.com` | [DeepSeek API Docs](https://platform.deepseek.com/api-docs) | +| **Minimax** | `https://api.minimax.io/v1` | [Minimax API Docs](https://platform.minimaxi.com/document/Announcement) | +| **Z.ai** | `https://api.z.ai/api/coding/paas/v4/` | [Z.ai Platform](https://z.ai) | +| **Azure OpenAI** | _(user-provided)_ | [Azure OpenAI Docs](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference) | +| **AWS Bedrock** | _(user-provided)_ | [AWS Bedrock Docs](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html) | +| **OpenAI Compatible** | _(user-provided)_ | For custom endpoints (e.g., xAI, local servers) | ## Tips diff --git a/docs/images/Screenshot2026-01-20at18.12.10.png b/docs/images/Screenshot2026-01-20at18.12.10.png new file mode 100644 index 0000000000000000000000000000000000000000..3ec991438041eb1cee652ab71d2916d5c388ca19 GIT binary patch literal 122319 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 literal 0 HcmV?d00001 diff --git a/docs/images/Screenshot2026-01-20at18.14.03.png b/docs/images/Screenshot2026-01-20at18.14.03.png new file mode 100644 index 0000000000000000000000000000000000000000..fc32b70404154046acc52780515f416703c9b328 GIT binary patch literal 144176 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

{>qZr4=wUi{ak-STZ_M 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 z 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

nJT!i*+kN3v41P8uzzXXO*S*I^6 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 Date: Tue, 20 Jan 2026 18:44:54 +0000 Subject: [PATCH 53/63] Documentation edits made through Mintlify web editor --- docs/core/models/local-model.md | 1 - docs/docs.json | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/core/models/local-model.md b/docs/core/models/local-model.md index b417745b..dcc7592a 100644 --- a/docs/core/models/local-model.md +++ b/docs/core/models/local-model.md @@ -1,7 +1,6 @@ --- title: "Models (Local Model)" description: "Configure and deploy your preferred LLM models with Eigent." -icon: "server" --- ## **Self-Host Model** diff --git a/docs/docs.json b/docs/docs.json index b6bd714b..b475af81 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -65,10 +65,10 @@ "icon": "brain", "expanded": true, "pages": [ + "/core/models/byok", + "/core/models/local-model", "/core/models/gemini", - "/core/models/minimax", - "/core/models/local-model" - "/core/models/byok" + "/core/models/minimax" ] }, "/core/tools", From be8068442ef6b893351ada68d21eca5415df1de2 Mon Sep 17 00:00:00 2001 From: Wendong-Fan <133094783+Wendong-Fan@users.noreply.github.com> Date: Tue, 20 Jan 2026 19:06:39 +0000 Subject: [PATCH 54/63] Update WeChat QR code via QR Code Updater MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Automated update --- src/assets/wechat_qr.jpg | Bin 183714 -> 167105 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/assets/wechat_qr.jpg b/src/assets/wechat_qr.jpg index f495c69baf1c2b4c4ef6dad15e73ec3bb29c10ab..0d92ed47ac2d17e896cae7072a04fbec2b92822a 100644 GIT binary patch literal 167105 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ξVLx3{g2%U_1?WV`Esi2 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 literal 183714 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 From f25537b0994faa88f7da5a0b36ee6ab762e6f4ad Mon Sep 17 00:00:00 2001 From: Puzhen Zhang <91596298+nitpicker55555@users.noreply.github.com> Date: Tue, 20 Jan 2026 19:20:06 +0000 Subject: [PATCH 55/63] Fix/reassign completion report browser (#990) Co-authored-by: Wendong-Fan Co-authored-by: Wendong-Fan <133094783+Wendong-Fan@users.noreply.github.com> --- .github/workflows/build.yml | 22 ++++ backend/app/service/chat_service.py | 4 - .../utils/toolkit/hybrid_browser_toolkit.py | 110 ++++++++++++++++++ backend/app/utils/workforce.py | 5 + 4 files changed, 137 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bca30793..60b93cb0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,6 +72,28 @@ jobs: # Remove pip cache pip cache purge 2>/dev/null || true # Note: Don't delete ~/Library/Caches/* as subsequent steps may need it + + # Additional cleanup for more disk space + # Remove hosted tool cache (can be several GB) + sudo rm -rf /Users/runner/hostedtoolcache || true + sudo rm -rf /opt/hostedtoolcache || true + # Remove browsers (not needed for Electron builds) + sudo rm -rf "/Applications/Google Chrome.app" || true + sudo rm -rf "/Applications/Firefox.app" || true + sudo rm -rf "/Applications/Safari Technology Preview.app" || true + # Remove PowerShell + sudo rm -rf /usr/local/microsoft/powershell || true + sudo rm -rf /usr/local/share/powershell || true + # Remove more from /usr/local + sudo rm -rf /usr/local/aws-cli || true + sudo rm -rf /usr/local/julia* || true + sudo rm -rf /usr/local/miniconda || true + # Remove unused large directories + sudo rm -rf /usr/share/swift || true + sudo rm -rf /usr/share/miniconda || true + # Remove Docker images if present + docker system prune -af 2>/dev/null || true + echo "Disk space after cleanup:" df -h diff --git a/backend/app/service/chat_service.py b/backend/app/service/chat_service.py index e37f9aa2..a9fdda99 100644 --- a/backend/app/service/chat_service.py +++ b/backend/app/service/chat_service.py @@ -1301,10 +1301,6 @@ You are a helpful coordinator. - You are now working in system {platform.system()} with architecture {platform.machine()} at working directory `{working_directory}`. All local file operations must occur here, but you can access files from any place in the file system. For all file system operations, you MUST use absolute paths to ensure precision and avoid ambiguity. The current date is {datetime.date.today()}. For any date-related tasks, you MUST use this as the current date. - -- If a task assigned to another agent fails, you should re-assign it to the -`Developer_Agent`. The `Developer_Agent` is a powerful agent with terminal -access and can resolve a wide range of issues. """, Agents.task_agent: f""" You are a helpful task planner. diff --git a/backend/app/utils/toolkit/hybrid_browser_toolkit.py b/backend/app/utils/toolkit/hybrid_browser_toolkit.py index 1c87d699..67705222 100644 --- a/backend/app/utils/toolkit/hybrid_browser_toolkit.py +++ b/backend/app/utils/toolkit/hybrid_browser_toolkit.py @@ -1,6 +1,7 @@ import os import asyncio import json +import uuid from typing import Any, Dict, List, Optional from typing_extensions import TypedDict import websockets @@ -19,6 +20,14 @@ from utils import traceroot_wrapper as traceroot logger = traceroot.get_logger("hybrid_browser_toolkit") +# Global navigation lock to prevent concurrent visit_page conflicts (ERR_ABORTED) +# This is needed because multiple sessions may share the same browser via CDP +_global_navigation_lock = asyncio.Lock() + +# Global registry: tab_id -> session_id (ensures each tab belongs to only one session) +_global_tab_registry: Dict[str, str] = {} +_global_tab_registry_lock = asyncio.Lock() + class SheetCell(TypedDict): row: int @@ -31,6 +40,9 @@ class WebSocketBrowserWrapper(BaseWebSocketBrowserWrapper): """Initialize wrapper.""" super().__init__(config) logger.info(f"WebSocketBrowserWrapper using ts_dir: {self.ts_dir}") + # Track tabs opened by this session for isolation + self._session_tab_ids: set = set() + self._wrapper_session_id: str = str(uuid.uuid4()) def _ensure_local_no_proxy(self) -> None: local_hosts = ["localhost", "127.0.0.1", "::1"] @@ -143,6 +155,100 @@ class WebSocketBrowserWrapper(BaseWebSocketBrowserWrapper): logger.error(f"Unexpected error sending command '{command}': {type(e).__name__}: {e}") raise + async def visit_page(self, url: str) -> Dict[str, Any]: + """Override visit_page to add global navigation lock preventing ERR_ABORTED. + + Multiple sessions sharing the same browser via CDP can cause conflicts + when they try to navigate simultaneously (e.g., both trying to use a + blank page). This lock serializes navigation operations at the WebSocket + wrapper level. + """ + global _global_navigation_lock + + async with _global_navigation_lock: + logger.debug(f"[visit_page] Acquired navigation lock, navigating to {url}") + try: + result = await super().visit_page(url) + logger.debug(f"[visit_page] Navigation completed, releasing lock") + return result + except Exception as e: + logger.error(f"[visit_page] Navigation failed: {e}") + raise + + async def get_tab_info(self) -> List[Dict[str, Any]]: + """Override get_tab_info to track and filter tabs for session isolation. + + Automatically tracks the current tab (is_current=true) as belonging to + this session, then filters to only return tabs owned by this session. + Uses global registry to ensure each tab belongs to only one session. + """ + global _global_tab_registry, _global_tab_registry_lock + + all_tabs = await super().get_tab_info() + session_id = self._wrapper_session_id # Stable UUID for this wrapper + + # Auto-track: add current tab to this session's tracked tabs (with global lock) + current_tab = next((t for t in all_tabs if t.get('is_current')), + None) + if current_tab and current_tab.get('tab_id'): + tab_id = current_tab['tab_id'] + async with _global_tab_registry_lock: + # Only track if not already owned by another session + if tab_id not in _global_tab_registry: + _global_tab_registry[tab_id] = session_id + self._session_tab_ids.add(tab_id) + logger.info( + f"[Session Tab Tracking] Auto-tracked current tab: {tab_id}, session {session_id} now has tabs: {self._session_tab_ids}") + elif _global_tab_registry[tab_id] == session_id: + # Already owned by this session, ensure local tracking + self._session_tab_ids.add(tab_id) + + # Filter: only return tabs belonging to this session + filtered_tabs = [tab for tab in all_tabs if + tab.get('tab_id') in self._session_tab_ids] + logger.info( + f"[Session Tab Filtering] Session {session_id}: Returning {len(filtered_tabs)}/{len(all_tabs)} tabs, tracked: {self._session_tab_ids}") + + return filtered_tabs + + async def close_tab(self, tab_id: str) -> Dict[str, Any]: + """Override close_tab to update tracking.""" + global _global_tab_registry, _global_tab_registry_lock + + result = await super().close_tab(tab_id) + + # Remove from tracking if it was ours + if tab_id in self._session_tab_ids: + self._session_tab_ids.discard(tab_id) + async with _global_tab_registry_lock: + if tab_id in _global_tab_registry: + del _global_tab_registry[tab_id] + logger.info( + f"[Session Tab Tracking] Removed closed tab: {tab_id}, session now has tabs: {self._session_tab_ids}") + + return result + + async def cleanup_tab_tracking(self): + """Clean up all tab tracking for this session from the global registry. + + Should be called when the wrapper is being stopped/destroyed to prevent + memory leaks and stale entries in the global registry. + """ + global _global_tab_registry, _global_tab_registry_lock + + if not self._session_tab_ids: + return + + async with _global_tab_registry_lock: + cleaned_count = len(self._session_tab_ids) + for tab_id in list(self._session_tab_ids): + if tab_id in _global_tab_registry: + del _global_tab_registry[tab_id] + # Clear inside lock to prevent race with concurrent get_tab_info + self._session_tab_ids.clear() + logger.info( + f"[Session Tab Tracking] Cleaned up {cleaned_count} tabs for session {self._wrapper_session_id}") + # WebSocket connection pool class WebSocketConnectionPool: @@ -190,6 +296,7 @@ class WebSocketConnectionPool: # Connection is unhealthy, clean it up logger.info(f"Removing unhealthy WebSocket connection for session {session_id}") try: + await wrapper.cleanup_tab_tracking() await wrapper.stop() except Exception as e: logger.debug(f"Error stopping unhealthy wrapper: {e}") @@ -209,6 +316,7 @@ class WebSocketConnectionPool: if session_id in self._connections: wrapper = self._connections[session_id] try: + await wrapper.cleanup_tab_tracking() await wrapper.stop() except Exception as e: logger.error(f"Error closing WebSocket connection for session {session_id}: {e}") @@ -220,6 +328,7 @@ class WebSocketConnectionPool: if session_id in self._connections: wrapper = self._connections[session_id] try: + await wrapper.cleanup_tab_tracking() await wrapper.stop() except Exception as e: logger.error(f"Error closing WebSocket connection for session {session_id}: {e}") @@ -237,6 +346,7 @@ class WebSocketConnectionPool: # Global connection pool instance websocket_connection_pool = WebSocketConnectionPool() + @auto_listen_toolkit(BaseHybridBrowserToolkit) class HybridBrowserToolkit(BaseHybridBrowserToolkit, AbstractToolkit): agent_name: str = Agents.browser_agent diff --git a/backend/app/utils/workforce.py b/backend/app/utils/workforce.py index 362eb0d4..8cb34615 100644 --- a/backend/app/utils/workforce.py +++ b/backend/app/utils/workforce.py @@ -450,6 +450,11 @@ class Workforce(BaseWorkforce): result = await super()._handle_failed_task(task) + # Only send completion report to frontend when all retries are exhausted + max_retries = self.failure_handling_config.max_retries + if task.failure_count < max_retries: + return result + error_message = "" # Use proper CAMEL pattern for metrics logging metrics_callbacks = [cb for cb in self._callbacks if isinstance(cb, WorkforceMetrics)] From db0ee803ed2b50b7ac4c0561165f475e3700fc22 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Wed, 21 Jan 2026 03:40:38 +0800 Subject: [PATCH 56/63] chore: hide unrelated folder in agent folder --- electron/main/fileReader.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/electron/main/fileReader.ts b/electron/main/fileReader.ts index 91a06977..680a812d 100644 --- a/electron/main/fileReader.ts +++ b/electron/main/fileReader.ts @@ -514,6 +514,15 @@ export class FileReader { }) } + // Folders to hide in the Agent Folder view + private readonly hiddenFolders = [ + 'browser_agent', + 'developer_agent', + 'document_agent', + 'multi_modal_agent', + 'terminal_logs' + ]; + private getFilesRecursive(dirPath: string, basePath: string): FileInfo[] { try { const files = fs.readdirSync(dirPath); @@ -521,6 +530,8 @@ export class FileReader { for (const file of files) { if (file.startsWith(".")) continue; + // Skip hidden folders + if (this.hiddenFolders.includes(file)) continue; const filePath = path.join(dirPath, file); const stats = fs.statSync(filePath); From 55e824900d1dd942128e1bc19923a89341b98176 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Wed, 21 Jan 2026 05:52:08 +0800 Subject: [PATCH 57/63] chore: update build config remove ubuntu building --- .github/workflows/build-view.yml | 76 ++++++++++++++++---------------- .github/workflows/build.yml | 58 ++++++++++++------------ 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/.github/workflows/build-view.yml b/.github/workflows/build-view.yml index dc79be08..145a2ca5 100644 --- a/.github/workflows/build-view.yml +++ b/.github/workflows/build-view.yml @@ -20,8 +20,8 @@ jobs: arch: x64 - os: windows-latest arch: x64 - - os: ubuntu-latest - arch: x64 + # - os: ubuntu-latest + # arch: x64 steps: - name: Free Disk Space (macOS) @@ -89,11 +89,11 @@ jobs: run: npm install # Install libfuse2 for Linux AppImage builds - - name: Install libfuse2 (Linux) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install -y libfuse2 + # - name: Install libfuse2 (Linux) + # if: runner.os == 'Linux' + # run: | + # sudo apt-get update + # sudo apt-get install -y libfuse2 # Verify disk space before build - name: Check Disk Space Before Build (macOS) @@ -138,17 +138,17 @@ jobs: USE_NPM_INSTALL_BUN: 'true' # Step for Linux builds - - name: Build Release Files (Linux) - if: runner.os == 'Linux' - timeout-minutes: 90 - run: npm run build:linux - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} - VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} - VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} - VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} - USE_NPM_INSTALL_BUN: 'true' + # - name: Build Release Files (Linux) + # if: runner.os == 'Linux' + # timeout-minutes: 90 + # run: npm run build:linux + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} + # VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} + # VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} + # VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} + # USE_NPM_INSTALL_BUN: 'true' - name: Upload Artifact (macOS - dmg only) if: runner.os == 'macOS' @@ -168,21 +168,21 @@ jobs: release/*.exe retention-days: 5 - - name: Upload Artifact (Linux - AppImage only) - if: runner.os == 'Linux' - uses: actions/upload-artifact@v6 - with: - name: release-${{ matrix.os }}-${{ matrix.arch }} - path: | - release/*.AppImage - retention-days: 5 + # - name: Upload Artifact (Linux - AppImage only) + # if: runner.os == 'Linux' + # uses: actions/upload-artifact@v6 + # with: + # name: release-${{ matrix.os }}-${{ matrix.arch }} + # path: | + # release/*.AppImage + # retention-days: 5 merge-release: needs: build runs-on: ubuntu-latest steps: - name: Create directories run: | - mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 release/linux-x64 + mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 # Download all artifacts with correct names - name: Download mac-x64 artifact @@ -203,11 +203,11 @@ jobs: name: release-windows-latest-x64 path: temp-win-x64 - - name: Download linux-x64 artifact - uses: actions/download-artifact@v7 - with: - name: release-ubuntu-latest-x64 - path: temp-linux-x64 + # - name: Download linux-x64 artifact + # uses: actions/download-artifact@v7 + # with: + # name: release-ubuntu-latest-x64 + # path: temp-linux-x64 # Move only dmg files for macOS, exe files for Windows, and AppImage for Linux - name: Move files to clean folders @@ -234,9 +234,9 @@ jobs: find temp-win-x64 -name "*.exe" -exec mv {} release/win-x64/ \; || true fi - # linux-x64 - only move AppImage files - if [ -d "temp-linux-x64/release" ]; then - find temp-linux-x64/release -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true - else - find temp-linux-x64 -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true - fi + # # linux-x64 - only move AppImage files + # if [ -d "temp-linux-x64/release" ]; then + # find temp-linux-x64/release -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true + # else + # find temp-linux-x64 -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true + # fi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 60b93cb0..ca9a7769 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,8 +31,8 @@ jobs: arch: x64 - os: windows-latest arch: x64 - - os: ubuntu-latest - arch: x64 + # - os: ubuntu-latest + # arch: x64 steps: - name: Free Disk Space (macOS) @@ -119,11 +119,11 @@ jobs: run: npm install # Install libfuse2 for Linux AppImage builds - - name: Install libfuse2 (Linux) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install -y libfuse2 + # - name: Install libfuse2 (Linux) + # if: runner.os == 'Linux' + # run: | + # sudo apt-get update + # sudo apt-get install -y libfuse2 # Verify disk space before build - name: Check Disk Space Before Build (macOS) @@ -164,15 +164,15 @@ jobs: VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} # Step for Linux builds - - name: Build Release Files (Linux) - if: runner.os == 'Linux' - run: npm run build:linux - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} - VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} - VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} - VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} + # - name: Build Release Files (Linux) + # if: runner.os == 'Linux' + # run: npm run build:linux + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} + # VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} + # VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} + # VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} - name: Upload Artifact uses: actions/upload-artifact@v6 @@ -189,7 +189,7 @@ jobs: steps: - name: Create directories run: | - mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 release/linux-x64 + mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 # Download all artifacts with correct names - name: Download mac-x64 artifact @@ -210,11 +210,11 @@ jobs: name: release-windows-latest-x64 path: temp-win-x64 - - name: Download linux-x64 artifact - uses: actions/download-artifact@v7 - with: - name: release-ubuntu-latest-x64 - path: temp-linux-x64 + # - name: Download linux-x64 artifact + # uses: actions/download-artifact@v7 + # with: + # name: release-ubuntu-latest-x64 + # path: temp-linux-x64 # Move files to final release directory, removing any nested release/ directory - name: Move files to clean folders @@ -241,12 +241,12 @@ jobs: mv temp-win-x64/* release/win-x64/ || true fi - # linux-x64 - if [ -d "temp-linux-x64/release" ]; then - mv temp-linux-x64/release/* release/linux-x64/ || true - else - mv temp-linux-x64/* release/linux-x64/ || true - fi + # # linux-x64 + # if [ -d "temp-linux-x64/release" ]; then + # mv temp-linux-x64/release/* release/linux-x64/ || true + # else + # mv temp-linux-x64/* release/linux-x64/ || true + # fi - name: Rename duplicate files run: | @@ -262,6 +262,6 @@ jobs: release/mac-x64/* release/mac-arm64/* release/win-x64/* - release/linux-x64/* + # release/linux-x64/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From abfc5c0970f29a79bf524e831c98bd8333c69db6 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Wed, 21 Jan 2026 07:23:38 +0800 Subject: [PATCH 58/63] Revert "chore: update build config remove ubuntu building" This reverts commit 55e824900d1dd942128e1bc19923a89341b98176. --- .github/workflows/build-view.yml | 76 ++++++++++++++++---------------- .github/workflows/build.yml | 58 ++++++++++++------------ 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/.github/workflows/build-view.yml b/.github/workflows/build-view.yml index 145a2ca5..dc79be08 100644 --- a/.github/workflows/build-view.yml +++ b/.github/workflows/build-view.yml @@ -20,8 +20,8 @@ jobs: arch: x64 - os: windows-latest arch: x64 - # - os: ubuntu-latest - # arch: x64 + - os: ubuntu-latest + arch: x64 steps: - name: Free Disk Space (macOS) @@ -89,11 +89,11 @@ jobs: run: npm install # Install libfuse2 for Linux AppImage builds - # - name: Install libfuse2 (Linux) - # if: runner.os == 'Linux' - # run: | - # sudo apt-get update - # sudo apt-get install -y libfuse2 + - name: Install libfuse2 (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y libfuse2 # Verify disk space before build - name: Check Disk Space Before Build (macOS) @@ -138,17 +138,17 @@ jobs: USE_NPM_INSTALL_BUN: 'true' # Step for Linux builds - # - name: Build Release Files (Linux) - # if: runner.os == 'Linux' - # timeout-minutes: 90 - # run: npm run build:linux - # env: - # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} - # VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} - # VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} - # VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} - # USE_NPM_INSTALL_BUN: 'true' + - name: Build Release Files (Linux) + if: runner.os == 'Linux' + timeout-minutes: 90 + run: npm run build:linux + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} + VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} + VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} + VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} + USE_NPM_INSTALL_BUN: 'true' - name: Upload Artifact (macOS - dmg only) if: runner.os == 'macOS' @@ -168,21 +168,21 @@ jobs: release/*.exe retention-days: 5 - # - name: Upload Artifact (Linux - AppImage only) - # if: runner.os == 'Linux' - # uses: actions/upload-artifact@v6 - # with: - # name: release-${{ matrix.os }}-${{ matrix.arch }} - # path: | - # release/*.AppImage - # retention-days: 5 + - name: Upload Artifact (Linux - AppImage only) + if: runner.os == 'Linux' + uses: actions/upload-artifact@v6 + with: + name: release-${{ matrix.os }}-${{ matrix.arch }} + path: | + release/*.AppImage + retention-days: 5 merge-release: needs: build runs-on: ubuntu-latest steps: - name: Create directories run: | - mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 + mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 release/linux-x64 # Download all artifacts with correct names - name: Download mac-x64 artifact @@ -203,11 +203,11 @@ jobs: name: release-windows-latest-x64 path: temp-win-x64 - # - name: Download linux-x64 artifact - # uses: actions/download-artifact@v7 - # with: - # name: release-ubuntu-latest-x64 - # path: temp-linux-x64 + - name: Download linux-x64 artifact + uses: actions/download-artifact@v7 + with: + name: release-ubuntu-latest-x64 + path: temp-linux-x64 # Move only dmg files for macOS, exe files for Windows, and AppImage for Linux - name: Move files to clean folders @@ -234,9 +234,9 @@ jobs: find temp-win-x64 -name "*.exe" -exec mv {} release/win-x64/ \; || true fi - # # linux-x64 - only move AppImage files - # if [ -d "temp-linux-x64/release" ]; then - # find temp-linux-x64/release -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true - # else - # find temp-linux-x64 -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true - # fi + # linux-x64 - only move AppImage files + if [ -d "temp-linux-x64/release" ]; then + find temp-linux-x64/release -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true + else + find temp-linux-x64 -name "*.AppImage" -exec mv {} release/linux-x64/ \; || true + fi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ca9a7769..60b93cb0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,8 +31,8 @@ jobs: arch: x64 - os: windows-latest arch: x64 - # - os: ubuntu-latest - # arch: x64 + - os: ubuntu-latest + arch: x64 steps: - name: Free Disk Space (macOS) @@ -119,11 +119,11 @@ jobs: run: npm install # Install libfuse2 for Linux AppImage builds - # - name: Install libfuse2 (Linux) - # if: runner.os == 'Linux' - # run: | - # sudo apt-get update - # sudo apt-get install -y libfuse2 + - name: Install libfuse2 (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y libfuse2 # Verify disk space before build - name: Check Disk Space Before Build (macOS) @@ -164,15 +164,15 @@ jobs: VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} # Step for Linux builds - # - name: Build Release Files (Linux) - # if: runner.os == 'Linux' - # run: npm run build:linux - # env: - # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} - # VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} - # VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} - # VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} + - name: Build Release Files (Linux) + if: runner.os == 'Linux' + run: npm run build:linux + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VITE_BASE_URL: ${{ secrets.VITE_BASE_URL }} + VITE_STACK_PROJECT_ID: ${{ secrets.VITE_STACK_PROJECT_ID }} + VITE_STACK_PUBLISHABLE_CLIENT_KEY: ${{ secrets.VITE_STACK_PUBLISHABLE_CLIENT_KEY }} + VITE_STACK_SECRET_SERVER_KEY: ${{ secrets.VITE_STACK_SECRET_SERVER_KEY }} - name: Upload Artifact uses: actions/upload-artifact@v6 @@ -189,7 +189,7 @@ jobs: steps: - name: Create directories run: | - mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 + mkdir -p release/mac-x64 release/mac-arm64 release/win-x64 release/linux-x64 # Download all artifacts with correct names - name: Download mac-x64 artifact @@ -210,11 +210,11 @@ jobs: name: release-windows-latest-x64 path: temp-win-x64 - # - name: Download linux-x64 artifact - # uses: actions/download-artifact@v7 - # with: - # name: release-ubuntu-latest-x64 - # path: temp-linux-x64 + - name: Download linux-x64 artifact + uses: actions/download-artifact@v7 + with: + name: release-ubuntu-latest-x64 + path: temp-linux-x64 # Move files to final release directory, removing any nested release/ directory - name: Move files to clean folders @@ -241,12 +241,12 @@ jobs: mv temp-win-x64/* release/win-x64/ || true fi - # # linux-x64 - # if [ -d "temp-linux-x64/release" ]; then - # mv temp-linux-x64/release/* release/linux-x64/ || true - # else - # mv temp-linux-x64/* release/linux-x64/ || true - # fi + # linux-x64 + if [ -d "temp-linux-x64/release" ]; then + mv temp-linux-x64/release/* release/linux-x64/ || true + else + mv temp-linux-x64/* release/linux-x64/ || true + fi - name: Rename duplicate files run: | @@ -262,6 +262,6 @@ jobs: release/mac-x64/* release/mac-arm64/* release/win-x64/* - # release/linux-x64/* + release/linux-x64/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 9fbdd1ca97ec17091aafdc27728360f245971e26 Mon Sep 17 00:00:00 2001 From: Wendong-Fan Date: Wed, 21 Jan 2026 07:48:40 +0800 Subject: [PATCH 59/63] update build yml --- .github/workflows/build-view.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/build-view.yml b/.github/workflows/build-view.yml index dc79be08..178fa43e 100644 --- a/.github/workflows/build-view.yml +++ b/.github/workflows/build-view.yml @@ -61,6 +61,28 @@ jobs: # Remove pip cache pip cache purge 2>/dev/null || true # Note: Don't delete ~/Library/Caches/* as subsequent steps may need it + + # Additional cleanup for more disk space + # Remove hosted tool cache (can be several GB) + sudo rm -rf /Users/runner/hostedtoolcache || true + sudo rm -rf /opt/hostedtoolcache || true + # Remove browsers (not needed for Electron builds) + sudo rm -rf "/Applications/Google Chrome.app" || true + sudo rm -rf "/Applications/Firefox.app" || true + sudo rm -rf "/Applications/Safari Technology Preview.app" || true + # Remove PowerShell + sudo rm -rf /usr/local/microsoft/powershell || true + sudo rm -rf /usr/local/share/powershell || true + # Remove more from /usr/local + sudo rm -rf /usr/local/aws-cli || true + sudo rm -rf /usr/local/julia* || true + sudo rm -rf /usr/local/miniconda || true + # Remove unused large directories + sudo rm -rf /usr/share/swift || true + sudo rm -rf /usr/share/miniconda || true + # Remove Docker images if present + docker system prune -af 2>/dev/null || true + echo "Disk space after cleanup:" df -h From 24b785ef81060488f85d61ebcb187dcf1b8e03b0 Mon Sep 17 00:00:00 2001 From: Wendong-Fan <133094783+Wendong-Fan@users.noreply.github.com> Date: Wed, 21 Jan 2026 09:51:43 +0800 Subject: [PATCH 60/63] chore: futher add more time for running (#994) --- backend/app/component/model_validation.py | 4 ++-- backend/app/controller/chat_controller.py | 4 ++-- backend/app/service/chat_service.py | 2 +- backend/app/service/task.py | 2 +- backend/app/utils/agent.py | 4 +++- backend/app/utils/workforce.py | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/backend/app/component/model_validation.py b/backend/app/component/model_validation.py index d734ab92..c0b52ea6 100644 --- a/backend/app/component/model_validation.py +++ b/backend/app/component/model_validation.py @@ -29,7 +29,7 @@ def create_agent( model_type=mtype, api_key=api_key, url=url, - timeout=10, + timeout=60, # 1 minute for validation model_config_dict=model_config_dict, **kwargs, ) @@ -37,6 +37,6 @@ def create_agent( system_message="You are a helpful assistant that must use the tool get_website_content to get the content of a website.", model=model, tools=[get_website_content], - step_timeout=900, + step_timeout=1800, # 30 minutes ) return agent diff --git a/backend/app/controller/chat_controller.py b/backend/app/controller/chat_controller.py index b3aef085..b3b8db9a 100644 --- a/backend/app/controller/chat_controller.py +++ b/backend/app/controller/chat_controller.py @@ -36,8 +36,8 @@ router = APIRouter() # Create traceroot logger for chat controller chat_logger = traceroot.get_logger("chat_controller") -# SSE timeout configuration (30 minutes in seconds) -SSE_TIMEOUT_SECONDS = 30 * 60 +# SSE timeout configuration (60 minutes in seconds) +SSE_TIMEOUT_SECONDS = 60 * 60 async def _cleanup_task_lock_safe(task_lock, reason: str) -> bool: diff --git a/backend/app/service/chat_service.py b/backend/app/service/chat_service.py index a9fdda99..04accf8b 100644 --- a/backend/app/service/chat_service.py +++ b/backend/app/service/chat_service.py @@ -154,7 +154,7 @@ def collect_previous_task_context(working_directory: str, previous_task_content: return "\n".join(context_parts) -def check_conversation_history_length(task_lock: TaskLock, max_length: int = 100000) -> tuple[bool, int]: +def check_conversation_history_length(task_lock: TaskLock, max_length: int = 200000) -> tuple[bool, int]: """ Check if conversation history exceeds maximum length diff --git a/backend/app/service/task.py b/backend/app/service/task.py index 1d9bb76b..d4958dd9 100644 --- a/backend/app/service/task.py +++ b/backend/app/service/task.py @@ -503,7 +503,7 @@ async def _periodic_cleanup(): await asyncio.sleep(300) # Run every 5 minutes current_time = datetime.now() - stale_timeout = timedelta(hours=2) # Consider tasks stale after 2 hours + stale_timeout = timedelta(hours=4) # Consider tasks stale after 4 hours stale_ids = [] for task_id, task_lock in task_locks.items(): diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index fa4bee25..91ef926e 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -173,7 +173,7 @@ class ListenChatAgent(ChatAgent): pause_event: asyncio.Event | None = None, prune_tool_calls_from_memory: bool = False, enable_snapshot_clean: bool = False, - step_timeout: float | None = 900, + step_timeout: float | None = 1800, # 30 minutes **kwargs: Any, ) -> None: super().__init__( @@ -805,6 +805,7 @@ def agent_model( api_key=options.api_key, url=options.api_url, model_config_dict=model_config or None, + timeout=600, # 10 minutes **init_params, ) @@ -1855,6 +1856,7 @@ async def mcp_agent(options: Chat): if options.is_cloud() else None ), + timeout=600, # 10 minutes **{ k: v for k, v in (options.extra_params or {}).items() diff --git a/backend/app/utils/workforce.py b/backend/app/utils/workforce.py index 8cb34615..363e6462 100644 --- a/backend/app/utils/workforce.py +++ b/backend/app/utils/workforce.py @@ -61,7 +61,7 @@ class Workforce(BaseWorkforce): graceful_shutdown_timeout=graceful_shutdown_timeout, share_memory=share_memory, use_structured_output_handler=use_structured_output_handler, - task_timeout_seconds=1800, # 30 minutes + task_timeout_seconds=3600, # 60 minutes failure_handling_config=FailureHandlingConfig( enabled_strategies=["retry", "replan"], ), From 3593caf6f64c65af7824a39a52b40ca484970bc8 Mon Sep 17 00:00:00 2001 From: Dream <42954461+eureka928@users.noreply.github.com> Date: Wed, 21 Jan 2026 02:30:35 -0500 Subject: [PATCH 61/63] feat: add Storybook for UI components (#137) (#955) --- .gitignore | 3 + .storybook/main.ts | 13 + .storybook/preview.tsx | 47 +++ .storybook/storybook.css | 1 + package.json | 10 +- src/components/ui/button.stories.tsx | 223 ++++++++++++ src/components/ui/dialog.stories.tsx | 512 +++++++++++++++++++++++++++ src/components/ui/input.stories.tsx | 291 +++++++++++++++ src/components/ui/input.tsx | 25 +- tailwind.config.js | 2 +- 10 files changed, 1112 insertions(+), 15 deletions(-) create mode 100644 .storybook/main.ts create mode 100644 .storybook/preview.tsx create mode 100644 .storybook/storybook.css create mode 100644 src/components/ui/button.stories.tsx create mode 100644 src/components/ui/dialog.stories.tsx create mode 100644 src/components/ui/input.stories.tsx diff --git a/.gitignore b/.gitignore index 6b6bff22..719583e8 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ __pycache__/ resources/prebuilt/bin/ resources/prebuilt/venv/ resources/prebuilt/cache/ + +*storybook.log +storybook-static diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 00000000..301640e5 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,13 @@ +import type { StorybookConfig } from '@storybook/react-vite' + +const config: StorybookConfig = { + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + addons: ['@storybook/addon-docs', '@storybook/addon-a11y'], + framework: '@storybook/react-vite', + viteFinal: async (config) => { + // Reuse project's vite config for path aliases + return config + }, +} + +export default config diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 00000000..4142d6db --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,47 @@ +import type { Preview } from '@storybook/react-vite' +import React from 'react' +import '@fontsource/inter/400.css' +import '@fontsource/inter/500.css' +import '@fontsource/inter/600.css' +import '@fontsource/inter/700.css' +import '@fontsource/inter/800.css' +import '../src/style/index.css' +import './storybook.css' // Storybook-specific overrides +import { Toaster } from 'sonner' + +// Apply theme immediately via script +if (typeof document !== 'undefined') { + document.documentElement.setAttribute('data-theme', 'light') + document.documentElement.classList.add('root') +} + +const preview: Preview = { + tags: ['autodocs'], + parameters: { + layout: 'centered', + controls: { + expanded: true, + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + backgrounds: { + default: 'light', + values: [ + { name: 'light', value: '#f5f5f5' }, + { name: 'dark', value: '#1d1c1b' }, + ], + }, + }, + decorators: [ + (Story) => ( +

+ ), + ], +} + +export default preview diff --git a/.storybook/storybook.css b/.storybook/storybook.css new file mode 100644 index 00000000..6e0e8f28 --- /dev/null +++ b/.storybook/storybook.css @@ -0,0 +1 @@ +/* Storybook-specific CSS overrides - currently empty as component handles styling */ diff --git a/package.json b/package.json index 9cdd6453..dd7170c4 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,9 @@ "test:watch": "vitest", "test:e2e": "vitest run --config vitest.config.ts", "test:coverage": "vitest run --coverage", - "type-check": "tsc --noEmit" + "type-check": "tsc --noEmit", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build -o storybook-static" }, "dependencies": { "@electron/notarize": "^2.5.0", @@ -131,7 +133,11 @@ "vite": "^5.4.11", "vite-plugin-electron": "^0.29.0", "vite-plugin-electron-renderer": "^0.14.6", - "vitest": "^2.1.5" + "vitest": "^2.1.5", + "storybook": "^10.1.11", + "@storybook/react-vite": "^10.1.11", + "@storybook/addon-a11y": "^10.1.11", + "@storybook/addon-docs": "^10.1.11" }, "overrides": { "glob": "^10.4.5" diff --git a/src/components/ui/button.stories.tsx b/src/components/ui/button.stories.tsx new file mode 100644 index 00000000..0ae56ba1 --- /dev/null +++ b/src/components/ui/button.stories.tsx @@ -0,0 +1,223 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' +import { Button } from './button' +import { Plus, Download, Trash2 } from 'lucide-react' +import { expect, fn, userEvent, within } from 'storybook/test' + +const meta: Meta = { + title: 'UI/Button', + component: Button, + argTypes: { + variant: { + control: 'select', + options: [ + 'primary', + 'secondary', + 'outline', + 'ghost', + 'success', + 'cuation', + 'information', + 'warning', + ], + }, + size: { + control: 'select', + options: ['xxs', 'xs', 'sm', 'md', 'lg', 'icon'], + }, + disabled: { + control: 'boolean', + }, + asChild: { + control: 'boolean', + }, + children: { + control: 'text', + }, + }, + args: { + children: 'Button', + variant: 'primary', + size: 'md', + }, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = { + args: { + variant: 'primary', + children: 'Primary Button', + }, +} + +export const Secondary: Story = { + args: { + variant: 'secondary', + children: 'Secondary Button', + }, +} + +export const Outline: Story = { + args: { + variant: 'outline', + children: 'Outline Button', + }, +} + +export const Ghost: Story = { + args: { + variant: 'ghost', + children: 'Ghost Button', + }, +} + +export const Success: Story = { + args: { + variant: 'success', + children: 'Success Button', + }, +} + +export const Warning: Story = { + args: { + variant: 'warning', + children: 'Warning Button', + }, +} + +export const Disabled: Story = { + args: { + variant: 'primary', + children: 'Disabled Button', + disabled: true, + }, +} + +export const WithIcon: Story = { + render: (args) => ( + + ), + args: { + variant: 'primary', + }, +} + +export const IconOnly: Story = { + render: (args) => ( + + ), + args: { + variant: 'ghost', + size: 'icon', + }, +} + +export const AllVariants: Story = { + render: () => ( +
+ + + + + + +
+ ), +} + +export const AllSizes: Story = { + render: () => ( +
+ + + + + + +
+ ), +} + +// Interaction test stories +export const ClickInteraction: Story = { + args: { + variant: 'primary', + children: 'Click Me', + onClick: fn(), + }, + play: async ({ args, canvasElement }) => { + const canvas = within(canvasElement) + const button = canvas.getByRole('button', { name: /click me/i }) + + // Test that button is visible and enabled + await expect(button).toBeVisible() + await expect(button).toBeEnabled() + + // Click the button + await userEvent.click(button) + + // Verify the onClick handler was called + await expect(args.onClick).toHaveBeenCalledTimes(1) + }, +} + +export const DisabledInteraction: Story = { + args: { + variant: 'primary', + children: 'Disabled Button', + disabled: true, + onClick: fn(), + }, + play: async ({ args, canvasElement }) => { + const canvas = within(canvasElement) + const button = canvas.getByRole('button', { name: /disabled button/i }) + + // Test that button is visible but disabled + await expect(button).toBeVisible() + await expect(button).toBeDisabled() + + // Verify the onClick handler was NOT called (disabled buttons block pointer events) + await expect(args.onClick).not.toHaveBeenCalled() + }, +} + +export const HoverInteraction: Story = { + args: { + variant: 'outline', + children: 'Hover Over Me', + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement) + const button = canvas.getByRole('button', { name: /hover over me/i }) + + // Test initial state + await expect(button).toBeVisible() + + // Hover over the button + await userEvent.hover(button) + + // The button should still be visible after hover + await expect(button).toBeVisible() + + // Unhover + await userEvent.unhover(button) + }, +} diff --git a/src/components/ui/dialog.stories.tsx b/src/components/ui/dialog.stories.tsx new file mode 100644 index 00000000..0a151d4e --- /dev/null +++ b/src/components/ui/dialog.stories.tsx @@ -0,0 +1,512 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' +import { useState } from 'react' +import { + Dialog, + DialogTrigger, + DialogContent, + DialogHeader, + DialogContentSection, + DialogFooter, +} from './dialog' +import { Button } from './button' +import { Input } from './input' +import { expect, userEvent, within } from 'storybook/test' + +const meta: Meta = { + title: 'UI/Dialog', + component: Dialog, +} + +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: function DefaultDialog() { + const [open, setOpen] = useState(false) + return ( + + + + + + + +

+ This is the main content area of the dialog. You can add any content + here including forms, text, images, or other components. +

+
+ setOpen(false)} + onConfirm={() => { + console.log('Confirmed!') + setOpen(false) + }} + /> +
+
+ ) + }, +} + +export const SmallSize: Story = { + render: function SmallDialog() { + const [open, setOpen] = useState(false) + return ( + + + + + + + +

A compact dialog for simple actions.

+
+ setOpen(false)} + /> +
+
+ ) + }, +} + +export const LargeSize: Story = { + render: function LargeDialog() { + const [open, setOpen] = useState(false) + return ( + + + + + + + +

+ Large dialogs are useful when you need to display more content, such + as detailed forms, tables, or multi-step processes. +

+
+ setOpen(false)} + onConfirm={() => setOpen(false)} + /> +
+
+ ) + }, +} + +export const WithForm: Story = { + render: function FormDialog() { + const [open, setOpen] = useState(false) + return ( + + + + + + + +
+ + + +
+
+ setOpen(false)} + onConfirm={() => { + console.log('Account created!') + setOpen(false) + }} + /> +
+
+ ) + }, +} + +export const WithTooltip: Story = { + render: function TooltipDialog() { + const [open, setOpen] = useState(false) + return ( + + + + + + + +

+ Hover over the icon next to the title to see the tooltip. +

+
+ setOpen(false)} + /> +
+
+ ) + }, +} + +export const WithBackButton: Story = { + render: function BackButtonDialog() { + const [open, setOpen] = useState(false) + return ( + + + + + + console.log('Back clicked')} + /> + +

+ Click the back button to return to the previous step. +

+
+ setOpen(false)} + onConfirm={() => { + console.log('Next step') + setOpen(false) + }} + /> +
+
+ ) + }, +} + +export const DestructiveAction: Story = { + render: function DestructiveDialog() { + const [open, setOpen] = useState(false) + return ( + + + + + + + +

+ Are you sure you want to delete this item? All associated data will + be permanently removed. +

+
+ setOpen(false)} + onConfirm={() => { + console.log('Item deleted!') + setOpen(false) + }} + /> +
+
+ ) + }, +} + +export const NoCloseButton: Story = { + render: function NoCloseDialog() { + const [open, setOpen] = useState(false) + return ( + + + + + + + +

+ This dialog does not have a close button. User must interact with + the footer buttons. +

+
+ setOpen(false)} + /> +
+
+ ) + }, +} + +export const AllSizes: Story = { + render: function AllSizesDialog() { + const [openSm, setOpenSm] = useState(false) + const [openMd, setOpenMd] = useState(false) + const [openLg, setOpenLg] = useState(false) + return ( +
+ + + + + + + +

Max width: 400px

+
+ setOpenSm(false)} + /> +
+
+ + + + + + + + +

Max width: 600px (default)

+
+ setOpenMd(false)} + /> +
+
+ + + + + + + + +

Max width: 900px

+
+ setOpenLg(false)} + /> +
+
+
+ ) + }, +} + +// Interaction test stories +export const OpenCloseInteraction: Story = { + render: function OpenCloseDialog() { + const [open, setOpen] = useState(false) + return ( + + + + + + + +

+ This dialog tests the open/close interaction. +

+
+ setOpen(false)} + onConfirm={() => setOpen(false)} + /> +
+
+ ) + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement) + const body = within(document.body) + + // Open the dialog + await userEvent.click(canvas.getByRole('button', { name: /open dialog/i })) + + // Verify dialog is visible (renders in portal) + await expect(await body.findByText('Interactive Dialog')).toBeVisible() + + // Close the dialog + await userEvent.click(body.getByRole('button', { name: /cancel/i })) + + // Verify dialog is closed + await expect(body.queryByText('Interactive Dialog')).not.toBeInTheDocument() + }, +} + +export const FormInteraction: Story = { + render: function FormInteractionDialog() { + const [open, setOpen] = useState(false) + const [submitted, setSubmitted] = useState(false) + return ( +
+ + + + + + + +
+ + +
+
+ setOpen(false)} + onConfirm={() => { + setSubmitted(true) + setOpen(false) + }} + /> +
+
+ {submitted &&

Form submitted successfully!

} +
+ ) + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement) + const body = within(document.body) + + // Open the dialog + await userEvent.click(canvas.getByRole('button', { name: /open form/i })) + + // Wait for dialog to appear (renders in portal) + await expect(await body.findByText('Sign Up')).toBeVisible() + + // Fill in the form + const nameInput = body.getByPlaceholderText('Enter your name') + const emailInput = body.getByPlaceholderText('Enter your email') + + await userEvent.type(nameInput, 'John Doe') + await userEvent.type(emailInput, 'john@example.com') + + // Verify inputs have values + await expect(nameInput).toHaveValue('John Doe') + await expect(emailInput).toHaveValue('john@example.com') + + // Submit the form + await userEvent.click(body.getByRole('button', { name: /sign up/i })) + + // Verify success message appears + await expect(await canvas.findByTestId('success-message')).toBeVisible() + }, +} + +export const ConfirmDialogInteraction: Story = { + render: function ConfirmInteractionDialog() { + const [open, setOpen] = useState(false) + const [confirmed, setConfirmed] = useState(false) + return ( +
+ + + + + + + +

+ Are you sure you want to delete this item? +

+
+ setOpen(false)} + onConfirm={() => { + setConfirmed(true) + setOpen(false) + }} + /> +
+
+ {confirmed &&

Item deleted!

} +
+ ) + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement) + const body = within(document.body) + + // Open the confirmation dialog + await userEvent.click(canvas.getByRole('button', { name: /delete item/i })) + + // Verify dialog is visible (renders in portal) + await expect(await body.findByText('Confirm Delete')).toBeVisible() + + // Click the confirm/delete button + await userEvent.click(body.getByRole('button', { name: /^delete$/i })) + + // Verify the deleted message appears + const deletedMessage = await canvas.findByTestId('deleted-message') + await expect(deletedMessage).toHaveTextContent('Item deleted!') + }, +} diff --git a/src/components/ui/input.stories.tsx b/src/components/ui/input.stories.tsx new file mode 100644 index 00000000..047affa4 --- /dev/null +++ b/src/components/ui/input.stories.tsx @@ -0,0 +1,291 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' +import { Input } from './input' +import { Search, Eye, EyeOff } from 'lucide-react' +import { useState } from 'react' +import { expect, fn, userEvent, within } from 'storybook/test' + +const meta: Meta = { + title: 'UI/Input', + component: Input, + argTypes: { + size: { + control: 'select', + options: ['default', 'sm'], + }, + state: { + control: 'select', + options: ['default', 'hover', 'input', 'error', 'success', 'disabled'], + }, + disabled: { + control: 'boolean', + }, + required: { + control: 'boolean', + }, + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} + +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + placeholder: 'Enter text...', + }, +} + +export const WithTitle: Story = { + args: { + title: 'Email Address', + placeholder: 'name@example.com', + type: 'email', + }, +} + +export const Required: Story = { + args: { + title: 'Username', + placeholder: 'Enter username', + required: true, + }, +} + +export const WithTooltip: Story = { + args: { + title: 'API Key', + placeholder: 'Enter your API key', + tooltip: 'Your API key can be found in your account settings', + }, +} + +export const WithNote: Story = { + args: { + title: 'Password', + type: 'password', + placeholder: 'Enter password', + note: 'Must be at least 8 characters', + }, +} + +export const ErrorState: Story = { + args: { + title: 'Email', + placeholder: 'name@example.com', + state: 'error', + note: 'Please enter a valid email address', + defaultValue: 'invalid-email', + }, +} + +export const SuccessState: Story = { + args: { + title: 'Username', + placeholder: 'Enter username', + state: 'success', + note: 'Username is available', + defaultValue: 'johndoe', + }, +} + +export const Disabled: Story = { + args: { + title: 'Locked Field', + placeholder: 'This field is disabled', + disabled: true, + defaultValue: 'Cannot edit', + }, +} + +export const SmallSize: Story = { + args: { + size: 'sm', + placeholder: 'Small input', + }, +} + +export const WithLeadingIcon: Story = { + args: { + placeholder: 'Search...', + leadingIcon: , + }, +} + +export const WithBackIcon: Story = { + render: function PasswordInput() { + const [showPassword, setShowPassword] = useState(false) + return ( + : } + onBackIconClick={() => setShowPassword(!showPassword)} + /> + ) + }, +} + +export const AllStates: Story = { + render: () => ( +
+ + + + + + +
+ ), +} + +export const FormExample: Story = { + render: () => ( +
+

Contact Form

+ + + + +
+ ), + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} + +// Interaction test stories +export const TypeInteraction: Story = { + args: { + placeholder: 'Type something...', + onChange: fn(), + }, + play: async ({ args, canvasElement }) => { + const canvas = within(canvasElement) + const input = canvas.getByPlaceholderText('Type something...') + + // Test that input is visible and enabled + await expect(input).toBeVisible() + await expect(input).toBeEnabled() + + // Clear any existing value and type new text + await userEvent.clear(input) + await userEvent.type(input, 'Hello World') + + // Verify the input value + await expect(input).toHaveValue('Hello World') + + // Verify onChange was called + await expect(args.onChange).toHaveBeenCalled() + }, +} + +export const FocusInteraction: Story = { + args: { + title: 'Focus Test', + placeholder: 'Click to focus...', + onFocus: fn(), + onBlur: fn(), + }, + play: async ({ args, canvasElement }) => { + const canvas = within(canvasElement) + const input = canvas.getByPlaceholderText('Click to focus...') + + // Click to focus the input + await userEvent.click(input) + await expect(args.onFocus).toHaveBeenCalled() + + // Tab away to blur + await userEvent.tab() + await expect(args.onBlur).toHaveBeenCalled() + }, +} + +export const ClearAndTypeInteraction: Story = { + args: { + title: 'Edit Field', + placeholder: 'Edit this text', + defaultValue: 'Initial value', + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement) + const input = canvas.getByPlaceholderText('Edit this text') + + // Verify initial value + await expect(input).toHaveValue('Initial value') + + // Select all and replace + await userEvent.tripleClick(input) + await userEvent.type(input, 'Replaced text') + + // Verify the new value + await expect(input).toHaveValue('Replaced text') + }, +} + +export const PasswordToggleInteraction: Story = { + render: function PasswordToggle() { + const [showPassword, setShowPassword] = useState(false) + return ( + : } + onBackIconClick={() => setShowPassword(!showPassword)} + /> + ) + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement) + const input = canvas.getByPlaceholderText('Enter password') + const toggleButton = canvas.getByRole('button') + + // Initially password should be hidden (type="password") + await expect(input).toHaveAttribute('type', 'password') + + // Click toggle to show password + await userEvent.click(toggleButton) + await expect(input).toHaveAttribute('type', 'text') + + // Click toggle again to hide password + await userEvent.click(toggleButton) + await expect(input).toHaveAttribute('type', 'password') + }, +} diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx index a8534db9..7efc37c9 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/input.tsx @@ -31,47 +31,47 @@ function resolveStateClasses(state: InputState | undefined) { if (state === "disabled") { return { container: "opacity-50 cursor-not-allowed", - field: - "border-input-border-default bg-input-bg-default text-input-text-default", + field: "border-input-border-default bg-input-bg-default", + input: "text-text-heading", placeholder: "placeholder-input-label-default", } } if (state === "hover") { return { container: "", - field: - "border-input-border-hover bg-input-bg-default text-input-text-default", + field: "border-input-border-hover bg-input-bg-default", + input: "text-text-heading", placeholder: "placeholder-input-label-default", } } if (state === "input") { return { container: "", - field: - "border-input-border-focus bg-input-bg-input text-input-text-focus", + field: "border-input-border-focus bg-input-bg-input", + input: "text-text-heading", placeholder: "placeholder-input-label-default", } } if (state === "error") { return { container: "", - field: - "border-input-border-cuation bg-input-bg-default text-text-body", + field: "border-input-border-cuation bg-input-bg-default", + input: "text-text-heading", placeholder: "placeholder-input-label-default", } } if (state === "success") { return { container: "", - field: - "border-input-border-success bg-input-bg-confirm text-text-body", + field: "border-input-border-success bg-input-bg-confirm", + input: "text-text-heading", placeholder: "placeholder-input-label-default", } } return { container: "", - field: - "border-input-border-default bg-input-bg-default text-input-text-default", + field: "border-input-border-default bg-input-bg-default", + input: "text-text-heading", placeholder: "placeholder-input-label-default/10", } } @@ -140,6 +140,7 @@ const Input = React.forwardRef( placeholder={placeholder} className={cn( "peer w-full bg-transparent outline-none placeholder:transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium", + stateCls.input, stateCls.placeholder, hasLeft ? "pl-9" : "pl-3", hasRight ? "pr-9" : "pr-3", diff --git a/tailwind.config.js b/tailwind.config.js index cb0e2014..29f90933 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,7 +1,7 @@ /** @type {import('tailwindcss').Config} */ module.exports = { darkMode: ["class"], - content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], + content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}", "./.storybook/**/*.{js,ts,jsx,tsx}"], theme: { extend: { colors: { From 604c096efc2c2c6077c4ed9da8393ecb406f9565 Mon Sep 17 00:00:00 2001 From: Douglas Lai <115660088+Douglasymlai@users.noreply.github.com> Date: Wed, 21 Jan 2026 09:39:10 +0000 Subject: [PATCH 62/63] update browser agent (#787) --- .../BrowserAgentWrokSpace/index.tsx | 404 ++++++++++++++++++ .../TerminalAgentWrokSpace/index.tsx | 2 +- src/components/WorkFlow/index.tsx | 2 +- src/components/WorkFlow/node.tsx | 2 +- src/i18n/locales/ar/dashboard.json | 2 +- src/i18n/locales/de/dashboard.json | 2 +- src/i18n/locales/en-us/dashboard.json | 2 +- src/i18n/locales/es/dashboard.json | 2 +- src/i18n/locales/fr/dashboard.json | 2 +- src/i18n/locales/it/dashboard.json | 2 +- src/i18n/locales/ja/dashboard.json | 2 +- src/i18n/locales/ko/dashboard.json | 2 +- src/i18n/locales/ru/dashboard.json | 2 +- src/i18n/locales/zh-Hans/dashboard.json | 2 +- src/i18n/locales/zh-Hant/dashboard.json | 2 +- src/pages/Home.tsx | 2 +- test/mocks/sse.mock.ts | 2 +- 17 files changed, 420 insertions(+), 16 deletions(-) create mode 100644 src/components/BrowserAgentWrokSpace/index.tsx diff --git a/src/components/BrowserAgentWrokSpace/index.tsx b/src/components/BrowserAgentWrokSpace/index.tsx new file mode 100644 index 00000000..ab46b4f1 --- /dev/null +++ b/src/components/BrowserAgentWrokSpace/index.tsx @@ -0,0 +1,404 @@ +import { useEffect, useState, useRef } from "react"; +import { + ArrowDown, + ArrowUp, + Bird, + Bot, + ChevronLeft, + CodeXml, + FileText, + GalleryThumbnails, + Globe, + Hand, + Image, + Settings2, +} from "lucide-react"; +import { Button } from "../ui/button"; +import { fetchPut } from "@/api/http"; +import { TaskState } from "../TaskState"; +import useChatStoreAdapter from "@/hooks/useChatStoreAdapter"; + +export default function Home() { + //Get Chatstore for the active project's task + const { chatStore, projectStore } = useChatStoreAdapter(); + if (!chatStore) { + return
Loading...
; + } + + const [isSingleMode, setIsSingleMode] = useState(false); + const scrollContainerRef = useRef(null); + + const agentMap = { + developer_agent: { + name: "Developer Agent", + icon: , + textColor: "text-emerald-700", + bgColor: "bg-bg-fill-coding-active", + shapeColor: "bg-bg-fill-coding-default", + borderColor: "border-bg-fill-coding-active", + bgColorLight: "bg-emerald-200", + }, + browser_agent: { + name: "Browser agent", + icon: , + textColor: "text-blue-700", + bgColor: "bg-bg-fill-browser-active", + shapeColor: "bg-bg-fill-browser-default", + borderColor: "border-bg-fill-browser-active", + bgColorLight: "bg-blue-200", + }, + document_agent: { + name: "Document Agent", + icon: , + textColor: "text-yellow-700", + bgColor: "bg-bg-fill-writing-active", + shapeColor: "bg-bg-fill-writing-default", + borderColor: "border-bg-fill-writing-active", + bgColorLight: "bg-yellow-200", + }, + multi_modal_agent: { + name: "Multi Modal Agent", + icon: , + textColor: "text-fuchsia-700", + bgColor: "bg-bg-fill-multimodal-active", + shapeColor: "bg-bg-fill-multimodal-default", + borderColor: "border-bg-fill-multimodal-active", + bgColorLight: "bg-fuchsia-200", + }, + social_medium_agent: { + name: "Social Media Agent", + icon: , + textColor: "text-purple-700", + bgColor: "bg-violet-700", + shapeColor: "bg-violet-300", + borderColor: "border-violet-700", + bgColorLight: "bg-purple-50", + }, + }; + const [activeAgent, setActiveAgent] = useState(null); + useEffect(() => { + const taskAssigning = + chatStore.tasks[chatStore.activeTaskId as string]?.taskAssigning; + if (taskAssigning) { + const activeAgent = taskAssigning.find( + (item) => + item.agent_id === + chatStore.tasks[chatStore.activeTaskId as string]?.activeWorkSpace + ); + setActiveAgent(() => { + if (activeAgent) { + return activeAgent; + } + return null; + }); + } + }, [ + chatStore.tasks[chatStore.activeTaskId as string].taskAssigning, + chatStore.tasks[chatStore.activeTaskId as string].activeWorkSpace, + ]); + + const [isTakeControl, setIsTakeControl] = useState(false); + const handleTakeControl = (id: string) => { + console.log("handleTakeControl", id); + fetchPut(`/task/${projectStore.activeProjectId}/take-control`, { + action: "pause", + }); + + setIsTakeControl(true); + setTimeout(() => { + getSize(); + // show corresponding webview + window.electronAPI.showWebview(id); + }, 400); + }; + + // listen to webview container size + useEffect(() => { + if (!projectStore.activeProjectId) { + projectStore.createProject("new project"); + console.warn("No active projectId found in WorkSpace, creating a new project"); + } + + const webviewContainer = document.getElementById("webview-container"); + if (webviewContainer) { + const resizeObserver = new ResizeObserver(() => { + getSize(); + }); + resizeObserver.observe(webviewContainer); + + return () => { + resizeObserver.disconnect(); + }; + } + }, []); + const getSize = () => { + const webviewContainer = document.getElementById("webview-container"); + if (webviewContainer) { + const rect = webviewContainer.getBoundingClientRect(); + window.electronAPI.setSize({ + x: rect.left, + y: rect.top, + width: rect.width, + height: rect.height, + }); + } + }; + + const [url, setUrl] = useState(""); + + useEffect(() => { + window.ipcRenderer?.on("url-updated", (_event, newUrl) => { + setUrl(newUrl); + }); + + // optional: clear listener when uninstall + return () => { + window.ipcRenderer.removeAllListeners("url-updated"); + }; + }, []); + + return isTakeControl ? ( +
+
+
+ +
+ {/*
{url}
*/} +
+
+
+ ) : ( +
+
+
+
+ +
+ {agentMap[activeAgent?.type as keyof typeof agentMap]?.name} +
+ task.reAssignTo).length || + 0 + } + done={ + activeAgent?.tasks?.filter( + (task) => task.status === "completed" + ).length || 0 + } + progress={ + activeAgent?.tasks?.filter( + (task) => + task.status !== "failed" && + task.status !== "completed" && + task.status !== "skipped" && + task.status !== "waiting" + ).length || 0 + } + failed={ + activeAgent?.tasks?.filter((task) => task.status === "failed") + .length || 0 + } + skipped={ + activeAgent?.tasks?.filter( + (task) => + task.status === "skipped" || task.status === "waiting" + ).length || 0 + } + /> + {/*
+ { + activeAgent?.tasks?.filter( + (task) => task.status && task.status !== "running" + ).length + } + /{activeAgent?.tasks?.length} +
*/} +
+ {/*
+ +
*/} +
+ + {activeAgent?.activeWebviewIds?.length === 1 ? ( +
+ {activeAgent?.activeWebviewIds[0]?.img && ( +
+ handleTakeControl( + activeAgent?.activeWebviewIds?.[0]?.id || "" + ) + } + className="cursor-pointer relative h-full w-full group pt-sm rounded-b-2xl" + > + +
+ +
+
+ )} +
+ ) : ( +
+ {activeAgent?.activeWebviewIds + ?.filter((item) => item?.img) + .map((item, index) => { + return ( +
handleTakeControl(item.id)} + className={`cursor-pointer relative card-box rounded-lg group ${ + isSingleMode + ? "h-[calc(100%)] w-[calc(100%)]" + : "h-[calc(50%-8px)] w-[calc(50%-8px)]" + }`} + > + {item.img && ( + + )} +
+ handleTakeControl( + activeAgent?.activeWebviewIds?.[0]?.id || "" + ) + } + className="flex justify-center items-center opacity-0 transition-all group-hover:opacity-100 rounded-lg absolute inset-0 w-full h-full bg-black/20 pointer-events-none" + > + +
+
+ ); + })} +
+ )} + {activeAgent?.activeWebviewIds?.length !== 1 && ( +
+ + + +
+ )} +
+
+ ); +} \ No newline at end of file diff --git a/src/components/TerminalAgentWrokSpace/index.tsx b/src/components/TerminalAgentWrokSpace/index.tsx index a4111f75..d445627f 100644 --- a/src/components/TerminalAgentWrokSpace/index.tsx +++ b/src/components/TerminalAgentWrokSpace/index.tsx @@ -332,4 +332,4 @@ export default function TerminalAgentWrokSpace() {
); -} +} \ No newline at end of file diff --git a/src/components/WorkFlow/index.tsx b/src/components/WorkFlow/index.tsx index b5f6ea46..05d260f2 100644 --- a/src/components/WorkFlow/index.tsx +++ b/src/components/WorkFlow/index.tsx @@ -459,4 +459,4 @@ export default function Workflow({ ); -} +} \ No newline at end of file diff --git a/src/components/WorkFlow/node.tsx b/src/components/WorkFlow/node.tsx index a897f6a5..30b261ab 100644 --- a/src/components/WorkFlow/node.tsx +++ b/src/components/WorkFlow/node.tsx @@ -894,4 +894,4 @@ export function Node({ id, data }: NodeProps) { /> ); -} +} \ No newline at end of file diff --git a/src/i18n/locales/ar/dashboard.json b/src/i18n/locales/ar/dashboard.json index d309d0e6..d3ff55ee 100644 --- a/src/i18n/locales/ar/dashboard.json +++ b/src/i18n/locales/ar/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "وكيل متعدد الوسائط", "social-media-agent": "وكيل وسائل التواصل الاجتماعي", "no-projects-found": "لا توجد مشاريع" -} +} \ No newline at end of file diff --git a/src/i18n/locales/de/dashboard.json b/src/i18n/locales/de/dashboard.json index 40aa684a..874790cb 100644 --- a/src/i18n/locales/de/dashboard.json +++ b/src/i18n/locales/de/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "Multi-Modal-Agent", "social-media-agent": "Social-Media-Agent", "no-projects-found": "Keine Projekte gefunden." -} +} \ No newline at end of file diff --git a/src/i18n/locales/en-us/dashboard.json b/src/i18n/locales/en-us/dashboard.json index 9ccaa218..36ef5df8 100644 --- a/src/i18n/locales/en-us/dashboard.json +++ b/src/i18n/locales/en-us/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "Multi Modal Agent", "social-media-agent": "Social Media Agent", "no-projects-found": "No projects found." -} +} \ No newline at end of file diff --git a/src/i18n/locales/es/dashboard.json b/src/i18n/locales/es/dashboard.json index 515ca1f5..f16d4efa 100644 --- a/src/i18n/locales/es/dashboard.json +++ b/src/i18n/locales/es/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "Agente Multi Modal", "social-media-agent": "Agente de Redes Sociales", "no-projects-found": "No se encontraron proyectos." -} +} \ No newline at end of file diff --git a/src/i18n/locales/fr/dashboard.json b/src/i18n/locales/fr/dashboard.json index e9a79b77..9e411645 100644 --- a/src/i18n/locales/fr/dashboard.json +++ b/src/i18n/locales/fr/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "Agent Multi Modal", "social-media-agent": "Agent de Médias Sociaux", "no-projects-found": "Aucun projet trouvé." -} +} \ No newline at end of file diff --git a/src/i18n/locales/it/dashboard.json b/src/i18n/locales/it/dashboard.json index a0184cc2..fa15eb04 100644 --- a/src/i18n/locales/it/dashboard.json +++ b/src/i18n/locales/it/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "Agente Multi Modale", "social-media-agent": "Agente Social Media", "no-projects-found": "Nessun progetto trovato." -} +} \ No newline at end of file diff --git a/src/i18n/locales/ja/dashboard.json b/src/i18n/locales/ja/dashboard.json index 0b6435fe..f8e271bd 100644 --- a/src/i18n/locales/ja/dashboard.json +++ b/src/i18n/locales/ja/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "マルチモーダルエージェント", "social-media-agent": "ソーシャルメディアエージェント", "no-projects-found": "プロジェクトが見つかりませんでした。" -} +} \ No newline at end of file diff --git a/src/i18n/locales/ko/dashboard.json b/src/i18n/locales/ko/dashboard.json index 0338ea41..c9df3b28 100644 --- a/src/i18n/locales/ko/dashboard.json +++ b/src/i18n/locales/ko/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "멀티모달 에이전트", "social-media-agent": "소셜미디어 에이전트", "no-projects-found": "프로젝트를 찾을 수 없습니다." -} +} \ No newline at end of file diff --git a/src/i18n/locales/ru/dashboard.json b/src/i18n/locales/ru/dashboard.json index 88d03427..bcaec242 100644 --- a/src/i18n/locales/ru/dashboard.json +++ b/src/i18n/locales/ru/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "Мультимодальный агент", "social-media-agent": "Агент социальных сетей", "no-projects-found": "Проекты не найдены" -} +} \ No newline at end of file diff --git a/src/i18n/locales/zh-Hans/dashboard.json b/src/i18n/locales/zh-Hans/dashboard.json index acd0203b..c194b609 100644 --- a/src/i18n/locales/zh-Hans/dashboard.json +++ b/src/i18n/locales/zh-Hans/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "多模态智能体", "social-media-agent": "社交媒体智能体", "no-projects-found": "没有找到项目" -} +} \ No newline at end of file diff --git a/src/i18n/locales/zh-Hant/dashboard.json b/src/i18n/locales/zh-Hant/dashboard.json index 7659a839..4445ca00 100644 --- a/src/i18n/locales/zh-Hant/dashboard.json +++ b/src/i18n/locales/zh-Hant/dashboard.json @@ -24,4 +24,4 @@ "multi-modal-agent": "多模態智能體", "social-media-agent": "社群媒體智能體", "no-projects-found": "沒有找到專案" -} +} \ No newline at end of file diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 70585e2c..dae2740d 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -208,7 +208,7 @@ export default function Home() {
- )} + )} {chatStore.tasks[chatStore.activeTaskId as string] ?.activeWorkSpace === "workflow" && (
diff --git a/test/mocks/sse.mock.ts b/test/mocks/sse.mock.ts index eb8ff527..b56a0fb7 100644 --- a/test/mocks/sse.mock.ts +++ b/test/mocks/sse.mock.ts @@ -324,4 +324,4 @@ export const issue619SseSequence = [ }, delay: 1100 } -]; +]; \ No newline at end of file From 6683a54abb9fe0e258a59f1351419b22a568e8c4 Mon Sep 17 00:00:00 2001 From: Douglas Lai <115660088+Douglasymlai@users.noreply.github.com> Date: Wed, 21 Jan 2026 09:40:23 +0000 Subject: [PATCH 63/63] Electron style (#800) --- electron/main/index.ts | 35 +++- electron/main/native/macos-window.ts | 171 ++++++++++++++++++ package.json | 1 + .../InstallStep/InstallDependencies.tsx | 2 +- src/components/Layout/index.tsx | 1 - src/components/Navigation/index.tsx | 2 +- src/components/TopBar/index.tsx | 2 +- src/components/ui/input.tsx | 2 +- src/components/ui/select.tsx | 8 +- src/pages/Dashboard/Browser.tsx | 2 +- src/pages/Setting/MCP.tsx | 2 +- src/style/token.css | 2 +- 12 files changed, 209 insertions(+), 21 deletions(-) create mode 100644 electron/main/native/macos-window.ts diff --git a/electron/main/index.ts b/electron/main/index.ts index 1261ec42..7b3c1d45 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -34,12 +34,9 @@ import { zipFolder } from './utils/log'; import mime from 'mime'; import axios from 'axios'; import FormData from 'form-data'; -import { - checkAndInstallDepsOnUpdate, - PromiseReturnType, - getInstallationStatus, -} from './install-deps'; -import { isBinaryExists, getBackendPath, getVenvPath } from './utils/process'; +import { checkAndInstallDepsOnUpdate, PromiseReturnType, getInstallationStatus } from './install-deps' +import { isBinaryExists, getBackendPath, getVenvPath } from './utils/process' +import { setVibrancy, setRoundedCorners, setTransparentTitlebar } from './native/macos-window' const userData = app.getPath('userData'); @@ -1279,9 +1276,7 @@ async function createWindow() { minHeight: 650, frame: false, transparent: true, - vibrancy: 'sidebar', - visualEffectState: 'active', - backgroundColor: '#f5f5f580', + backgroundColor: '#00000000', titleBarStyle: isMac ? 'hidden' : undefined, trafficLightPosition: isMac ? { x: 10, y: 10 } : undefined, icon: path.join(VITE_PUBLIC, 'favicon.ico'), @@ -1299,6 +1294,28 @@ async function createWindow() { }, }); + // Apply native macOS effects + if (process.platform === 'darwin') { + win.once('ready-to-show', () => { + if (win && !win.isDestroyed()) { + try { + // Apply vibrancy with HUDWindow material (or others like 'Sidebar', 'UnderWindowBackground') + setVibrancy(win, 'HUDWindow'); + + // Apply rounded corners + setRoundedCorners(win, 20); + + // Make titlebar transparent + setTransparentTitlebar(win); + + log.info('[MacOS] Applied native visual effects'); + } catch (error) { + log.error('[MacOS] Failed to apply native visual effects:', error); + } + } + }); + } + // Main window now uses default userData directly with partition 'persist:main_window' // No migration needed - data is already persistent diff --git a/electron/main/native/macos-window.ts b/electron/main/native/macos-window.ts new file mode 100644 index 00000000..7a81e01e --- /dev/null +++ b/electron/main/native/macos-window.ts @@ -0,0 +1,171 @@ +import { BrowserWindow } from 'electron'; +import koffi from 'koffi'; +import os from 'os'; + +// NSVisualEffectView material constants (enum values) +export const NSVisualEffectMaterial = { + Titlebar: 3, + Selection: 4, + Menu: 5, + Popover: 6, + Sidebar: 7, + HeaderView: 10, + Sheet: 11, + WindowBackground: 12, + HUDWindow: 13, + FullScreenUI: 15, + ToolTip: 17, + ContentBackground: 18, + UnderWindowBackground: 21, + UnderPageBackground: 22 +} as const; + +export type MaterialType = keyof typeof NSVisualEffectMaterial; + +// Interface for our module functions +interface MacWindowUtils { + setVibrancy: (window: BrowserWindow, material?: MaterialType) => void; + setRoundedCorners: (window: BrowserWindow, radius?: number) => void; + setTransparentTitlebar: (window: BrowserWindow) => void; +} + +let utils: MacWindowUtils; + +if (os.platform() === 'darwin') { + try { + const objc = koffi.load('libobjc.A.dylib'); + + // Types + const Ptr = 'size_t'; + + const objc_getClass = objc.func('objc_getClass', Ptr, ['string']); + const sel_registerName = objc.func('sel_registerName', Ptr, ['string']); + const objc_msgSend = objc.func('objc_msgSend', Ptr, [Ptr, Ptr]); + const objc_msgSend_long = objc.func('objc_msgSend', Ptr, [Ptr, Ptr, 'long']); + const objc_msgSend_double = objc.func('objc_msgSend', Ptr, [Ptr, Ptr, 'double']); + const objc_msgSend_bool = objc.func('objc_msgSend', Ptr, [Ptr, Ptr, 'bool']); + + const NSRect = koffi.struct('NSRect', { + x: 'double', + y: 'double', + width: 'double', + height: 'double' + }); + + const NSVisualEffectBlendingMode = { + BehindWindow: 0, + WithinWindow: 1 + }; + + utils = { + setVibrancy: (window: BrowserWindow, material: MaterialType = 'HUDWindow') => { + try { + const windowHandle = window.getNativeWindowHandle(); + if (windowHandle.length === 0) return; + + // Electron calls valid native handle returns the NSView (BridgedContentView) on macOS + const nsViewPtr = windowHandle.readBigUInt64LE(); + if (!nsViewPtr) return; + + // Selectors + const selAlloc = sel_registerName('alloc'); + const selInit = sel_registerName('init'); + const selSetMaterial = sel_registerName('setMaterial:'); + const selSetBlendingMode = sel_registerName('setBlendingMode:'); + const selSetState = sel_registerName('setState:'); + const selSetAutoresizingMask = sel_registerName('setAutoresizingMask:'); + const selSetFrame = sel_registerName('setFrame:'); + const selAddSubview = sel_registerName('addSubview:positioned:relativeTo:'); + + const NSVisualEffectViewClass = objc_getClass('NSVisualEffectView'); + if (!NSVisualEffectViewClass) return; + + // Allocation + const visualEffectView = objc_msgSend(NSVisualEffectViewClass, selAlloc); + objc_msgSend(visualEffectView, selInit); + + const materialValue = NSVisualEffectMaterial[material] || NSVisualEffectMaterial.HUDWindow; + + // Configuration + objc_msgSend_long(visualEffectView, selSetMaterial, materialValue); + objc_msgSend_long(visualEffectView, selSetBlendingMode, NSVisualEffectBlendingMode.BehindWindow); + objc_msgSend_long(visualEffectView, selSetState, 1); + objc_msgSend_long(visualEffectView, selSetAutoresizingMask, 18); + + // Frame + const bounds = window.getBounds(); + const viewFrame = { x: 0, y: 0, width: bounds.width, height: bounds.height }; + + const objc_msgSend_frame = objc.func('objc_msgSend', 'void', [Ptr, Ptr, NSRect]); + objc_msgSend_frame(visualEffectView, selSetFrame, viewFrame); + + // Add Subview to the CONTENT VIEW (which we already have as nsViewPtr) + const objc_msgSend_positioned = objc.func('objc_msgSend', 'void', [Ptr, Ptr, Ptr, 'long', Ptr]); + objc_msgSend_positioned(nsViewPtr, selAddSubview, visualEffectView, -1, 0); // -1 = NSWindowBelow + + console.log(`[MacOS] Vibrancy applied successfully`); + } catch (error) { + console.error('[MacOS] Error applying vibrancy:', error); + } + }, + + setRoundedCorners: (window: BrowserWindow, radius = 20) => { + try { + const windowHandle = window.getNativeWindowHandle(); + const nsViewPtr = windowHandle.readBigUInt64LE(); + + const selLayer = sel_registerName('layer'); + const selSetWantsLayer = sel_registerName('setWantsLayer:'); + const selSetCornerRadius = sel_registerName('setCornerRadius:'); + const selSetMasksToBounds = sel_registerName('setMasksToBounds:'); + + // Ensure layer-backing + objc_msgSend_bool(nsViewPtr, selSetWantsLayer, true); + + // Get layer + const nsLayer = objc_msgSend(nsViewPtr, selLayer); + if (!nsLayer) return console.error('[MacOS] Failed to get layer'); + + // Apply Corner Radius + objc_msgSend_double(nsLayer, selSetCornerRadius, radius); + objc_msgSend_bool(nsLayer, selSetMasksToBounds, true); + + console.log(`[MacOS] Rounded corners applied: ${radius}`); + } catch (error) { + console.error('[MacOS] Error applying rounded corners:', error); + } + }, + + setTransparentTitlebar: (window: BrowserWindow) => { + try { + const windowHandle = window.getNativeWindowHandle(); + const nsViewPtr = windowHandle.readBigUInt64LE(); + + // We have the View, we need the Window + const selWindow = sel_registerName('window'); + const nsWindowPtr = objc_msgSend(nsViewPtr, selWindow); + + if (!nsWindowPtr) return console.error('[MacOS] Failed to get NSWindow from NSView'); + + const selSetTitlebarAppearsTransparent = sel_registerName('setTitlebarAppearsTransparent:'); + objc_msgSend_bool(nsWindowPtr, selSetTitlebarAppearsTransparent, true); + + console.log('[MacOS] Transparent titlebar applied'); + } catch (error) { + console.error('[MacOS] Error setting transparent titlebar:', error); + } + } + }; + } catch (e) { + console.error('[MacOS] Failed to load native libraries:', e); + utils = { setVibrancy: () => { }, setRoundedCorners: () => { }, setTransparentTitlebar: () => { } }; + } +} else { + utils = { + setVibrancy: () => { }, + setRoundedCorners: () => { }, + setTransparentTitlebar: () => { } + }; +} + +export const { setVibrancy, setRoundedCorners, setTransparentTitlebar } = utils; diff --git a/package.json b/package.json index dd7170c4..b1ffee24 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "embla-carousel-react": "^8.6.0", "framer-motion": "^12.17.0", "gsap": "^3.13.0", + "koffi": "^2.14.1", "lodash-es": "^4.17.21", "lottie-web": "^5.13.0", "lucide-react": "^0.509.0", diff --git a/src/components/InstallStep/InstallDependencies.tsx b/src/components/InstallStep/InstallDependencies.tsx index 3ea2d3aa..ca70b0a9 100644 --- a/src/components/InstallStep/InstallDependencies.tsx +++ b/src/components/InstallStep/InstallDependencies.tsx @@ -16,7 +16,7 @@ export const InstallDependencies: React.FC = () => { } = useInstallationUI(); return ( -
+
{/* {isInstalling.toString()} */} diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 8e0a7814..8d82cb42 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -99,7 +99,6 @@ const Layout = () => { onOpenChange={setNoticeOpen} open={noticeOpen} /> -
); diff --git a/src/components/Navigation/index.tsx b/src/components/Navigation/index.tsx index 16077cb5..960c6c25 100644 --- a/src/components/Navigation/index.tsx +++ b/src/components/Navigation/index.tsx @@ -53,7 +53,7 @@ export function VerticalNavigation({ > diff --git a/src/components/TopBar/index.tsx b/src/components/TopBar/index.tsx index 988bdce9..860dc60c 100644 --- a/src/components/TopBar/index.tsx +++ b/src/components/TopBar/index.tsx @@ -343,7 +343,7 @@ function HeaderWin() { onClick={exportLog} variant="ghost" size="icon" - className="no-drag" + className="no-drag rounded-full" > diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx index 7efc37c9..12cf6c28 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/input.tsx @@ -119,7 +119,7 @@ const Input = React.forwardRef(
span]:line-clamp-1 whitespace-nowrap", // Default state (when no error/success) @@ -147,7 +147,7 @@ const SelectContent = React.forwardRef< {/* Header Section */} -
+
diff --git a/src/pages/Setting/MCP.tsx b/src/pages/Setting/MCP.tsx index 81949941..ea04991f 100644 --- a/src/pages/Setting/MCP.tsx +++ b/src/pages/Setting/MCP.tsx @@ -590,7 +590,7 @@ export default function SettingMCP() { return (
{/* Header Section */} -
+
{showMarket ? ( diff --git a/src/style/token.css b/src/style/token.css index 137ce863..6dab9fbb 100644 --- a/src/style/token.css +++ b/src/style/token.css @@ -446,7 +446,7 @@ --text-developer: var(--colors-emerald-default); --text-multimodal: var(--colors-fuchsia-default); --text-on-hover: var(--colors-primary-2); - --surface-primary: var(--colors-off-white-80); + --surface-primary: var(--colors-off-white-50); --surface-secondary: var(--colors-off-white-50); --surface-success: var(--colors-green-50); --surface-information: var(--colors-blue-50);