diff --git a/packages/agent/src/argus_agent/collectors/process_monitor.py b/packages/agent/src/argus_agent/collectors/process_monitor.py index 8c3db0b..eedc084 100644 --- a/packages/agent/src/argus_agent/collectors/process_monitor.py +++ b/packages/agent/src/argus_agent/collectors/process_monitor.py @@ -242,12 +242,12 @@ async def _check_remote(self) -> dict[str, Any]: def get_process_list( sort_by: str = "cpu_percent", - limit: int = 50, ) -> list[dict[str, Any]]: """Get current process list snapshot (synchronous, for tools). Uses `ps` for a complete listing (no AccessDenied gaps), falls back to psutil if `ps` is unavailable. + Returns ALL processes — no limit. """ processes = _get_process_list_ps() if processes is None: @@ -259,7 +259,7 @@ def get_process_list( else: processes.sort(key=lambda p: p.get("cpu_percent", 0), reverse=True) - return processes[:limit] + return processes def _get_process_list_ps() -> list[dict[str, Any]] | None: diff --git a/packages/agent/src/argus_agent/tools/process.py b/packages/agent/src/argus_agent/tools/process.py index b9a91e3..a22d1d1 100644 --- a/packages/agent/src/argus_agent/tools/process.py +++ b/packages/agent/src/argus_agent/tools/process.py @@ -21,8 +21,8 @@ def name(self) -> str: @property def description(self) -> str: return ( - "List running processes with CPU and memory usage. " - "Sort by cpu_percent, memory_percent, or pid." + "List ALL running processes with CPU and memory usage. " + "Returns every process — no filtering, no limits." ) @property @@ -39,42 +39,13 @@ def parameters_schema(self) -> dict[str, Any]: "description": "Sort: cpu_percent, memory_percent, pid", "default": "cpu_percent", }, - "limit": { - "type": "integer", - "description": "Max processes to return (default: 25)", - "default": 25, - }, - "filter_name": { - "type": "string", - "description": "Filter by process name (substring match)", - }, - "filter_user": { - "type": "string", - "description": "Filter by username", - }, }, } async def execute(self, **kwargs: Any) -> dict[str, Any]: sort_by = kwargs.get("sort_by", "cpu_percent") - limit = min(kwargs.get("limit", 25), 100) - filter_name = kwargs.get("filter_name", "") - filter_user = kwargs.get("filter_user", "") - - processes = get_process_list(sort_by=sort_by, limit=200) - - # Apply filters - if filter_name: - fn = filter_name.lower() - processes = [ - p - for p in processes - if fn in p.get("name", "").lower() or fn in p.get("cmdline", "").lower() - ] - if filter_user: - processes = [p for p in processes if p.get("username") == filter_user] - - processes = processes[:limit] + + processes = get_process_list(sort_by=sort_by) return { "total_processes": len(processes), diff --git a/packages/agent/tests/test_collectors.py b/packages/agent/tests/test_collectors.py index aa017a9..815edd5 100644 --- a/packages/agent/tests/test_collectors.py +++ b/packages/agent/tests/test_collectors.py @@ -107,7 +107,7 @@ async def test_format_snapshot_with_data(self): class TestProcessMonitor: def test_get_process_list(self): - processes = get_process_list(limit=10) + processes = get_process_list() assert len(processes) > 0 assert "pid" in processes[0] assert "name" in processes[0] @@ -115,12 +115,12 @@ def test_get_process_list(self): assert "memory_percent" in processes[0] def test_sort_by_memory(self): - processes = get_process_list(sort_by="memory_percent", limit=5) + processes = get_process_list(sort_by="memory_percent") if len(processes) >= 2: assert processes[0]["memory_percent"] >= processes[1]["memory_percent"] def test_sort_by_pid(self): - processes = get_process_list(sort_by="pid", limit=5) + processes = get_process_list(sort_by="pid") if len(processes) >= 2: assert processes[0]["pid"] <= processes[1]["pid"] diff --git a/packages/agent/tests/test_new_tools.py b/packages/agent/tests/test_new_tools.py index 00b5aa5..2eb558e 100644 --- a/packages/agent/tests/test_new_tools.py +++ b/packages/agent/tests/test_new_tools.py @@ -83,19 +83,13 @@ async def test_list_processes(self): assert result["display_type"] == "process_table" @pytest.mark.asyncio - async def test_limit(self): + async def test_returns_all_processes(self): tool = ProcessListTool() - result = await tool.execute(limit=3) - - assert len(result["processes"]) <= 3 - - @pytest.mark.asyncio - async def test_filter_name(self): - tool = ProcessListTool() - result = await tool.execute(filter_name="python", limit=100) + result = await tool.execute() - for p in result["processes"]: - assert "python" in p["name"].lower() or "python" in p.get("cmdline", "").lower() + # Should return all processes, no artificial limit + assert result["total_processes"] == len(result["processes"]) + assert result["total_processes"] > 10 def test_tool_properties(self): tool = ProcessListTool() diff --git a/packages/sdk-python/pyproject.toml b/packages/sdk-python/pyproject.toml index f64fd54..ecb93b0 100644 --- a/packages/sdk-python/pyproject.toml +++ b/packages/sdk-python/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "argus-ai-sdk" -version = "0.2.1" +version = "0.2.2" description = "Argus Python SDK - Instrumentation for AI-native observability" readme = "README.md" requires-python = ">=3.9" diff --git a/packages/sdk-python/src/argus/webhook.py b/packages/sdk-python/src/argus/webhook.py index 577abb5..d80c12a 100644 --- a/packages/sdk-python/src/argus/webhook.py +++ b/packages/sdk-python/src/argus/webhook.py @@ -84,22 +84,21 @@ def _tool_system_metrics(**_kwargs: Any) -> dict[str, Any]: def _tool_process_list(**kwargs: Any) -> dict[str, Any]: - """List running processes. + """List ALL running processes. Uses `ps` for a complete listing (no AccessDenied gaps), falls back to psutil if `ps` is unavailable. + Returns every process — no filtering, no limits. """ - limit = int(kwargs.get("limit", 20)) sort_by = kwargs.get("sort_by", "cpu") key = "cpu_percent" if sort_by == "cpu" else "memory_percent" - # Try ps first — shows all processes regardless of permissions procs = _ps_process_list() if procs is None: procs = _psutil_process_list() procs.sort(key=lambda x: x.get(key) or 0, reverse=True) - return {"processes": procs[:limit], "total": len(procs)} + return {"processes": procs, "total": len(procs)} def _ps_process_list() -> list[dict[str, Any]] | None: