diff --git a/src/praisonaiui/datastore.py b/src/praisonaiui/datastore.py index 55627cd..b13ce4d 100644 --- a/src/praisonaiui/datastore.py +++ b/src/praisonaiui/datastore.py @@ -591,7 +591,7 @@ class SQLAlchemyDataStore(BaseDataStore): base = Path(os.environ.get("AIUI_DATA_DIR", str(Path.home() / ".praisonaiui"))) base.mkdir(parents=True, exist_ok=True) db_path = base / "aiui.db" - return f"sqlite+aiosqlite:///{db_path}" + return f"sqlite+aiosqlite:///{db_path.as_posix()}" async def _ensure_initialized(self) -> None: """Lazy initialization of SQLAlchemy engine and tables.""" diff --git a/src/praisonaiui/features/lifecycle.py b/src/praisonaiui/features/lifecycle.py index 3618032..3557f07 100644 --- a/src/praisonaiui/features/lifecycle.py +++ b/src/praisonaiui/features/lifecycle.py @@ -175,7 +175,7 @@ async def run_startup_hooks() -> None: return _log.info(f"Running {len(_startup_hooks)} startup hooks") - start_time = time.time() + start_time = time.perf_counter() for hook in _startup_hooks: try: @@ -187,7 +187,7 @@ async def run_startup_hooks() -> None: _log.error(f"Startup hook failed: {getattr(hook, '__name__', str(hook))}: {e}") # Continue with other hooks - individual failures shouldn't break startup - execution_time = time.time() - start_time + execution_time = time.perf_counter() - start_time _lifecycle_state.update( { "startup_completed": True, @@ -209,7 +209,7 @@ async def run_shutdown_hooks() -> None: _lifecycle_state["shutdown_initiated"] = True _log.info(f"Running {len(_shutdown_hooks)} shutdown hooks") - start_time = time.time() + start_time = time.perf_counter() # Get shutdown timeout from environment timeout = float(os.environ.get("AIUI_SHUTDOWN_TIMEOUT", "30.0")) @@ -227,7 +227,7 @@ async def run_shutdown_hooks() -> None: try: await asyncio.wait_for(_execute_hooks(), timeout=timeout) - execution_time = time.time() - start_time + execution_time = time.perf_counter() - start_time _lifecycle_state["shutdown_time"] = execution_time _log.info(f"Shutdown hooks completed in {execution_time:.3f}s") except asyncio.TimeoutError: diff --git a/tests/unit/test_audio_hooks.py b/tests/unit/test_audio_hooks.py index b0bb9d3..c259d22 100644 --- a/tests/unit/test_audio_hooks.py +++ b/tests/unit/test_audio_hooks.py @@ -305,7 +305,7 @@ class TestAudioSessionManagement: session = _audio_sessions[session_id] assert session["chunks_received"] == 1 assert session["bytes_received"] == len(test_data) - assert session["last_chunk_at"] > session["started_at"] + assert session["last_chunk_at"] >= session["started_at"] # Check global stats were updated assert _audio_stats["total_chunks"] == 1 diff --git a/tests/unit/test_sqlalchemy_datastore.py b/tests/unit/test_sqlalchemy_datastore.py index 5572fef..c4dc13b 100644 --- a/tests/unit/test_sqlalchemy_datastore.py +++ b/tests/unit/test_sqlalchemy_datastore.py @@ -95,7 +95,7 @@ async def test_default_sqlite_url(): with patch.dict(os.environ, {}, clear=True): store = SQLAlchemyDataStore() - expected = str(Path.home() / ".praisonaiui" / "aiui.db") + expected = (Path.home() / ".praisonaiui" / "aiui.db").as_posix() assert expected in store._database_url assert store._database_url.startswith("sqlite+aiosqlite:///") @@ -108,7 +108,7 @@ async def test_respects_aiui_data_dir_env(): with tempfile.TemporaryDirectory() as tmpdir: with patch.dict(os.environ, {"AIUI_DATA_DIR": tmpdir}): store = SQLAlchemyDataStore() - expected = str(Path(tmpdir) / "aiui.db") + expected = (Path(tmpdir) / "aiui.db").as_posix() assert expected in store._database_url diff --git a/tests/unit/test_unified_naming.py b/tests/unit/test_unified_naming.py index 93df3fd..ef95700 100644 --- a/tests/unit/test_unified_naming.py +++ b/tests/unit/test_unified_naming.py @@ -151,17 +151,32 @@ class TestCompetitorScrub: """The peer framework's name must never reappear in the source tree.""" def test_zero_matches_in_source(self): - import subprocess - r = subprocess.run( - ["grep", "-rn", "-i", "chainlit", - "src/praisonaiui", "docs", "examples", "tests", - "--include=*.py", "--include=*.md", "--include=*.yaml", - "--include=*.yml", "--include=*.ts", "--include=*.tsx"], - capture_output=True, text=True, cwd=_repo_root(), - ) - hits = [line for line in r.stdout.splitlines() - if ".pyc" not in line - and "tests/unit/test_unified_naming" not in line] + import pathlib + + root = pathlib.Path(_repo_root()) + needle = "chainlit" + suffixes = {".py", ".md", ".yaml", ".yml", ".ts", ".tsx"} + search_dirs = ["src/praisonaiui", "docs", "examples", "tests"] + + hits = [] + for rel in search_dirs: + base = root / rel + if not base.exists(): + continue + for path in base.rglob("*"): + if not path.is_file() or path.suffix not in suffixes: + continue + rel_path = path.relative_to(root).as_posix() + if "test_unified_naming" in rel_path: + continue + try: + text = path.read_text(encoding="utf-8", errors="ignore") + except OSError: + continue + for lineno, line in enumerate(text.splitlines(), 1): + if needle in line.lower(): + hits.append(f"{rel_path}:{lineno}:{line}") + assert not hits, f"Competitor name reappeared: {hits}"