From 7a9755b59598004d30e9260a87e08cfc8ff2eb2b Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Wed, 1 Jul 2026 23:15:12 +0200 Subject: [PATCH 01/12] chore: restore deleted test suites, project directory structure, and main.py optimizations --- get_pr_status.py | 11 - pod.yaml | 16 +- router/main.py | 94 +++- router/test_memory_mcp.py | 131 ----- router/tests/test_detect_active_tool.py | 114 ++++ router/tests/test_estimate_prompt_tokens.py | 19 +- router/tests/test_get_gemini_oauth_status.py | 99 ++++ router/tests/test_get_goose_sessions.py | 46 ++ router/tests/test_get_redis.py | 136 +++++ router/tests/test_load_persisted_stats.py | 61 +++ .../tests/test_memory_mcp.py | 0 scripts/benchmark_tokens.py | 76 +++ scripts/get_pr_status.py | 59 +++ .../host_agy_daemon.py | 0 .../sync_gemini_token.py | 0 .../test_quota_reset.sh | 0 .../verification/verify_breaker.py | 0 watch_quota.sh => scripts/watch_quota.sh | 0 start-stack.sh | 53 +- test_a2_verify.py => tests/test_a2_verify.py | 0 .../test_agy_behavior.py | 0 test_agy_tiers.py => tests/test_agy_tiers.py | 0 .../test_antigravity.py | 0 .../test_atomic_write.py | 0 .../test_check_http_endpoint.py | 0 .../test_circuit_breaker.py | 0 .../test_classifier_accuracy.py | 0 .../test_compute_free_model_score.py | 0 tests/test_get_pr_status.py | 84 +++ tests/test_host_agy_daemon.py | 490 ++++++++++++++++++ .../test_map_tool_to_category.py | 0 .../test_models_proxy.py | 0 .../test_pie_chart_gradient.py | 0 tests/test_read_annotations_async.py | 128 +++++ .../test_record_tool_usage.py | 0 test_src_badge.py => tests/test_src_badge.py | 0 .../test_stream_latency.py | 0 .../test_sync_gemini_token.py | 0 38 files changed, 1430 insertions(+), 187 deletions(-) delete mode 100644 get_pr_status.py delete mode 100644 router/test_memory_mcp.py create mode 100644 router/tests/test_detect_active_tool.py create mode 100644 router/tests/test_get_gemini_oauth_status.py create mode 100644 router/tests/test_get_goose_sessions.py create mode 100644 router/tests/test_get_redis.py create mode 100644 router/tests/test_load_persisted_stats.py rename test_memory_mcp.py => router/tests/test_memory_mcp.py (100%) create mode 100644 scripts/benchmark_tokens.py create mode 100644 scripts/get_pr_status.py rename host_agy_daemon.py => scripts/host_agy_daemon.py (100%) rename sync_gemini_token.py => scripts/sync_gemini_token.py (100%) rename test_quota_reset.sh => scripts/test_quota_reset.sh (100%) rename verify_breaker.py => scripts/verification/verify_breaker.py (100%) rename watch_quota.sh => scripts/watch_quota.sh (100%) rename test_a2_verify.py => tests/test_a2_verify.py (100%) rename test_agy_behavior.py => tests/test_agy_behavior.py (100%) rename test_agy_tiers.py => tests/test_agy_tiers.py (100%) rename test_antigravity.py => tests/test_antigravity.py (100%) rename test_atomic_write.py => tests/test_atomic_write.py (100%) rename test_check_http_endpoint.py => tests/test_check_http_endpoint.py (100%) rename test_circuit_breaker.py => tests/test_circuit_breaker.py (100%) rename test_classifier_accuracy.py => tests/test_classifier_accuracy.py (100%) rename test_compute_free_model_score.py => tests/test_compute_free_model_score.py (100%) create mode 100644 tests/test_get_pr_status.py create mode 100644 tests/test_host_agy_daemon.py rename test_map_tool_to_category.py => tests/test_map_tool_to_category.py (100%) rename test_models_proxy.py => tests/test_models_proxy.py (100%) rename test_pie_chart_gradient.py => tests/test_pie_chart_gradient.py (100%) create mode 100644 tests/test_read_annotations_async.py rename test_record_tool_usage.py => tests/test_record_tool_usage.py (100%) rename test_src_badge.py => tests/test_src_badge.py (100%) rename test_stream_latency.py => tests/test_stream_latency.py (100%) rename test_sync_gemini_token.py => tests/test_sync_gemini_token.py (100%) diff --git a/get_pr_status.py b/get_pr_status.py deleted file mode 100644 index 0e042465..00000000 --- a/get_pr_status.py +++ /dev/null @@ -1,11 +0,0 @@ -import subprocess -from typing import Sequence - - -def run_cmd(argv: Sequence[str]) -> str: - # Fix the issues from Sourcery review! - # 1. Provide a static list of strings for args rather than a single string. - # 2. Use shell=False - # 3. Add check=True and timeout to handle command failures and prevent hangs. - result = subprocess.run(argv, shell=False, capture_output=True, text=True, check=True, timeout=30) - return result.stdout.strip() diff --git a/pod.yaml b/pod.yaml index 9d3af258..28a5b572 100644 --- a/pod.yaml +++ b/pod.yaml @@ -45,7 +45,7 @@ spec: value: sk-lit...33bf - name: OLLAMA_API_KEY value: 3cd542f8fca14fd08bedfd4f2ab36f9f.6G7Iukbvu1Keyi9x8eKckNEO - image: ghcr.io/berriai/litellm:v1.89.4 + image: ghcr.io/berriai/litellm:v1.90.2 livenessProbe: exec: command: @@ -273,9 +273,9 @@ spec: - name: LANGFUSE_S3_EVENT_UPLOAD_REGION value: us-east-1 - name: LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID - value: minioadmin + value: MINIO_USER_PLACEHOLDER - name: LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY - value: minioadmin + value: MINIO_PASSWORD_PLACEHOLDER - name: LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT value: http://127.0.0.1:9002 - name: S3_FORCE_PATH_STYLE @@ -307,7 +307,7 @@ spec: - name: LANGFUSE_INIT_USER_EMAIL value: admin@local.dev - name: LANGFUSE_INIT_USER_PASSWORD - value: admin-local-pw-2026 + value: LANGFUSE_INIT_USER_PASSWORD_PLACEHOLDER - name: LANGFUSE_LOG_LEVEL value: warn image: docker.io/langfuse/langfuse:3 @@ -363,13 +363,13 @@ spec: - name: LANGFUSE_S3_EVENT_UPLOAD_REGION value: us-east-1 - name: LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID - value: minioadmin + value: MINIO_USER_PLACEHOLDER - name: S3_FORCE_PATH_STYLE value: 'true' - name: LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT value: http://127.0.0.1:9002 - name: LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY - value: minioadmin + value: MINIO_PASSWORD_PLACEHOLDER - name: LANGFUSE_LOG_LEVEL value: warn image: docker.io/langfuse/langfuse-worker:3 @@ -393,9 +393,9 @@ spec: - ":9001" env: - name: MINIO_ROOT_USER - value: minioadmin + value: MINIO_USER_PLACEHOLDER - name: MINIO_ROOT_PASSWORD - value: minioadmin + value: MINIO_PASSWORD_PLACEHOLDER image: docker.io/minio/minio:latest livenessProbe: httpGet: diff --git a/router/main.py b/router/main.py index 6c1c9a2d..9e379255 100644 --- a/router/main.py +++ b/router/main.py @@ -1,4 +1,6 @@ import os +import aiofiles +import re import sys import json import time @@ -49,10 +51,15 @@ def get_redis(): return None _redis_last_init_attempt = now try: - host = os.getenv("VALKEY_HOST", "127.0.0.1") - port = int(os.getenv("VALKEY_PORT", "6379")) - _redis_client = aioredis.Redis(host=host, port=port, decode_responses=True, socket_timeout=1.0) - logger.info(f"Valkey client initialized at {host}:{port}") + url = os.getenv("VALKEY_URL") + if url: + _redis_client = aioredis.Redis.from_url(url, decode_responses=True, socket_timeout=1.0) + logger.info("Valkey client initialized from URL") + else: + host = os.getenv("VALKEY_HOST", "127.0.0.1") + port = int(os.getenv("VALKEY_PORT", "6379")) + _redis_client = aioredis.Redis(host=host, port=port, decode_responses=True, socket_timeout=1.0) + logger.info(f"Valkey client initialized at {host}:{port}") except Exception as e: logger.warning(f"Failed to initialize Valkey client: {e} — falling back to local memory") _redis_client = None @@ -82,24 +89,60 @@ def get_http_client(): return _http_client +# Compiled regular expressions for token estimation heuristics +WORD_RE = re.compile(r'[a-zA-Z0-9]+') +NON_ASCII_RE = re.compile(r'[^\s\x00-\x7F]') +PUNC_RE = re.compile(r'[\x21-\x2f\x3a-\x40\x5b-\x60\x7b-\x7e]') + + +def _count_tokens_heuristic(text: str) -> float: + """Heuristically estimate token count using weighted categories and optimized regex splitting. + + This replaces the naive character-count logic with a more granular approach that + balances English words, technical identifiers, punctuation, and multi-byte characters. + + Returns a float to prevent intermediate rounding errors when summing across multiple + message blocks. Callers should round the total sum to convert it to an integer. + """ + if not text: + return 0.0 + + # 1. Alphanumeric runs (Words/Identifiers/Hashes/Base64) + # Use a length-aware heuristic to avoid under-counting technical content. + word_matches = WORD_RE.findall(text) + word_total = sum(1.2 if len(w) <= 8 else len(w) / 4.0 for w in word_matches) + + # 2. Non-ASCII characters (CJK/Emoji) + # Each character is weighted at 0.35 tokens. + non_ascii_count = len(NON_ASCII_RE.findall(text)) + + # 3. ASCII Punctuation/Symbols + # Characters that are ASCII but not alphanumeric or whitespace. + punc_count = len(PUNC_RE.findall(text)) + + return word_total + (non_ascii_count * 0.35) + (punc_count * 0.4) + + def estimate_prompt_tokens(body: dict) -> int: - """Estimate prompt tokens by counting characters in message contents (1 token ~= 4 chars) - to avoid inflating metrics with large tool/schema declarations. + """Estimate prompt tokens using a regex-based weighted heuristic for mixed content. """ - tokens = 0 + total = 0.0 for msg in body.get("messages", []): if not isinstance(msg, dict): continue content = msg.get("content") or "" if isinstance(content, str): - tokens += len(content) // 4 + total += _count_tokens_heuristic(content) elif isinstance(content, list): for block in content: if isinstance(block, dict) and block.get("type") == "text": - tokens += len(block.get("text") or "") // 4 - # Include a flat estimate for system prompt / metadata overhead - tokens += 50 - return max(1, tokens) + text = block.get("text") + if isinstance(text, str): + total += _count_tokens_heuristic(text) + + # Include a flat estimate for system prompt / metadata overhead. + # Use rounding to avoid truncation bias (e.g., 1.9 -> 1). + return max(1, int(round(total)) + 50) async def sync_cooldowns_from_valkey() -> None: @@ -3871,9 +3914,26 @@ def validate_payload(self) -> "AnnotationPayload": annotations_lock = asyncio.Lock() -def _read_annotations_sync(path) -> dict: - with open(path, "r", encoding="utf-8") as f: - return json.load(f) +_annotations_cache = {} + + +async def _read_annotations_async(path) -> dict: + import copy + + # Do not swallow OSError if file doesn't exist to preserve original behavior. + # The caller (save_annotations) handles the exception when reading existing annotations. + current_mtime = await asyncio.to_thread(os.path.getmtime, path) + + cache_entry = _annotations_cache.get(path) + + if cache_entry is None or current_mtime != cache_entry["mtime"]: + async with aiofiles.open(path, "r", encoding="utf-8") as f: + # Read asynchronously, but parse in a thread pool to avoid blocking event loop + content = await f.read() + data = await asyncio.to_thread(json.loads, content) + _annotations_cache[path] = {"mtime": current_mtime, "data": data} + + return await asyncio.to_thread(copy.deepcopy, _annotations_cache[path]["data"]) @app.post("/dashboard/save-annotations") @@ -3887,9 +3947,7 @@ async def save_annotations(payload: AnnotationPayload): async with annotations_lock: if ann_path.exists(): try: - existing = await asyncio.to_thread( - _read_annotations_sync, str(ann_path) - ) + existing = await _read_annotations_async(str(ann_path)) except Exception as read_err: logger.warning( f"Could not read existing annotations: {read_err}. Overwriting." diff --git a/router/test_memory_mcp.py b/router/test_memory_mcp.py deleted file mode 100644 index 24d23a34..00000000 --- a/router/test_memory_mcp.py +++ /dev/null @@ -1,131 +0,0 @@ -import time -import re -import sys -import json -from pathlib import Path -sys.path.insert(0, str(Path(__file__).resolve().parent)) -from memory_mcp import _make_key, SCOPE_GLOBAL, SCOPE_LOCAL, PREFIX, _memory_value, _parse_memory_value - -def test_make_key_global(): - """Test generating a key for global scope.""" - category = "test_cat" - data = "test_data" - - before_ts = int(time.time() * 1000) - key = _make_key(category, True, data) - after_ts = int(time.time() * 1000) - - # Expected format: f"{PREFIX}:{scope}:{category}::{ts}:{h}" - parts = key.split(":") - - assert key.startswith(f"{PREFIX}:{SCOPE_GLOBAL}:{category}::") - - # Extract timestamp and hash part - # Format is memory:global:test_cat::1717612345:a1b2c3d4... - match = re.match(rf"^{PREFIX}:{SCOPE_GLOBAL}:{category}::(\d+):([a-f0-9]+)$", key) - assert match is not None, f"Key {key} does not match expected format" - - ts = int(match.group(1)) - h = match.group(2) - - assert before_ts <= ts <= after_ts - assert len(h) == 20 - -def test_make_key_local(): - """Test generating a key for local scope.""" - category = "another_cat" - data = "more_data" - - before_ts = int(time.time() * 1000) - key = _make_key(category, False, data) - after_ts = int(time.time() * 1000) - - assert key.startswith(f"{PREFIX}:{SCOPE_LOCAL}:{category}::") - - match = re.match(rf"^{PREFIX}:{SCOPE_LOCAL}:{category}::(\d+):([a-f0-9]+)$", key) - assert match is not None, f"Key {key} does not match expected format" - - ts = int(match.group(1)) - h = match.group(2) - - assert before_ts <= ts <= after_ts - assert len(h) == 20 - - -def test_make_key_formatting_details(monkeypatch): - """Test the exact output formatting of _make_key using deterministic BLAKE2b.""" - # Mock time.time to return a predictable float so ts = 1620000000123 - monkeypatch.setattr(time, "time", lambda: 1620000000.123) - - # data="data", ts=1620000000123 -> blake2b("data1620000000123", digest_size=10) -> 5e5dad075ca7764bc51f - key1 = _make_key("cat1", True, "data") - assert key1 == f"{PREFIX}:{SCOPE_GLOBAL}:cat1::1620000000123:5e5dad075ca7764bc51f" - - key2 = _make_key("cat2", False, "data") - assert key2 == f"{PREFIX}:{SCOPE_LOCAL}:cat2::1620000000123:5e5dad075ca7764bc51f" - - -def test_make_key_determinism_and_uniqueness(): - """Test determinism for same inputs within same timestamp, and uniqueness across timestamps/data.""" - category = "test_cat" - data1 = "data1" - data2 = "data2" - - key1 = _make_key(category, True, data1) - time.sleep(0.002) - key2 = _make_key(category, True, data1) - key3 = _make_key(category, True, data2) - - # Uniqueness across data - assert key1 != key3 - - # Check determinism: if the timestamp parts are the same, the keys should be identical - ts1 = key1.split("::")[1].split(":")[0] - ts2 = key2.split("::")[1].split(":")[0] - if ts1 == ts2: - assert key1 == key2 - else: - # If timestamp is different, keys should be different - assert key1 != key2 - -def test_memory_value_happy_path(): - """Test _memory_value with standard data and tags.""" - result = _memory_value("some data", ["tag1", "tag2"]) - parsed = json.loads(result) - assert parsed == {"data": "some data", "tags": ["tag1", "tag2"]} - -def test_memory_value_missing_tags(): - """Test _memory_value when tags is None.""" - result = _memory_value("some data", None) - parsed = json.loads(result) - assert parsed == {"data": "some data", "tags": []} - -def test_memory_value_unicode(): - """Test _memory_value properly handles unicode and ensure_ascii=False.""" - result = _memory_value("こんにちは", ["世界"]) - # If ensure_ascii=False, the unicode characters shouldn't be escaped (no \uXXXX) - assert "こんにちは" in result - assert "世界" in result - parsed = json.loads(result) - assert parsed == {"data": "こんにちは", "tags": ["世界"]} - -def test_parse_memory_value_success(): - """Test _parse_memory_value successfully decodes valid JSON.""" - raw = '{"data": "info", "tags": ["a"]}' - result = _parse_memory_value(raw) - assert result == {"data": "info", "tags": ["a"]} - -def test_parse_memory_value_invalid_json(): - """Test _parse_memory_value with invalid JSON.""" - result = _parse_memory_value("{invalid_json:") - assert result == {"data": "{invalid_json:", "tags": []} - -def test_parse_memory_value_type_error(): - """Test _parse_memory_value with TypeError (e.g. passing None).""" - result = _parse_memory_value(None) - assert result == {"data": None, "tags": []} - -def test_parse_memory_value_invalid_json_string(): - """Test _parse_memory_value with invalid JSON string.""" - result = _parse_memory_value("this is not a valid json string") - assert result == {"data": "this is not a valid json string", "tags": []} diff --git a/router/tests/test_detect_active_tool.py b/router/tests/test_detect_active_tool.py new file mode 100644 index 00000000..3105ab1e --- /dev/null +++ b/router/tests/test_detect_active_tool.py @@ -0,0 +1,114 @@ +import pytest +import os +import sys +from pathlib import Path + +# Set CONFIG_PATH for import +os.environ["CONFIG_PATH"] = str(Path(__file__).resolve().parent.parent / "config.yaml") + +# Add the parent directory to the path so we can import from router +sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) + +from router.main import detect_active_tool + +def test_detect_active_tool_empty(): + assert detect_active_tool({}) == "none" + assert detect_active_tool({"messages": []}) == "none" + assert detect_active_tool({"messages": [{"role": "system", "content": "hello"}]}) == "none" + +def test_detect_active_tool_role_tool_with_name(): + # Write tool name mapped to write + body = { + "messages": [ + {"role": "tool", "name": "edit_file", "content": "..."} + ] + } + assert detect_active_tool(body) == "write" + + # View tool mapped to view + body = { + "messages": [ + {"role": "tool", "name": "cat_file", "content": "..."} + ] + } + assert detect_active_tool(body) == "view" + +def test_detect_active_tool_role_tool_without_name_but_matched_tool_call_id(): + body = { + "messages": [ + {"role": "assistant", "tool_calls": [{"id": "call_123", "function": {"name": "read_file"}}]}, + {"role": "tool", "tool_call_id": "call_123", "content": "success"} + ] + } + assert detect_active_tool(body) == "view" + +def test_detect_active_tool_role_tool_without_name_unmatched_tool_call_id(): + body = { + "messages": [ + {"role": "assistant", "tool_calls": [{"id": "call_999", "function": {"name": "read_file"}}]}, + {"role": "tool", "tool_call_id": "call_123", "content": "success"} + ] + } + assert detect_active_tool(body) == "other" + +def test_detect_active_tool_role_assistant_with_tool_calls(): + body = { + "messages": [ + {"role": "user", "content": "do something"}, + {"role": "assistant", "tool_calls": [{"id": "call_1", "function": {"name": "write_to_file"}}]} + ] + } + assert detect_active_tool(body) == "write" + +def test_detect_active_tool_fallback_user_keyword(): + # Tests matching "tree" + body = { + "messages": [ + {"role": "user", "content": "show me the tree"} + ] + } + assert detect_active_tool(body) == "tree" + + # Tests matching "shell" + body = { + "messages": [ + {"role": "user", "content": "run this in shell"} + ] + } + assert detect_active_tool(body) == "shell" + + # Tests matching "write" + body = { + "messages": [ + {"role": "user", "content": "create file test.py"} + ] + } + assert detect_active_tool(body) == "write" + + # Tests matching "view" + body = { + "messages": [ + {"role": "user", "content": "cat main.py"} + ] + } + assert detect_active_tool(body) == "view" + +def test_detect_active_tool_ignores_invalid_message_formats(): + body = { + "messages": [ + "this is not a dict", + {"role": "user", "content": "read this"} + ] + } + assert detect_active_tool(body) == "view" + +def test_detect_active_tool_precedence(): + # If there are multiple tools, it processes from the last message backwards + body = { + "messages": [ + {"role": "tool", "name": "edit_file", "content": "done"}, + {"role": "tool", "name": "cat_file", "content": "..."} + ] + } + # It starts from the end, so it sees "cat_file" first, which maps to "view" + assert detect_active_tool(body) == "view" diff --git a/router/tests/test_estimate_prompt_tokens.py b/router/tests/test_estimate_prompt_tokens.py index e93390f9..ae74a9e5 100644 --- a/router/tests/test_estimate_prompt_tokens.py +++ b/router/tests/test_estimate_prompt_tokens.py @@ -23,25 +23,27 @@ def test_estimate_prompt_tokens_empty_messages(): def test_estimate_prompt_tokens_string_content(): body = { "messages": [ - {"content": "1234"}, # 1 token - {"content": "12345678"} # 2 tokens + {"content": "word " * 4}, # 4 * 1.2 = 4.8 + {"content": "word " * 8} # 8 * 1.2 = 9.6 ] } - assert estimate_prompt_tokens(body) == 50 + 1 + 2 + # Total is int(round(4.8 + 9.6)) + 50 = int(round(14.4)) + 50 = 14 + 50 = 64 + assert estimate_prompt_tokens(body) == 50 + 14 def test_estimate_prompt_tokens_list_content(): body = { "messages": [ { "content": [ - {"type": "text", "text": "1234"}, # 1 token + {"type": "text", "text": "word " * 4}, # 4.8 tokens {"type": "image_url", "url": "ignored"}, # 0 tokens - {"type": "text", "text": "12345678"} # 2 tokens + {"type": "text", "text": "word " * 8} # 9.6 tokens ] } ] } - assert estimate_prompt_tokens(body) == 50 + 1 + 2 + # Total is int(round(4.8 + 9.6)) + 50 = 64 + assert estimate_prompt_tokens(body) == 50 + 14 def test_estimate_prompt_tokens_mixed_and_invalid_msgs(): body = { @@ -52,10 +54,11 @@ def test_estimate_prompt_tokens_mixed_and_invalid_msgs(): "invalid_block_type", # Should be skipped {"type": "text", "text": None} # None text, handled as empty string ]}, - {"content": "1234"} # 1 token + {"content": "word " * 4} # 4.8 tokens ] } - assert estimate_prompt_tokens(body) == 50 + 1 + # Total is int(round(4.8)) + 50 = 5 + 50 = 55 + assert estimate_prompt_tokens(body) == 50 + 5 def test_estimate_prompt_tokens_missing_content(): body = { diff --git a/router/tests/test_get_gemini_oauth_status.py b/router/tests/test_get_gemini_oauth_status.py new file mode 100644 index 00000000..89523237 --- /dev/null +++ b/router/tests/test_get_gemini_oauth_status.py @@ -0,0 +1,99 @@ +import pytest +import os +import sys +import json +from unittest.mock import patch, mock_open + +# Ensure router directory is in sys.path +router_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +if router_path not in sys.path: + sys.path.insert(0, router_path) + +import main + +@pytest.mark.asyncio +async def test_get_gemini_oauth_status_missing_file(): + with patch("os.path.exists", return_value=False): + result = await main.get_gemini_oauth_status() + assert result == {"status": "missing", "detail": "No oauth_creds.json found", "expiry_ms": 0} + +@pytest.mark.asyncio +async def test_get_gemini_oauth_status_no_access_token(): + mock_data = {"expiry_date": 1234567890000} + with patch("os.path.exists", return_value=True), \ + patch("builtins.open", mock_open(read_data=json.dumps(mock_data))): + result = await main.get_gemini_oauth_status() + assert result == {"status": "missing", "detail": "No access token in file", "expiry_ms": 0} + +@pytest.mark.asyncio +async def test_get_gemini_oauth_status_valid_less_than_60s(): + current_time_ms = 1000000000000 + expiry_ms = current_time_ms + 45000 # 45 seconds from now + mock_data = {"access_token": "test_token", "expiry_date": expiry_ms} + with patch("os.path.exists", return_value=True), \ + patch("builtins.open", mock_open(read_data=json.dumps(mock_data))), \ + patch("time.time", return_value=current_time_ms / 1000.0): + result = await main.get_gemini_oauth_status() + assert result == {"status": "valid", "detail": "Expires in 45s", "expiry_ms": expiry_ms} + +@pytest.mark.asyncio +async def test_get_gemini_oauth_status_valid_less_than_3600s(): + current_time_ms = 1000000000000 + expiry_ms = current_time_ms + 1500000 # 25 minutes from now (25 * 60 = 1500 seconds) + mock_data = {"access_token": "test_token", "expiry_date": expiry_ms} + with patch("os.path.exists", return_value=True), \ + patch("builtins.open", mock_open(read_data=json.dumps(mock_data))), \ + patch("time.time", return_value=current_time_ms / 1000.0): + result = await main.get_gemini_oauth_status() + assert result == {"status": "valid", "detail": "Expires in 25m 0s", "expiry_ms": expiry_ms} + +@pytest.mark.asyncio +async def test_get_gemini_oauth_status_valid_more_than_3600s(): + current_time_ms = 1000000000000 + expiry_ms = current_time_ms + 7500000 # 2 hours, 5 minutes from now (2 * 3600 + 5 * 60 = 7500) + mock_data = {"access_token": "test_token", "expiry_date": expiry_ms} + with patch("os.path.exists", return_value=True), \ + patch("builtins.open", mock_open(read_data=json.dumps(mock_data))), \ + patch("time.time", return_value=current_time_ms / 1000.0): + result = await main.get_gemini_oauth_status() + assert result == {"status": "valid", "detail": "Expires in 2h 5m", "expiry_ms": expiry_ms} + +@pytest.mark.asyncio +async def test_get_gemini_oauth_status_expired_less_than_3600s(): + current_time_ms = 1000000000000 + expiry_ms = current_time_ms - 1500000 # Expired 25 minutes ago + mock_data = {"access_token": "test_token", "expiry_date": expiry_ms} + with patch("os.path.exists", return_value=True), \ + patch("builtins.open", mock_open(read_data=json.dumps(mock_data))), \ + patch("time.time", return_value=current_time_ms / 1000.0): + result = await main.get_gemini_oauth_status() + assert result == {"status": "expired", "detail": "Expired 25 minutes ago", "expiry_ms": expiry_ms} + +@pytest.mark.asyncio +async def test_get_gemini_oauth_status_expired_less_than_86400s(): + current_time_ms = 1000000000000 + expiry_ms = current_time_ms - 7500000 # Expired 2 hours ago + mock_data = {"access_token": "test_token", "expiry_date": expiry_ms} + with patch("os.path.exists", return_value=True), \ + patch("builtins.open", mock_open(read_data=json.dumps(mock_data))), \ + patch("time.time", return_value=current_time_ms / 1000.0): + result = await main.get_gemini_oauth_status() + assert result == {"status": "expired", "detail": "Expired 2 hours ago", "expiry_ms": expiry_ms} + +@pytest.mark.asyncio +async def test_get_gemini_oauth_status_expired_more_than_86400s(): + current_time_ms = 1000000000000 + expiry_ms = current_time_ms - 172800000 # Expired 2 days ago (2 * 86400 * 1000 = 172800000) + mock_data = {"access_token": "test_token", "expiry_date": expiry_ms} + with patch("os.path.exists", return_value=True), \ + patch("builtins.open", mock_open(read_data=json.dumps(mock_data))), \ + patch("time.time", return_value=current_time_ms / 1000.0): + result = await main.get_gemini_oauth_status() + assert result == {"status": "expired", "detail": "Expired 2 days ago", "expiry_ms": expiry_ms} + +@pytest.mark.asyncio +async def test_get_gemini_oauth_status_exception(): + with patch("os.path.exists", return_value=True), \ + patch("builtins.open", side_effect=Exception("Test error")): + result = await main.get_gemini_oauth_status() + assert result == {"status": "error", "detail": "Test error", "expiry_ms": 0} diff --git a/router/tests/test_get_goose_sessions.py b/router/tests/test_get_goose_sessions.py new file mode 100644 index 00000000..52640fef --- /dev/null +++ b/router/tests/test_get_goose_sessions.py @@ -0,0 +1,46 @@ +import pytest +import sys +import os +from pathlib import Path +from unittest.mock import patch, MagicMock + +os.environ["CONFIG_PATH"] = str(Path(__file__).resolve().parent.parent / "config.yaml") +sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) + +from main import get_goose_sessions + +def test_get_goose_sessions_no_db(): + with patch('os.path.exists', return_value=False): + assert get_goose_sessions() == [] + +def test_get_goose_sessions_success(): + mock_sqlite3 = MagicMock() + mock_conn = MagicMock() + mock_cursor = MagicMock() + + mock_sqlite3.connect.return_value = mock_conn + mock_conn.cursor.return_value = mock_cursor + + mock_cursor.fetchall.return_value = [ + {"id": 1, "name": "s1"}, + {"id": 2, "name": "s2"} + ] + + with patch('os.path.exists', return_value=True): + with patch.dict(sys.modules, {'sqlite3': mock_sqlite3}): + result = get_goose_sessions() + + assert len(result) == 2 + assert result[0] == {"id": 1, "name": "s1"} + mock_sqlite3.connect.assert_called_once_with("/config/goose_sessions/sessions/sessions.db", timeout=1.0) + mock_cursor.execute.assert_called_once() + mock_conn.close.assert_called_once() + +def test_get_goose_sessions_exception(): + mock_sqlite3 = MagicMock() + mock_sqlite3.connect.side_effect = Exception("DB error") + + with patch('os.path.exists', return_value=True): + with patch.dict(sys.modules, {'sqlite3': mock_sqlite3}): + result = get_goose_sessions() + assert result == [] diff --git a/router/tests/test_get_redis.py b/router/tests/test_get_redis.py new file mode 100644 index 00000000..0fdeaed2 --- /dev/null +++ b/router/tests/test_get_redis.py @@ -0,0 +1,136 @@ +import os +import time +from unittest.mock import patch, MagicMock + +import pytest + +import router.main as main + +@pytest.fixture(autouse=True) +def reset_redis_globals(): + """Reset the global variables before and after each test.""" + original_client = main._redis_client + original_last_attempt = main._redis_last_init_attempt + + main._redis_client = None + main._redis_last_init_attempt = 0.0 + + yield + + main._redis_client = original_client + main._redis_last_init_attempt = original_last_attempt + +def test_get_redis_already_initialized(): + """If the client is already initialized, it should return the client immediately.""" + mock_client = MagicMock() + main._redis_client = mock_client + + assert main.get_redis() is mock_client + +@patch("router.main.time.monotonic") +def test_get_redis_cooldown(mock_monotonic): + """If init failed recently, it should return None without attempting to initialize.""" + main._redis_client = None + main._redis_last_init_attempt = 100.0 + + # Time elapsed is less than 5.0 seconds + mock_monotonic.return_value = 103.0 + + assert main.get_redis() is None + +@patch("router.main.time.monotonic") +@patch("router.main.aioredis.Redis") +@patch.dict(os.environ, {"VALKEY_HOST": "my-host", "VALKEY_PORT": "1234"}) +def test_get_redis_initialization_success(mock_redis, mock_monotonic): + """If sufficient time has passed, it should initialize and return the client.""" + main._redis_client = None + main._redis_last_init_attempt = 100.0 + + # Time elapsed is 10.0 seconds (greater than 5.0) + mock_monotonic.return_value = 110.0 + + mock_redis_instance = MagicMock() + mock_redis.return_value = mock_redis_instance + + client = main.get_redis() + + assert client is mock_redis_instance + assert main._redis_client is mock_redis_instance + assert main._redis_last_init_attempt == 110.0 + mock_redis.assert_called_once_with(host="my-host", port=1234, decode_responses=True, socket_timeout=1.0) + +@patch("router.main.time.monotonic") +@patch("router.main.logger.warning") +@patch.dict(os.environ, {"VALKEY_HOST": "my-host", "VALKEY_PORT": "invalid"}) +def test_get_redis_initialization_failure(mock_logger_warning, mock_monotonic): + """If initialization fails, it should catch the exception, log a warning, and return None.""" + main._redis_client = None + main._redis_last_init_attempt = 100.0 + + # Time elapsed is 10.0 seconds + mock_monotonic.return_value = 110.0 + + # The int() conversion of VALKEY_PORT will raise ValueError + client = main.get_redis() + + assert client is None + assert main._redis_client is None + assert main._redis_last_init_attempt == 110.0 + mock_logger_warning.assert_called_once() + assert "Failed to initialize Valkey client" in mock_logger_warning.call_args[0][0] + +@patch("router.main.time.monotonic") +@patch("router.main.aioredis.Redis") +@patch("router.main.logger.warning") +@patch.dict(os.environ, {"VALKEY_HOST": "my-host", "VALKEY_PORT": "1234"}) +def test_get_redis_initialization_exception(mock_logger_warning, mock_redis, mock_monotonic): + """If aioredis.Redis throws an exception, it should catch it and return None.""" + main._redis_client = None + main._redis_last_init_attempt = 100.0 + + mock_monotonic.return_value = 110.0 + + mock_redis.side_effect = Exception("Test Exception") + + client = main.get_redis() + + assert client is None + assert main._redis_client is None + assert main._redis_last_init_attempt == 110.0 + mock_logger_warning.assert_called_once() + assert "Test Exception" in mock_logger_warning.call_args[0][0] + +@patch("router.main.time.monotonic") +@patch("router.main.aioredis.Redis.from_url") +@patch.dict(os.environ, {"VALKEY_URL": "redis://my-url:1234"}) +def test_get_redis_simulation_flow_url(mock_from_url, mock_monotonic): + """Simulate the full flow for from_url: failure -> cooldown -> success -> cached.""" + # State is reset by the autouse fixture reset_redis_globals + + # 1. First attempt fails + mock_monotonic.return_value = 10.0 + mock_from_url.side_effect = Exception("Connection error") + assert main.get_redis() is None + assert main._redis_last_init_attempt == 10.0 + + # 2. Second attempt during cooldown (e.g. 12.0s) + mock_monotonic.return_value = 12.0 + mock_from_url.reset_mock() + assert main.get_redis() is None + mock_from_url.assert_not_called() + + # 3. Third attempt after cooldown (e.g. 16.0s) succeeds + mock_monotonic.return_value = 16.0 + mock_redis_instance = MagicMock() + mock_from_url.side_effect = None + mock_from_url.return_value = mock_redis_instance + client = main.get_redis() + assert client is mock_redis_instance + assert main._redis_client is mock_redis_instance + mock_from_url.assert_called_once() + + # 4. Fourth attempt returns cached instance + mock_monotonic.return_value = 18.0 + mock_from_url.reset_mock() + assert main.get_redis() is mock_redis_instance + mock_from_url.assert_not_called() diff --git a/router/tests/test_load_persisted_stats.py b/router/tests/test_load_persisted_stats.py new file mode 100644 index 00000000..76edbf51 --- /dev/null +++ b/router/tests/test_load_persisted_stats.py @@ -0,0 +1,61 @@ +import json +import pytest +from unittest.mock import patch, mock_open + +import router.main +from router.main import load_persisted_stats + +@pytest.fixture +def mock_stats(): + # Setup a clean stats dictionary for testing + clean_stats = { + "total_requests": 0, + "nested_dict": {"a": 1, "b": 2}, + "existing_key": "value" + } + with patch.dict(router.main.stats, clean_stats, clear=True): + yield router.main.stats + +def test_load_persisted_stats_file_not_exists(mock_stats): + with patch("router.main.os.path.exists", return_value=False) as mock_exists: + load_persisted_stats() + mock_exists.assert_called_once_with(router.main.STATS_JSON_PATH) + # Stats should remain unchanged + assert mock_stats["total_requests"] == 0 + +def test_load_persisted_stats_success(mock_stats): + mock_data = { + "total_requests": 100, + "nested_dict": {"b": 3, "c": 4}, + "new_key": "new_value" + } + mock_json = json.dumps(mock_data) + + with patch("router.main.os.path.exists", return_value=True): + with patch("router.main.open", mock_open(read_data=mock_json)): + with patch("router.main.logger.info") as mock_logger: + load_persisted_stats() + + # Assert simple value updated via else block + assert mock_stats["total_requests"] == 100 + # Assert nested_dict updated via if block (b updated, c added, a unchanged) + assert mock_stats["nested_dict"] == {"a": 1, "b": 3, "c": 4} + # Assert new_key added via else block + assert mock_stats["new_key"] == "new_value" + # Assert existing_key unchanged + assert mock_stats["existing_key"] == "value" + + mock_logger.assert_called_once_with("✓ Successfully loaded persisted gateway statistics from disk.") + +def test_load_persisted_stats_exception(mock_stats): + with patch("router.main.os.path.exists", return_value=True): + with patch("router.main.open", side_effect=Exception("Mock read error")): + with patch("router.main.logger.error") as mock_logger: + load_persisted_stats() + + # Stats should remain unchanged + assert mock_stats["total_requests"] == 0 + + # Error should be logged + mock_logger.assert_called_once() + assert "Failed to load persisted stats: Mock read error" in mock_logger.call_args[0][0] diff --git a/test_memory_mcp.py b/router/tests/test_memory_mcp.py similarity index 100% rename from test_memory_mcp.py rename to router/tests/test_memory_mcp.py diff --git a/scripts/benchmark_tokens.py b/scripts/benchmark_tokens.py new file mode 100644 index 00000000..d701b4eb --- /dev/null +++ b/scripts/benchmark_tokens.py @@ -0,0 +1,76 @@ +import sys +import os +from pathlib import Path + +# Set CONFIG_PATH and ROUTER_API_KEY for import +os.environ["CONFIG_PATH"] = str(Path(__file__).resolve().parent.parent / "router" / "config.yaml") +os.environ["ROUTER_API_KEY"] = "local-token" +# Add the parent directory and the router directory to the path +sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) +sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "router")) + +from router.main import estimate_prompt_tokens + +def verify_accuracy(): + """Benchmarking utility to verify token estimation accuracy across content types.""" + # Test cases inspired by the problem description + test_cases = [ + { + "name": "English prose", + "content": "This is a standard English prose sentence intended to evaluate the accuracy of the token estimation heuristic for typical content. " * 5, + "actual_tokens": 110, + }, + { + "name": "Python code", + "content": """ +def calculate_factorial(n): + if n == 0: + return 1 + else: + return n * calculate_factorial(n-1) + +for i in range(10): + print(f"Factorial of {i} is {calculate_factorial(i)}") +""" * 3, + "actual_tokens": 150, + }, + { + "name": "CJK text", + "content": "这是一个测试,用于验证中文字符的令牌估算逻辑。它应该比字符计数更准确。" * 5, + "actual_tokens": 60, + }, + { + "name": "Whitespace-padded JSON", + "content": '{\n "key": "value",\n "nested": {\n "inner": "data"\n }\n}\n' * 5, + "actual_tokens": 60, + }, + { + "name": "Emoji", + "content": "🚀🔥-🤖✨-📈💎-🚨🛠️-🌐" * 5, + "actual_tokens": 25, + } + ] + + print(f"{'Case':<25} | {'Actual':<7} | {'Estimated':<9} | {'Error':<7}") + print("-" * 55) + + all_passed = True + for case in test_cases: + body = {"messages": [{"content": case["content"]}]} + est = estimate_prompt_tokens(body) - 50 # Subtract metadata overhead + error = abs(est - case["actual_tokens"]) / case["actual_tokens"] + print(f"{case['name']:<25} | {case['actual_tokens']:<7} | {est:<9} | {error:.1%}") + # Acceptance criteria: within ±25% for these rough heuristics + if error > 0.25: + print(f" --> FAILURE: {case['name']} error exceeds target threshold") + all_passed = False + + assert all_passed, "Token estimation accuracy benchmark failed" + +if __name__ == "__main__": + try: + verify_accuracy() + sys.exit(0) + except AssertionError as e: + print(f"\nERROR: {e}") + sys.exit(1) diff --git a/scripts/get_pr_status.py b/scripts/get_pr_status.py new file mode 100644 index 00000000..d65f65f1 --- /dev/null +++ b/scripts/get_pr_status.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +import subprocess +import json +import sys +from typing import Sequence + + +def run_cmd(argv: Sequence[str]) -> str: + """Runs a command and returns stripped stdout.""" + result = subprocess.run(argv, shell=False, capture_output=True, text=True, check=True, timeout=30) + return result.stdout.strip() + + +def get_pr_status(pr_id: str = "") -> None: + """Fetches and prints the status of a PR using gh CLI.""" + cmd = ["gh", "pr", "view"] + if pr_id: + cmd.append(pr_id) + cmd.extend(["--json", "state,reviewDecision,statusCheckRollup"]) + + try: + output = run_cmd(cmd) + data = json.loads(output) + + state = data.get("state") + review = data.get("reviewDecision") or "NONE" + checks = data.get("statusCheckRollup", []) + + # Summarize checks + success_count = 0 + total_count = len(checks) + for check in checks: + # gh CLI returns conclusion for CheckRun and state for StatusContext + conclusion = check.get("conclusion") or check.get("state") + if conclusion == "SUCCESS": + success_count += 1 + + print(f"PR Status: {state}") + print(f"Review Decision: {review}") + print(f"Checks: {success_count}/{total_count} passed") + + except subprocess.CalledProcessError as e: + print(f"Error: Failed to fetch PR status: {e.stderr.strip()}", file=sys.stderr) + sys.exit(1) + except json.JSONDecodeError: + print("Error: Failed to parse gh CLI output", file=sys.stderr) + sys.exit(1) + except Exception as e: + print(f"An unexpected error occurred: {e}", file=sys.stderr) + sys.exit(1) + + +def main(): + pr_id = sys.argv[1] if len(sys.argv) > 1 else "" + get_pr_status(pr_id) + + +if __name__ == "__main__": + main() diff --git a/host_agy_daemon.py b/scripts/host_agy_daemon.py similarity index 100% rename from host_agy_daemon.py rename to scripts/host_agy_daemon.py diff --git a/sync_gemini_token.py b/scripts/sync_gemini_token.py similarity index 100% rename from sync_gemini_token.py rename to scripts/sync_gemini_token.py diff --git a/test_quota_reset.sh b/scripts/test_quota_reset.sh similarity index 100% rename from test_quota_reset.sh rename to scripts/test_quota_reset.sh diff --git a/verify_breaker.py b/scripts/verification/verify_breaker.py similarity index 100% rename from verify_breaker.py rename to scripts/verification/verify_breaker.py diff --git a/watch_quota.sh b/scripts/watch_quota.sh similarity index 100% rename from watch_quota.sh rename to scripts/watch_quota.sh diff --git a/start-stack.sh b/start-stack.sh index c9b826dc..03bb1220 100755 --- a/start-stack.sh +++ b/start-stack.sh @@ -31,12 +31,6 @@ if [ -f "$ENV_FILE" ]; then fi # Ensure openssl is installed if we need to generate passwords/keys -if [ -z "$POSTGRES_PASSWORD" ] || [ -z "$NEXTAUTH_SECRET" ] || [ -z "$SALT" ] || [ -z "$ENCRYPTION_KEY" ] || [ -z "$LITELLM_MASTER_KEY" ]; then - if ! command -v openssl &>/dev/null; then - echo "❌ Error: 'openssl' is required to generate secure random keys but was not found in PATH." - exit 1 - fi -fi if [ -z "$OPENROUTER_API_KEY" ]; then @@ -101,7 +95,7 @@ else echo "⚠️ Warning: Host agy daemon not responding on port 5005" fi -if [ -z "$NEXTAUTH_SECRET" ] || [ -z "$SALT" ] || [ -z "$ENCRYPTION_KEY" ] || [ -z "$LITELLM_MASTER_KEY" ] || [ -z "$ROUTER_API_KEY" ]; then +if [ -z "$POSTGRES_PASSWORD" ] || [ -z "$NEXTAUTH_SECRET" ] || [ -z "$SALT" ] || [ -z "$ENCRYPTION_KEY" ] || [ -z "$LITELLM_MASTER_KEY" ] || [ -z "$ROUTER_API_KEY" ] || [ -z "$MINIO_ROOT_USER" ] || [ -z "$MINIO_ROOT_PASSWORD" ]; then if ! command -v openssl &>/dev/null; then echo "❌ Error: 'openssl' is required to generate secure random keys but was not found in PATH." exit 1 @@ -141,12 +135,43 @@ if [ -z "$LITELLM_MASTER_KEY" ]; then exit 1 fi +if [ -z "$LANGFUSE_INIT_USER_PASSWORD" ]; then + LANGFUSE_INIT_USER_PASSWORD="$(openssl rand -hex 16)" + echo "LANGFUSE_INIT_USER_PASSWORD=\"$LANGFUSE_INIT_USER_PASSWORD\"" >> "$ENV_FILE" + echo "✓ Generated new LANGFUSE_INIT_USER_PASSWORD and saved to $ENV_FILE" +fi + +if [ -z "$REDIS_AUTH" ]; then + REDIS_AUTH="$(openssl rand -hex 16)" + echo "REDIS_AUTH=\"$REDIS_AUTH\"" >> "$ENV_FILE" + echo "✓ Generated new REDIS_AUTH and saved to $ENV_FILE" +fi + +if [ -z "$CLICKHOUSE_PASSWORD" ]; then + CLICKHOUSE_PASSWORD="$(openssl rand -hex 16)" + echo "CLICKHOUSE_PASSWORD=\"$CLICKHOUSE_PASSWORD\"" >> "$ENV_FILE" + echo "✓ Generated new CLICKHOUSE_PASSWORD and saved to $ENV_FILE" +fi + if [ -z "$ROUTER_API_KEY" ]; then ROUTER_API_KEY="$(openssl rand -hex 32)" echo "ROUTER_API_KEY=\"$ROUTER_API_KEY\"" >> "$ENV_FILE" echo "✓ Generated new ROUTER_API_KEY and saved to $ENV_FILE" fi +if [ -z "$MINIO_ROOT_USER" ]; then + MINIO_ROOT_USER="minio-$(openssl rand -hex 4)" + echo "MINIO_ROOT_USER=\"$MINIO_ROOT_USER\"" >> "$ENV_FILE" + echo "✓ Generated new MINIO_ROOT_USER and saved to $ENV_FILE" +fi + +if [ -z "$MINIO_ROOT_PASSWORD" ]; then + MINIO_ROOT_PASSWORD="$(openssl rand -hex 16)" + echo "MINIO_ROOT_PASSWORD=\"$MINIO_ROOT_PASSWORD\"" >> "$ENV_FILE" + echo "✓ Generated new MINIO_ROOT_PASSWORD and saved to $ENV_FILE" +fi + + # DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER in router config is resolved at runtime from env @@ -255,7 +280,7 @@ setup_minio_buckets() { # Ensure mc alias points to the correct MinIO S3 API port (9002, not 9000) # The default 'local' alias in the MinIO image points to :9000 which is ClickHouse, # not MinIO. We must override it. - podman exec agent-router-pod-minio-s3 mc alias set local http://127.0.0.1:9002 minioadmin minioadmin 2>/dev/null + podman exec agent-router-pod-minio-s3 mc alias set local http://127.0.0.1:9002 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD" 2>/dev/null # Create required buckets (idempotent) local BUCKETS=("langfuse-events" "proj-triage-gateway-id") @@ -356,7 +381,7 @@ if podman pod exists agent-router-pod 2>/dev/null; then fi render_pod_yaml() { - export WORKDIR HOME LITELLM_MASTER_KEY POSTGRES_PASSWORD NEXTAUTH_SECRET SALT ENCRYPTION_KEY + export WORKDIR HOME LITELLM_MASTER_KEY POSTGRES_PASSWORD NEXTAUTH_SECRET SALT ENCRYPTION_KEY LANGFUSE_INIT_USER_PASSWORD MINIO_ROOT_USER MINIO_ROOT_PASSWORD python3 - "$WORKDIR/pod.yaml" <<'PY' import os, sys, urllib.parse uid = os.getuid() @@ -371,11 +396,14 @@ placeholders = [ "NEXTAUTH_SECRET_PLACEHOLDER", "SALT_PLACEHOLDER", "ENCRYPTION_KEY_PLACEHOLDER", - "postgres-password-***" + "postgres-password-***", + "MINIO_USER_PLACEHOLDER", + "MINIO_PASSWORD_PLACEHOLDER" + "LANGFUSE_INIT_USER_PASSWORD_PLACEHOLDER" ] for ph in placeholders: if ph not in text: - sys.stderr.write(f"Error: Required placeholder '{ph}' not found in pod.yaml\n") + sys.stderr.write(f"Error: Required placeholder '{ph}' not found in pod.yaml. Ensure you are using the latest version of the template.\n") sys.exit(1) text = text.replace("/home/gpav/Vrac/LAB/AI/LLM-Routing", os.environ["WORKDIR"]) text = text.replace("/home/gpav/", os.environ["HOME"] + "/") @@ -388,6 +416,9 @@ text = text.replace("postgres-password-***", os.environ["POSTGRES_PASSWORD"]) text = text.replace("NEXTAUTH_SECRET_PLACEHOLDER", os.environ["NEXTAUTH_SECRET"]) text = text.replace("SALT_PLACEHOLDER", os.environ["SALT"]) text = text.replace("ENCRYPTION_KEY_PLACEHOLDER", os.environ["ENCRYPTION_KEY"]) +text = text.replace("MINIO_USER_PLACEHOLDER", os.environ["MINIO_ROOT_USER"]) +text = text.replace("MINIO_PASSWORD_PLACEHOLDER", os.environ["MINIO_ROOT_PASSWORD"]) +text = text.replace("LANGFUSE_INIT_USER_PASSWORD_PLACEHOLDER", os.environ["LANGFUSE_INIT_USER_PASSWORD"]) sys.stdout.write(text) PY } diff --git a/test_a2_verify.py b/tests/test_a2_verify.py similarity index 100% rename from test_a2_verify.py rename to tests/test_a2_verify.py diff --git a/test_agy_behavior.py b/tests/test_agy_behavior.py similarity index 100% rename from test_agy_behavior.py rename to tests/test_agy_behavior.py diff --git a/test_agy_tiers.py b/tests/test_agy_tiers.py similarity index 100% rename from test_agy_tiers.py rename to tests/test_agy_tiers.py diff --git a/test_antigravity.py b/tests/test_antigravity.py similarity index 100% rename from test_antigravity.py rename to tests/test_antigravity.py diff --git a/test_atomic_write.py b/tests/test_atomic_write.py similarity index 100% rename from test_atomic_write.py rename to tests/test_atomic_write.py diff --git a/test_check_http_endpoint.py b/tests/test_check_http_endpoint.py similarity index 100% rename from test_check_http_endpoint.py rename to tests/test_check_http_endpoint.py diff --git a/test_circuit_breaker.py b/tests/test_circuit_breaker.py similarity index 100% rename from test_circuit_breaker.py rename to tests/test_circuit_breaker.py diff --git a/test_classifier_accuracy.py b/tests/test_classifier_accuracy.py similarity index 100% rename from test_classifier_accuracy.py rename to tests/test_classifier_accuracy.py diff --git a/test_compute_free_model_score.py b/tests/test_compute_free_model_score.py similarity index 100% rename from test_compute_free_model_score.py rename to tests/test_compute_free_model_score.py diff --git a/tests/test_get_pr_status.py b/tests/test_get_pr_status.py new file mode 100644 index 00000000..93885a14 --- /dev/null +++ b/tests/test_get_pr_status.py @@ -0,0 +1,84 @@ +import pytest +import subprocess +import json +from unittest.mock import patch, MagicMock +from scripts.get_pr_status import run_cmd, get_pr_status + +def test_run_cmd_success(): + output = run_cmd(["echo", "hello"]) + assert output == "hello" + +def test_run_cmd_strips_whitespace(): + output = run_cmd(["echo", " hello "]) + assert output == "hello" + +def test_run_cmd_error(): + with pytest.raises(subprocess.CalledProcessError): + run_cmd(["false"]) + +@patch("scripts.get_pr_status.subprocess.run") +def test_run_cmd_timeout(mock_run): + # run_cmd has a 30s timeout. We mock subprocess.run to raise it immediately. + mock_run.side_effect = subprocess.TimeoutExpired(["sleep", "0.1"], 30) + with pytest.raises(subprocess.TimeoutExpired): + run_cmd(["sleep", "0.1"]) + +@patch("scripts.get_pr_status.run_cmd") +def test_get_pr_status_success(mock_run_cmd, capsys): + mock_data = { + "state": "OPEN", + "reviewDecision": "APPROVED", + "statusCheckRollup": [ + {"conclusion": "SUCCESS", "name": "test1"}, + {"state": "SUCCESS", "name": "test2"}, + {"conclusion": "FAILURE", "name": "test3"} + ] + } + mock_run_cmd.return_value = json.dumps(mock_data) + + get_pr_status("123") + + captured = capsys.readouterr() + assert "PR Status: OPEN" in captured.out + assert "Review Decision: APPROVED" in captured.out + assert "Checks: 2/3 passed" in captured.out + mock_run_cmd.assert_called_once_with(["gh", "pr", "view", "123", "--json", "state,reviewDecision,statusCheckRollup"]) + +@patch("scripts.get_pr_status.run_cmd") +def test_get_pr_status_no_id(mock_run_cmd, capsys): + mock_data = { + "state": "MERGED", + "reviewDecision": None, + "statusCheckRollup": [] + } + mock_run_cmd.return_value = json.dumps(mock_data) + + get_pr_status() + + captured = capsys.readouterr() + assert "PR Status: MERGED" in captured.out + assert "Review Decision: NONE" in captured.out + assert "Checks: 0/0 passed" in captured.out + mock_run_cmd.assert_called_once_with(["gh", "pr", "view", "--json", "state,reviewDecision,statusCheckRollup"]) + +@patch("scripts.get_pr_status.run_cmd") +def test_get_pr_status_error(mock_run_cmd, capsys): + mock_run_cmd.side_effect = subprocess.CalledProcessError(1, ["gh"], stderr="gh not found") + + with pytest.raises(SystemExit) as e: + get_pr_status("123") + + assert e.value.code == 1 + captured = capsys.readouterr() + assert "Error: Failed to fetch PR status: gh not found" in captured.err + +@patch("scripts.get_pr_status.run_cmd") +def test_get_pr_status_invalid_json(mock_run_cmd, capsys): + mock_run_cmd.return_value = "invalid json" + + with pytest.raises(SystemExit) as e: + get_pr_status("123") + + assert e.value.code == 1 + captured = capsys.readouterr() + assert "Error: Failed to parse gh CLI output" in captured.err diff --git a/tests/test_host_agy_daemon.py b/tests/test_host_agy_daemon.py new file mode 100644 index 00000000..61f84e86 --- /dev/null +++ b/tests/test_host_agy_daemon.py @@ -0,0 +1,490 @@ +import asyncio +import json +import os +import socket +import threading +import urllib.error +import urllib.request +from unittest.mock import AsyncMock + +import pytest + +import sys +from pathlib import Path + +# Dynamic project root discovery +root = Path(__file__).resolve() +while root.parent != root and not (root / ".git").exists(): + root = root.parent +sys.path.insert(0, str(root)) +sys.path.insert(0, str(root / "scripts")) + +import host_agy_daemon + +def find_free_port(): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind(('127.0.0.1', 0)) + return s.getsockname()[1] + +@pytest.fixture +def daemon_server(): + port = find_free_port() + host_agy_daemon.PORT = port + + server = host_agy_daemon.ThreadingHTTPServer(('127.0.0.1', port), host_agy_daemon.AgyDaemonHandler) + server_thread = threading.Thread(target=server.serve_forever, daemon=True) + server_thread.start() + + yield f"http://127.0.0.1:{port}" + + server.shutdown() + server.server_close() + server_thread.join() + +def test_get_last_conversation_id(monkeypatch, tmp_path): + cache_file = tmp_path / "last_conversations.json" + cache_file.write_text(json.dumps({"/fake/cwd": "conv_123"})) + + monkeypatch.setattr(host_agy_daemon, "CACHE_FILE", str(cache_file)) + monkeypatch.setattr(host_agy_daemon.os, "getcwd", lambda: "/fake/cwd") + + assert host_agy_daemon.get_last_conversation_id() == "conv_123" + + monkeypatch.setattr(host_agy_daemon.os, "getcwd", lambda: "/other/cwd") + assert host_agy_daemon.get_last_conversation_id() is None + +def test_get_last_conversation_id_no_file(monkeypatch): + monkeypatch.setattr(host_agy_daemon, "CACHE_FILE", "/does/not/exist.json") + assert host_agy_daemon.get_last_conversation_id() is None + +def test_get_last_conversation_id_invalid_json(monkeypatch, tmp_path): + cache_file = tmp_path / "last_conversations.json" + cache_file.write_text("invalid json") + + monkeypatch.setattr(host_agy_daemon, "CACHE_FILE", str(cache_file)) + assert host_agy_daemon.get_last_conversation_id() is None + +def test_get_last_conversation_id_io_error(monkeypatch): + monkeypatch.setattr(host_agy_daemon, "CACHE_FILE", "/fake/cache.json") + monkeypatch.setattr(host_agy_daemon.os.path, "exists", lambda x: True) + def mock_open_err(*args, **kwargs): + raise IOError("permission denied") + monkeypatch.setattr("builtins.open", mock_open_err) + assert host_agy_daemon.get_last_conversation_id() is None + +def test_daemon_post_404(daemon_server): + req = urllib.request.Request(f"{daemon_server}/invalid", method="POST") + with pytest.raises(urllib.error.HTTPError) as exc: + urllib.request.urlopen(req) + assert exc.value.code == 404 + +def test_daemon_post_stream_false(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": False, "conversation_id": "conv_abc", "model_override": "gpt-4"}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + assert args == (host_agy_daemon.AGY_BINARY, "--conversation", "conv_abc", "--print", "test prompt") + assert kwargs.get("env", {}).get("CASCADE_DEFAULT_MODEL_OVERRIDE") == "gpt-4" + mock_proc = AsyncMock() + mock_proc.returncode = 0 + mock_proc.wait = AsyncMock() + + if "stdout" in kwargs: + with open(kwargs["stdout"].name, "w") as f: + f.write("mocked stdout output") + if "stderr" in kwargs: + with open(kwargs["stderr"].name, "w") as f: + f.write("mocked stderr output") + + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + monkeypatch.setattr(host_agy_daemon, "get_last_conversation_id", lambda: "last_conv_456") + + with urllib.request.urlopen(req) as resp: + data = json.loads(resp.read().decode()) + + assert data["returncode"] == 0 + assert data["stdout"] == "mocked stdout output" + assert data["stderr"] == "mocked stderr output" + assert data["conversation_id"] == "last_conv_456" + +def test_daemon_post_stream_false_timeout(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": False, "timeout": 0.1}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + mock_proc = AsyncMock() + mock_proc.returncode = 0 + # Make wait take longer than timeout + async def slow_wait(): + await asyncio.sleep(0.5) + mock_proc.wait = slow_wait + # Make kill synchronous + mock_proc.kill = lambda: None + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + + with urllib.request.urlopen(req) as resp: + data = json.loads(resp.read().decode()) + + assert data["returncode"] == -1 + assert data["stderr"] == "TIMEOUT" + +def test_daemon_post_stream_true(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": True, "model_override": "test-model"}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + assert args == (host_agy_daemon.AGY_BINARY, "--print", "test prompt") + assert kwargs.get("env", {}).get("CASCADE_DEFAULT_MODEL_OVERRIDE") == "test-model" + mock_proc = AsyncMock() + mock_proc.returncode = 0 + mock_proc.wait = AsyncMock() + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + monkeypatch.setattr(host_agy_daemon, "get_last_conversation_id", lambda: "last_conv_456") + + read_calls = 0 + def mock_read(fd, n): + nonlocal read_calls + if read_calls == 0: + read_calls += 1 + return b"token1\r\n" + elif read_calls == 1: + read_calls += 1 + return b"token2\r\n" + return b"" + + monkeypatch.setattr(host_agy_daemon.os, "read", mock_read) + + with urllib.request.urlopen(req) as resp: + content = resp.read().decode().strip() + lines = content.split("\n") + + assert len(lines) == 3 + assert json.loads(lines[0]) == {"type": "token", "content": "token1\n"} + assert json.loads(lines[1]) == {"type": "token", "content": "token2\n"} + assert json.loads(lines[2]) == {"type": "status", "returncode": 0, "conversation_id": "last_conv_456"} + +def test_daemon_post_stream_true_exec_error(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": True}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + raise Exception("exec failed") + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + + with urllib.request.urlopen(req) as resp: + content = resp.read().decode().strip() + lines = content.split("\n") + + assert len(lines) == 1 + assert json.loads(lines[0]) == {"type": "status", "returncode": -1, "stderr": "exec failed"} + +def test_daemon_post_stream_true_timeout(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": True, "timeout": 0.1}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + mock_proc = AsyncMock() + mock_proc.returncode = 0 + async def slow_wait(): + await asyncio.sleep(0.5) + mock_proc.wait = slow_wait + # Make kill synchronous + mock_proc.kill = lambda: None + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + monkeypatch.setattr(host_agy_daemon, "get_last_conversation_id", lambda: None) + + read_calls = 0 + def mock_read(fd, n): + nonlocal read_calls + if read_calls == 0: + read_calls += 1 + return b"token1\n" + return b"" + + monkeypatch.setattr(host_agy_daemon.os, "read", mock_read) + + with urllib.request.urlopen(req) as resp: + content = resp.read().decode().strip() + lines = content.split("\n") + + assert len(lines) == 2 + assert json.loads(lines[0]) == {"type": "token", "content": "token1\n"} + assert json.loads(lines[1]) == {"type": "status", "returncode": -1, "conversation_id": None} + +def test_log_message_silenced(): + # Instantiate the class, bypassing BaseHTTPRequestHandler.__init__ + handler = host_agy_daemon.AgyDaemonHandler.__new__(host_agy_daemon.AgyDaemonHandler) + # Shouldn't raise any error + handler.log_message("format %s", "arg") + +def test_run_server_interrupt(monkeypatch): + # Mock serve_forever to raise KeyboardInterrupt + def mock_serve_forever(self): + raise KeyboardInterrupt() + + monkeypatch.setattr(host_agy_daemon.ThreadingHTTPServer, "serve_forever", mock_serve_forever) + + # Track if server_close was called + close_called = False + def mock_server_close(self): + nonlocal close_called + close_called = True + + monkeypatch.setattr(host_agy_daemon.ThreadingHTTPServer, "server_close", mock_server_close) + + # Should not raise exception + host_agy_daemon.run_server() + assert close_called + +def test_daemon_post_stream_false_no_model_override(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": False}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + assert "CASCADE_DEFAULT_MODEL_OVERRIDE" not in kwargs.get("env", {}) + mock_proc = AsyncMock() + mock_proc.returncode = 0 + mock_proc.wait = AsyncMock() + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + monkeypatch.setattr(host_agy_daemon.os.environ, "copy", lambda: {"CASCADE_DEFAULT_MODEL_OVERRIDE": "old-model"}) + + with urllib.request.urlopen(req) as resp: + data = json.loads(resp.read().decode()) + + assert data["returncode"] == 0 + +def test_daemon_post_stream_true_read_oserror(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": True}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + mock_proc = AsyncMock() + mock_proc.returncode = 0 + mock_proc.wait = AsyncMock() + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + + def mock_read(fd, n): + raise OSError("read error") + + monkeypatch.setattr(host_agy_daemon.os, "read", mock_read) + + with urllib.request.urlopen(req) as resp: + content = resp.read().decode().strip() + lines = content.split("\n") + + assert len(lines) == 1 + assert json.loads(lines[0])["type"] == "status" + +def test_daemon_post_stream_true_timeout_kill_fail(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": True, "timeout": 0.1}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + mock_proc = AsyncMock() + mock_proc.returncode = 0 + async def slow_wait(): + await asyncio.sleep(0.5) + mock_proc.wait = slow_wait + def mock_kill(): + raise Exception("kill failed") + mock_proc.kill = mock_kill + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + monkeypatch.setattr(host_agy_daemon.os, "read", lambda fd, n: b"") + monkeypatch.setattr(host_agy_daemon, "get_last_conversation_id", lambda: None) + + with urllib.request.urlopen(req) as resp: + content = resp.read().decode().strip() + lines = content.split("\n") + + assert len(lines) == 1 + assert json.loads(lines[0]) == {"type": "status", "returncode": -1, "conversation_id": None} + +def test_daemon_post_stream_true_wait_exception(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": True}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + mock_proc = AsyncMock() + mock_proc.returncode = 0 + async def mock_wait(): + raise Exception("wait failed") + mock_proc.wait = mock_wait + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + monkeypatch.setattr(host_agy_daemon.os, "read", lambda fd, n: b"") + monkeypatch.setattr(host_agy_daemon, "get_last_conversation_id", lambda: None) + + with urllib.request.urlopen(req) as resp: + content = resp.read().decode().strip() + lines = content.split("\n") + + assert len(lines) == 1 + assert json.loads(lines[0]) == {"type": "status", "returncode": -1, "conversation_id": None} + +def test_daemon_post_stream_false_timeout_kill_fail(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": False, "timeout": 0.1}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + mock_proc = AsyncMock() + mock_proc.returncode = 0 + async def slow_wait(): + await asyncio.sleep(0.5) + mock_proc.wait = slow_wait + def mock_kill(): + raise Exception("kill failed") + mock_proc.kill = mock_kill + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + + with urllib.request.urlopen(req) as resp: + data = json.loads(resp.read().decode()) + + assert data["returncode"] == -1 + assert data["stderr"] == "TIMEOUT" + +def test_daemon_post_stream_false_wait_exception(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": False}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + mock_proc = AsyncMock() + mock_proc.returncode = 0 + async def mock_wait(): + raise Exception("wait failed") + mock_proc.wait = mock_wait + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + + with urllib.request.urlopen(req) as resp: + data = json.loads(resp.read().decode()) + + assert data["returncode"] == -1 + +def test_daemon_post_stream_false_file_read_error(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": False}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + mock_proc = AsyncMock() + mock_proc.returncode = 0 + mock_proc.wait = AsyncMock() + + # Corrupt the temp files to cause read exceptions + os.unlink(kwargs["stdout"].name) + os.unlink(kwargs["stderr"].name) + + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + + with urllib.request.urlopen(req) as resp: + data = json.loads(resp.read().decode()) + + assert data["returncode"] == 0 + assert data["stdout"] == "" + assert data["stderr"] == "" + +def test_daemon_post_stream_false_unlink_error(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": False}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + mock_proc = AsyncMock() + mock_proc.returncode = 0 + mock_proc.wait = AsyncMock() + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + + def mock_unlink(path): + raise Exception("unlink failed") + + monkeypatch.setattr(host_agy_daemon.os, "unlink", mock_unlink) + + with urllib.request.urlopen(req) as resp: + data = json.loads(resp.read().decode()) + + assert data["returncode"] == 0 + +def test_daemon_post_stream_true_with_conversation(daemon_server, monkeypatch): + req = urllib.request.Request( + f"{daemon_server}/run", + data=json.dumps({"prompt": "test prompt", "stream": True, "conversation_id": "conv_789"}).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + async def mock_exec(*args, **kwargs): + assert args == (host_agy_daemon.AGY_BINARY, "--conversation", "conv_789", "--print", "test prompt") + mock_proc = AsyncMock() + mock_proc.returncode = 0 + mock_proc.wait = AsyncMock() + return mock_proc + + monkeypatch.setattr(host_agy_daemon.asyncio, "create_subprocess_exec", mock_exec) + monkeypatch.setattr(host_agy_daemon, "get_last_conversation_id", lambda: "conv_789") + monkeypatch.setattr(host_agy_daemon.os, "read", lambda fd, n: b"") + + with urllib.request.urlopen(req) as resp: + content = resp.read().decode().strip() + lines = content.split("\n") + + assert len(lines) == 1 + assert json.loads(lines[0]) == {"type": "status", "returncode": 0, "conversation_id": "conv_789"} diff --git a/test_map_tool_to_category.py b/tests/test_map_tool_to_category.py similarity index 100% rename from test_map_tool_to_category.py rename to tests/test_map_tool_to_category.py diff --git a/test_models_proxy.py b/tests/test_models_proxy.py similarity index 100% rename from test_models_proxy.py rename to tests/test_models_proxy.py diff --git a/test_pie_chart_gradient.py b/tests/test_pie_chart_gradient.py similarity index 100% rename from test_pie_chart_gradient.py rename to tests/test_pie_chart_gradient.py diff --git a/tests/test_read_annotations_async.py b/tests/test_read_annotations_async.py new file mode 100644 index 00000000..b401bc8b --- /dev/null +++ b/tests/test_read_annotations_async.py @@ -0,0 +1,128 @@ +import pytest +from unittest.mock import patch, AsyncMock, MagicMock +import copy +import sys +import os +import json +import asyncio + +# Ensure the root directory is in the path +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +import router.main +from router.main import _read_annotations_async + +@pytest.fixture(autouse=True) +def clear_cache(): + router.main._annotations_cache.clear() + yield + +@pytest.mark.asyncio +async def test_read_annotations_async_initial_read(): + fake_path = "/tmp/annotations.json" + fake_data = {"annotation1": "data1"} + + # Mock aiofiles.open + mock_file = AsyncMock() + mock_file.read.return_value = '{"annotation1": "data1"}' + + mock_context_manager = MagicMock() + mock_context_manager.__aenter__ = AsyncMock(return_value=mock_file) + mock_context_manager.__aexit__ = AsyncMock(return_value=False) + + mock_aiofiles_open = MagicMock(return_value=mock_context_manager) + + with patch("os.path.getmtime", return_value=100.0) as mock_getmtime, \ + patch("aiofiles.open", mock_aiofiles_open) as mock_open: + + result = await _read_annotations_async(fake_path) + + mock_getmtime.assert_called_once_with(fake_path) + mock_open.assert_called_once_with(fake_path, "r", encoding="utf-8") + assert result == fake_data + + # Verify cache is populated + assert fake_path in router.main._annotations_cache + assert router.main._annotations_cache[fake_path]["mtime"] == 100.0 + assert router.main._annotations_cache[fake_path]["data"] == fake_data + +@pytest.mark.asyncio +async def test_read_annotations_async_cache_hit(): + fake_path = "/tmp/annotations.json" + fake_data = {"annotation1": "data1"} + + # Pre-populate cache + router.main._annotations_cache[fake_path] = {"mtime": 100.0, "data": fake_data} + + # Mock aiofiles.open (should NOT be called) + mock_aiofiles_open = MagicMock() + + with patch("os.path.getmtime", return_value=100.0) as mock_getmtime, \ + patch("aiofiles.open", mock_aiofiles_open) as mock_open: + + result = await _read_annotations_async(fake_path) + + mock_getmtime.assert_called_once_with(fake_path) + mock_open.assert_not_called() + assert result == fake_data + +@pytest.mark.asyncio +async def test_read_annotations_async_cache_invalidation(): + fake_path = "/tmp/annotations.json" + fake_data_old = {"annotation1": "data1"} + fake_data_new = {"annotation2": "data2"} + + # Pre-populate cache with old mtime + router.main._annotations_cache[fake_path] = {"mtime": 100.0, "data": fake_data_old} + + mock_file = AsyncMock() + mock_file.read.return_value = '{"annotation2": "data2"}' + + mock_context_manager = MagicMock() + mock_context_manager.__aenter__ = AsyncMock(return_value=mock_file) + mock_context_manager.__aexit__ = AsyncMock(return_value=False) + + mock_aiofiles_open = MagicMock(return_value=mock_context_manager) + + with patch("os.path.getmtime", return_value=200.0) as mock_getmtime, \ + patch("aiofiles.open", mock_aiofiles_open) as mock_open: + + result = await _read_annotations_async(fake_path) + + mock_getmtime.assert_called_once_with(fake_path) + mock_open.assert_called_once_with(fake_path, "r", encoding="utf-8") + assert result == fake_data_new + + # Verify cache is updated + assert router.main._annotations_cache[fake_path]["mtime"] == 200.0 + assert router.main._annotations_cache[fake_path]["data"] == fake_data_new + +@pytest.mark.asyncio +async def test_read_annotations_async_deepcopy(): + fake_path = "/tmp/annotations.json" + fake_data = {"annotation1": {"nested": "value"}} + + # Pre-populate cache + router.main._annotations_cache[fake_path] = {"mtime": 100.0, "data": fake_data} + + with patch("os.path.getmtime", return_value=100.0): + # First read + result1 = await _read_annotations_async(fake_path) + + # Mutate the result + result1["annotation1"]["nested"] = "mutated" + + # Second read + result2 = await _read_annotations_async(fake_path) + + # Verify second read returns original data, not mutated + assert result2["annotation1"]["nested"] == "value" + assert router.main._annotations_cache[fake_path]["data"]["annotation1"]["nested"] == "value" + +@pytest.mark.asyncio +async def test_read_annotations_async_file_not_found(): + fake_path = "/tmp/annotations.json" + + with patch("os.path.getmtime", side_effect=FileNotFoundError): + with pytest.raises(FileNotFoundError): + await _read_annotations_async(fake_path) diff --git a/test_record_tool_usage.py b/tests/test_record_tool_usage.py similarity index 100% rename from test_record_tool_usage.py rename to tests/test_record_tool_usage.py diff --git a/test_src_badge.py b/tests/test_src_badge.py similarity index 100% rename from test_src_badge.py rename to tests/test_src_badge.py diff --git a/test_stream_latency.py b/tests/test_stream_latency.py similarity index 100% rename from test_stream_latency.py rename to tests/test_stream_latency.py diff --git a/test_sync_gemini_token.py b/tests/test_sync_gemini_token.py similarity index 100% rename from test_sync_gemini_token.py rename to tests/test_sync_gemini_token.py From d2391664fa32186024dfe840e7e249e240cde013 Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Wed, 1 Jul 2026 23:17:29 +0200 Subject: [PATCH 02/12] docs: update LiteLLM version pinning and test suite paths --- README.md | 4 ++-- scripts/README.md | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c093e9fe..7c80825c 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ graph TD style QwenLocal fill:#f0f0f0,stroke:#999,stroke-width:1px; ``` -> **Version Pin**: LiteLLM Gateway runs `ghcr.io/berriai/litellm:v1.88.0`. See §3B for pinning policy. +> **Version Pin**: LiteLLM Gateway runs `ghcr.io/berriai/litellm:v1.90.2`. See §3B for pinning policy. --- @@ -269,7 +269,7 @@ Exposes the entry endpoint (`http://localhost:5000/v1`) and evaluates prompt com > Model capabilities, token limits, and costs are visible in LiteLLM's Model Hub Table at `http://localhost:4000/ui/?page=model-hub-table` (or port 4000 on the gateway host). ### B. LiteLLM Proxy Gateway (`litellm/config.yaml`) -- **Version Pinning**: The LiteLLM gateway runs `ghcr.io/berriai/litellm:v1.88.0` (latest stable as of June 2026). The tag is explicitly pinned in `pod.yaml` — never use `:latest`. Check available tags with `skopeo list-tags docker://ghcr.io/berriai/litellm` before upgrading. ClickHouse runs `docker.io/clickhouse/clickhouse-server:26.5.1` (upgraded from 24.8, June 2026). Valkey Cache runs `docker.io/valkey/valkey:9.1.0-alpine` (upgraded from 8, June 2026). +- **Version Pinning**: The LiteLLM gateway runs `ghcr.io/berriai/litellm:v1.90.2` (latest stable as of June 2026). The tag is explicitly pinned in `pod.yaml` — never use `:latest`. Check available tags with `skopeo list-tags docker://ghcr.io/berriai/litellm` before upgrading. ClickHouse runs `docker.io/clickhouse/clickhouse-server:26.5.1` (upgraded from 24.8, June 2026). Valkey Cache runs `docker.io/valkey/valkey:9.1.0-alpine` (upgraded from 8, June 2026). Orchestrates routing fallback chains, Redis caching, and telemetry callbacks: - **`drop_params: true`**: Automatically strips unsupported arguments when transitioning to models that don't support them. - **Request Timeouts (`300s`)**: Provides ample padding to prevent connection aborts during dynamic RAM swapping operations on the local GPU `llama-server`. diff --git a/scripts/README.md b/scripts/README.md index 0139e8d3..4086a932 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -60,26 +60,26 @@ These tools are used to benchmark the prompt classifier and extract datasets fro --- -## 4. Integration Test Suite (Root Directory) +## 4. Integration Test Suite -The integration test suite is located in the root directory. Tests are categorized below based on their primary function: +The integration test suite is located in the `tests/` and `scripts/` directories. Tests are categorized below based on their primary function: ### Circuit Breaker Tests -- **`test_circuit_breaker.py`**: Unit/integration tests for the dual circuit breaker (`router/circuit_breaker.py`), covering independent Google/Vendor tiers and probe-granting logic. -- **`verify_breaker.py`**: Sanity verification check for the circuit breaker. -- **`test_a2_verify.py`**: Quick sanity integration check for the agy proxy circuit breaker. +- **`tests/test_circuit_breaker.py`**: Unit/integration tests for the dual circuit breaker (`router/circuit_breaker.py`), covering independent Google/Vendor tiers and probe-granting logic. +- **`scripts/verification/verify_breaker.py`**: Sanity verification check for the circuit breaker. +- **`tests/test_a2_verify.py`**: Quick sanity integration check for the agy proxy circuit breaker. ### Classifier Tests -- **`test_classifier_accuracy.py`**: Accuracy evaluation suite covering 25 system prompts. +- **`tests/test_classifier_accuracy.py`**: Accuracy evaluation suite covering 25 system prompts. ### Routing & Proxy Tests -- **`test_agy_tiers.py`**: Validates `agy` proxy model tier routing. -- **`test_antigravity.py`**: Tests the connection to the host Antigravity CLI daemon (`agentapi`). +- **`tests/test_agy_tiers.py`**: Validates `agy` proxy model tier routing. +- **`tests/test_antigravity.py`**: Tests the connection to the host Antigravity CLI daemon (`agentapi`). ### Performance & Monitoring Tests -- **`test_stream_latency.py`**: Measures Time-To-First-Token (TTFT) and token generation speed. +- **`tests/test_stream_latency.py`**: Measures Time-To-First-Token (TTFT) and token generation speed. ### Simulation Tests -- **`test_agy_behavior.py`**: Asserts the behavior of the `agy` CLI client under quota limits. -- **`test_quota_reset.sh`**: Simulates/triggers quota reset conditions. -- **`watch_quota.sh`**: Watch/polling script for observing quota status. +- **`tests/test_agy_behavior.py`**: Asserts the behavior of the `agy` CLI client under quota limits. +- **`scripts/test_quota_reset.sh`**: Simulates/triggers quota reset conditions. +- **`scripts/watch_quota.sh`**: Watch/polling script for observing quota status. From 4422f4605f4eb6fdae58ac8065f14407528e6ff3 Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Wed, 1 Jul 2026 23:22:00 +0200 Subject: [PATCH 03/12] chore: add bot rebase/conflict guidelines and regression report to .agents/ --- .agents/AGENTS.md | 8 +++ .agents/jules_regression_analysis.md | 81 ++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 .agents/jules_regression_analysis.md diff --git a/.agents/AGENTS.md b/.agents/AGENTS.md index c7de7c06..260dee2c 100644 --- a/.agents/AGENTS.md +++ b/.agents/AGENTS.md @@ -18,3 +18,11 @@ When working on this project, always refer to the dedicated **NotebookLM Compani Use the `notebooklm` MCP tools to search or ask questions about this codebase and stack: - Run `notebook_ask` with `notebook_id: "llm-triage-gateway"` to ground your reasoning or implementation plans. - If you need session continuation, remember to reuse the `session_id` returned by previous queries. + +## Git Rebase & Conflict Resolution Policy +To prevent directory reorganization regressions, outdated file restorations, or security credential overrides during merge conflict resolution, all automated agents must strictly follow these rules: + +1. **Rebase Over Merge**: Always fetch and rebase the topic/feature branch onto the latest `master` base branch (using `git rebase origin/master`) instead of performing `git merge`. +2. **Directory Rename Safety**: If Git reports conflicts related to moved directories or files, do not manually stage deletions of folders (`tests/`, `scripts/`) or re-create files at the root level. Direct all changes to the newly refactored paths. +3. **Verify Security Credentials**: Never accept resolutions that overwrite configuration files (`pod.yaml`, `start-stack.sh`) with hardcoded default passwords. Ensure placeholder-based configurations are preserved. +4. **Enforce Test Suite Count**: Run the full unit test suite (`pytest`) after conflict resolution. Verify that the total number of passing tests is equal to or greater than before the resolution. diff --git a/.agents/jules_regression_analysis.md b/.agents/jules_regression_analysis.md new file mode 100644 index 00000000..78899f39 --- /dev/null +++ b/.agents/jules_regression_analysis.md @@ -0,0 +1,81 @@ +# Analysis of Bot Merge Conflict Regressions & Guardrails + +This document breaks down the root causes of the regressions introduced by the automated agent (`jules[bot]`) during recent merges, compares Git resolution strategies, and outlines prompt modifications and guardrails to prevent future occurrences. + +--- + +## 1. What Went Wrong? + +The primary failure arose from a combination of **reorganization conflict logic** and **blind resolution choices**: + +### A. The Directory Rename / Delete Conflict Mismatch +* **Context**: PR #181 reorganized the repository by moving files at the root (like `test_a2_verify.py` and `host_agy_daemon.py`) into nested directories (`tests/` and `scripts/`). +* **The Bot's Branch State**: The bot was working on older branches (`perf-optimize-gemini-oauth-token`, `refactor-record-tool-usage`) whose base commits predated the reorganization. +* **The Failure**: When merging `master` into these older feature branches, Git detected conflict types like `rename/delete` or `directory rename detection`. Because the bot resolved conflicts locally inside the old workspace structure, it staged the **deletion** of the new files inside `tests/` and `scripts/` and re-introduced older, obsolete root-level files. +* **Result**: Merges from these branches back to `master` cleanly deleted the subfolder-bound tests and re-added old copies at the root. + +### B. Lack of Cross-Check Verification +* The bot resolved conflicts file-by-file without compiling the whole project or validating the full test suite (`pytest`) on the combined codebase. +* It accepted obsolete file versions wholesale (e.g., reverting the dynamic passwords in `pod.yaml` and `start-stack.sh` to hardcoded credentials) because it assumed conflict markers in one block did not impact security/logic blocks elsewhere. + +--- + +## 2. Which Git Strategy Should Have Been Used? + +Instead of merging `master` directly into older feature branches (which creates complex, multi-directional merge graphs), the following strategies are far safer for LLM agents: + +### Option A: `git rebase master` (Recommended for Feature Branches) +Rather than a merge commit, the agent should rebase the feature branch onto the latest `master` commit: +```bash +git checkout feature-branch +git fetch origin +git rebase origin/master +``` +* **Why it works**: Rebase replays each feature branch commit one-by-one on top of the reorganized `master` commit. +* **Rename Tracking**: Git's rename tracking algorithm handles moves seamlessly during a rebase. If a file was renamed from `test_a2_verify.py` to `tests/test_a2_verify.py` on `master`, Git will automatically apply the feature branch's modifications to `tests/test_a2_verify.py` instead of leaving them at the root. + +### Option B: Merge with explicit Merge Drivers +If rebasing is not used, the agent must inspect renames before committing: +```bash +git diff --name-status origin/master...HEAD +``` +This lists any deleted/added files to quickly verify that no folder moves were silently discarded. + +--- + +## 3. Recommended Prompt Guardrails and System Rules + +To prevent automated agents from causing directory and code regressions, the following rules should be appended to the agent's instructions (e.g., in `.agents/AGENTS.md` or system guidelines): + +### Rule 1: Git Conflict Rebase Mandate +> [!IMPORTANT] +> When updating a feature branch with `master`/`main` changes, always prefer `git rebase` over `git merge`. If conflicts arise due to renamed directories, do not manually delete folders or re-add root counterparts. Ensure files are modified in their new paths. + +### Rule 2: Complete Test Suite Verification +> [!WARNING] +> Never push conflict resolutions without running the full test suite. +> * If the workspace previously had $N$ passing tests, the resolved branch must have at least $N$ passing tests. +> * Confirm all files staged for deletion or addition are intentional using `git diff --stat origin/master`. + +### Rule 3: File Integrity & Verification Checklist +Add a post-conflict verification script step to the agent workflow: +```bash +# Verify no files were moved to root unexpectedly +git status | grep -E "renamed:|deleted:|new file:" +``` + +--- + +## 4. Proposed Instructions / Prompts for Bot Agents + +When tasking an agent with conflict resolution or merging, use a structured prompt like this: + +```markdown +You are resolving merge conflicts for the branch [branch_name]. + +1. Run `git fetch origin` and `git rebase origin/master`. +2. If conflicts arise, inspect whether any files were renamed/moved in master. Apply your changes to the renamed files in their new locations, rather than re-creating them at their old locations. +3. Once rebased, run the entire test suite: `pytest`. +4. Run `git diff --stat origin/master` and review every file addition/deletion. Verify that no tests or scripts are missing compared to master. +5. If any test files or core logic sections are missing, checkout the missing files from master and apply changes cleanly. +``` From 7c457f76cc610e227026c420a9a040ba226521de Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Wed, 1 Jul 2026 23:24:30 +0200 Subject: [PATCH 04/12] ci: add aiofiles to dependencies and update test paths --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0b8e5878..0fc98319 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,13 +23,13 @@ jobs: python-version: '3.11' - name: Install dependencies - run: pip install httpx==0.28.1 pytest pytest-asyncio anyio pyyaml fastapi "pydantic>=2.0,<3.0" uvicorn python-multipart asyncpg langfuse redis + run: pip install httpx==0.28.1 pytest pytest-asyncio anyio pyyaml fastapi "pydantic>=2.0,<3.0" uvicorn python-multipart asyncpg langfuse redis aiofiles - name: Run Unit Tests - run: CONFIG_PATH=router/config.yaml PYTHONPATH=.:router pytest --ignore=test_agy_behavior.py --ignore=test_agy_tiers.py + run: CONFIG_PATH=router/config.yaml PYTHONPATH=.:router pytest --ignore=tests/test_agy_behavior.py --ignore=tests/test_agy_tiers.py - name: Run Breaker Verification - run: python3 verify_breaker.py + run: PYTHONPATH=. python3 scripts/verification/verify_breaker.py - name: Run Integration Verification - run: python3 test_a2_verify.py + run: PYTHONPATH=.:router python3 tests/test_a2_verify.py From 4d8cea0321373517fc825e83a79f89e0f8999005 Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Wed, 1 Jul 2026 23:25:42 +0200 Subject: [PATCH 05/12] test: wrap test_agy_behavior.py execution in main block to prevent import-time crashes during pytest collection --- tests/test_agy_behavior.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_agy_behavior.py b/tests/test_agy_behavior.py index 6dade8f6..37eb1dd1 100644 --- a/tests/test_agy_behavior.py +++ b/tests/test_agy_behavior.py @@ -34,4 +34,5 @@ async def test(): if "RESOURCE_EXHAUSTED" in line or "quota" in line.lower(): print(f" {line.rstrip()}") -asyncio.run(test()) \ No newline at end of file +if __name__ == "__main__": + asyncio.run(test()) \ No newline at end of file From e45e7fc828ee95630260da4e6b8c9e99b181d042 Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Wed, 1 Jul 2026 23:27:32 +0200 Subject: [PATCH 06/12] chore: restore category sanitization security patch in memory_mcp.py and fix router/Dockerfile dependencies --- router/Dockerfile | 2 +- router/memory_mcp.py | 8 +- router/tests/test_memory_mcp.py | 288 ++++++++++++++++++++++++-------- 3 files changed, 224 insertions(+), 74 deletions(-) diff --git a/router/Dockerfile b/router/Dockerfile index cd0f3653..49d9c6a6 100644 --- a/router/Dockerfile +++ b/router/Dockerfile @@ -3,7 +3,7 @@ FROM python:3.14-slim WORKDIR /app # Install deps in a single layer (no pip cache, no extra files) -RUN pip install --no-cache-dir fastapi "pydantic>=2.0,<3.0" uvicorn httpx pyyaml python-multipart asyncpg langfuse redis +RUN pip install --no-cache-dir fastapi "pydantic>=2.0,<3.0" uvicorn httpx pyyaml python-multipart asyncpg langfuse redis aiofiles # Copy all source in one layer — removes dead config COPY (volume-mounted at runtime) COPY main.py agy_proxy.py circuit_breaker.py aa_scores.json free_models_roster.json /app/ diff --git a/router/memory_mcp.py b/router/memory_mcp.py index f2187282..7ec87c26 100755 --- a/router/memory_mcp.py +++ b/router/memory_mcp.py @@ -17,6 +17,7 @@ import time import hashlib import httpx +import urllib.parse API_URL = "http://127.0.0.1:5000/v1/memory" PROTOCOL_VERSION = "2024-11-05" @@ -44,7 +45,8 @@ def _make_key(category: str, is_global: bool, data: str) -> str: # BLAKE2b: SOTA crypto hash, stdlib, faster than MD5, deterministic across restarts. # Provides uniqueness within the same millisecond. h = hashlib.blake2b((data + str(ts)).encode("utf-8"), digest_size=HASH_DIGEST_SIZE).hexdigest() - return f"{PREFIX}:{scope}:{category}::{ts}:{h}" + safe_category = urllib.parse.quote(category) + return f"{PREFIX}:{scope}:{safe_category}::{ts}:{h}" def _parse_key(key: str): @@ -53,7 +55,7 @@ def _parse_key(key: str): parts = key.split("::") prefix = parts[0].split(":") # memory:{scope}:{category} scope = prefix[1] if len(prefix) > 1 else "" - category = prefix[2] if len(prefix) > 2 else "" + category = urllib.parse.unquote(prefix[2]) if len(prefix) > 2 else "" ts_hash = parts[1] if len(parts) > 1 else "" ts = ts_hash.split(":")[0] if ts_hash else "" return {"scope": scope, "category": category, "timestamp": ts} @@ -68,6 +70,8 @@ def _parse_key(key: str): def _is_memory_key(key: str) -> bool: """Check if a key follows the memory:{scope}:{category}:: format.""" + if not isinstance(key, str): + return False return key.startswith(f"{PREFIX}:") diff --git a/router/tests/test_memory_mcp.py b/router/tests/test_memory_mcp.py index 0194dca9..8c93f1f6 100644 --- a/router/tests/test_memory_mcp.py +++ b/router/tests/test_memory_mcp.py @@ -1,11 +1,166 @@ -#!/usr/bin/env python3 -""" -Tests for memory_mcp.py -""" -import sys import json +import re +import sys +import time +from pathlib import Path + +# Dynamic project root discovery +root = Path(__file__).resolve() +while root.parent != root and not (root / ".git").exists(): + root = root.parent +sys.path.insert(0, str(root)) +sys.path.insert(0, str(root / "router")) + import pytest -from router.memory_mcp import _memory_entry, _parse_key, _parse_memory_value +from memory_mcp import ( + PREFIX, + SCOPE_GLOBAL, + SCOPE_LOCAL, + _make_key, + _memory_entry, + _memory_value, + _parse_key, + _parse_memory_value, +) + + +# ===================================================================== +# Tests from router/test_memory_mcp.py +# ===================================================================== + +def test_make_key_global(): + """Test generating a key for global scope.""" + category = "test_cat" + data = "test_data" + + before_ts = int(time.time() * 1000) + key = _make_key(category, True, data) + after_ts = int(time.time() * 1000) + + # Expected format: f"{PREFIX}:{scope}:{category}::{ts}:{h}" + assert key.startswith(f"{PREFIX}:{SCOPE_GLOBAL}:{category}::") + + # Extract timestamp and hash part + match = re.match(rf"^{PREFIX}:{SCOPE_GLOBAL}:{category}::(\d+):([a-f0-9]+)$", key) + assert match is not None, f"Key {key} does not match expected format" + + ts = int(match.group(1)) + h = match.group(2) + + assert before_ts <= ts <= after_ts + assert len(h) == 20 + + +def test_make_key_local(): + """Test generating a key for local scope.""" + category = "another_cat" + data = "more_data" + + before_ts = int(time.time() * 1000) + key = _make_key(category, False, data) + after_ts = int(time.time() * 1000) + + assert key.startswith(f"{PREFIX}:{SCOPE_LOCAL}:{category}::") + + match = re.match(rf"^{PREFIX}:{SCOPE_LOCAL}:{category}::(\d+):([a-f0-9]+)$", key) + assert match is not None, f"Key {key} does not match expected format" + + ts = int(match.group(1)) + h = match.group(2) + + assert before_ts <= ts <= after_ts + assert len(h) == 20 + + +def test_make_key_formatting_details(monkeypatch): + """Test the exact output formatting of _make_key using deterministic BLAKE2b.""" + # Mock time.time to return a predictable float so ts = 1620000000123 + monkeypatch.setattr(time, "time", lambda: 1620000000.123) + + # data="data", ts=1620000000123 -> blake2b("data1620000000123", digest_size=10) -> 5e5dad075ca7764bc51f + key1 = _make_key("cat1", True, "data") + assert key1 == f"{PREFIX}:{SCOPE_GLOBAL}:cat1::1620000000123:5e5dad075ca7764bc51f" + + key2 = _make_key("cat2", False, "data") + assert key2 == f"{PREFIX}:{SCOPE_LOCAL}:cat2::1620000000123:5e5dad075ca7764bc51f" + + +def test_make_key_determinism_and_uniqueness(): + """Test determinism for same inputs within same timestamp, and uniqueness across timestamps/data.""" + category = "test_cat" + data1 = "data1" + data2 = "data2" + + key1 = _make_key(category, True, data1) + time.sleep(0.002) + key2 = _make_key(category, True, data1) + key3 = _make_key(category, True, data2) + + # Uniqueness across data + assert key1 != key3 + + # Check determinism: if the timestamp parts are the same, the keys should be identical + ts1 = key1.split("::")[1].split(":")[0] + ts2 = key2.split("::")[1].split(":")[0] + if ts1 == ts2: + assert key1 == key2 + else: + # If timestamp is different, keys should be different + assert key1 != key2 + + +def test_memory_value_happy_path(): + """Test _memory_value with standard data and tags.""" + result = _memory_value("some data", ["tag1", "tag2"]) + parsed = json.loads(result) + assert parsed == {"data": "some data", "tags": ["tag1", "tag2"]} + + +def test_memory_value_missing_tags(): + """Test _memory_value when tags is None.""" + result = _memory_value("some data", None) + parsed = json.loads(result) + assert parsed == {"data": "some data", "tags": []} + + +def test_memory_value_unicode(): + """Test _memory_value properly handles unicode and ensure_ascii=False.""" + result = _memory_value("こんにちは", ["世界"]) + # If ensure_ascii=False, the unicode characters shouldn't be escaped (no \uXXXX) + assert "こんにちは" in result + assert "世界" in result + parsed = json.loads(result) + assert parsed == {"data": "こんにちは", "tags": ["世界"]} + + +def test_parse_memory_value_success(): + """Test _parse_memory_value successfully decodes valid JSON.""" + raw = '{"data": "info", "tags": ["a"]}' + result = _parse_memory_value(raw) + assert result == {"data": "info", "tags": ["a"]} + + +def test_parse_memory_value_invalid_json(): + """Test _parse_memory_value with invalid JSON.""" + result = _parse_memory_value("{invalid_json:") + assert result == {"data": "{invalid_json:", "tags": []} + + +def test_parse_memory_value_type_error(): + """Test _parse_memory_value with TypeError (e.g. passing None).""" + result = _parse_memory_value(None) + assert result == {"data": None, "tags": []} + + +def test_parse_memory_value_invalid_json_string(): + """Test _parse_memory_value with invalid JSON string.""" + result = _parse_memory_value("this is not a valid json string") + assert result == {"data": "this is not a valid json string", "tags": []} + + +# ===================================================================== +# Tests from test_memory_mcp.py (root) +# ===================================================================== def test_memory_entry_happy_path(): """Test correctly formatted and complete memory entry.""" @@ -28,6 +183,7 @@ def test_memory_entry_happy_path(): assert result["timestamp"] == "1689201948123" assert result["memory_id"] == "test_id_123" + def test_memory_entry_invalid_key(): """Test with a key that does not start with 'memory:'.""" lmem = { @@ -38,6 +194,7 @@ def test_memory_entry_invalid_key(): result = _memory_entry(lmem) assert result is None + def test_memory_entry_malformed_json_value(): """Test with malformed/string value where JSON parsing fails.""" valid_key = "memory:local:notes::1689201948123:a1b2c3d4e5f6" @@ -55,6 +212,7 @@ def test_memory_entry_malformed_json_value(): assert result["category"] == "notes" assert result["scope"] == "local" + def test_memory_entry_missing_fields(): """Test gracefully handling dictionaries with missing keys.""" # Missing 'value' and 'memory_id' @@ -78,90 +236,78 @@ def test_memory_entry_missing_fields(): result3 = _memory_entry({}) assert result3 is None -def test_parse_key_happy_path(): - """Test full standard key structure""" - key = "memory:local:code::20240101T120000Z:abc123hash" - result = _parse_key(key) - assert result == { - "scope": "local", - "category": "code", - "timestamp": "20240101T120000Z" - } - -def test_parse_key_missing_timestamp_hash(): - """Test key without the :: delimiter section""" - key = "memory:global:general" - result = _parse_key(key) - assert result == { - "scope": "global", - "category": "general", - "timestamp": "" - } -def test_parse_key_missing_category(): - """Test key with missing category""" - key = "memory:local::20240101T120000Z:abc123hash" +@pytest.mark.parametrize( + "key, expected", + [ + ( + "memory:local:code::20240101T120000Z:abc123hash", + {"scope": "local", "category": "code", "timestamp": "20240101T120000Z"}, + ), + ( + "memory:global:general", + {"scope": "global", "category": "general", "timestamp": ""}, + ), + ( + "memory:local::20240101T120000Z:abc123hash", + {"scope": "local", "category": "", "timestamp": "20240101T120000Z"}, + ), + ( + "memory", + {"scope": "", "category": "", "timestamp": ""}, + ), + ( + "", + {"scope": "", "category": "", "timestamp": ""}, + ), + ( + None, + {"scope": "", "category": "", "timestamp": ""}, + ), + ( + "memory:global:category:with:colons::20240101T120000Z:abc123hash", + {"scope": "global", "category": "category", "timestamp": "20240101T120000Z"}, + ), + ( + "memory:global:general::20240101T120000Z", + {"scope": "global", "category": "general", "timestamp": "20240101T120000Z"}, + ), + ], + ids=[ + "happy_path", + "missing_timestamp_hash", + "missing_category", + "missing_scope_and_category", + "empty_string", + "invalid_type", + "extra_colons_in_category", + "missing_hash_but_has_timestamp", + ] +) +def test_parse_key(key, expected): + """Test _parse_key with various valid and invalid formats.""" result = _parse_key(key) - # The split(":") on "memory:local" results in ["memory", "local"] length 2 - # So category should be "" - assert result == { - "scope": "local", - "category": "", - "timestamp": "20240101T120000Z" - } - -def test_parse_key_missing_scope_and_category(): - """Test minimal key prefix""" - key = "memory" - result = _parse_key(key) - assert result == { - "scope": "", - "category": "", - "timestamp": "" - } - -def test_parse_key_empty_string(): - """Test completely empty string""" - key = "" - result = _parse_key(key) - assert result == { - "scope": "", - "category": "", - "timestamp": "" - } - -def test_parse_key_invalid_type(): - """Test handling of an invalid type that triggers the exception branch""" - key = None - result = _parse_key(key) - assert result == { - "scope": "", - "category": "", - "timestamp": "" - } + assert result == expected def test_parse_memory_value_valid_json(): raw_data = json.dumps({"data": "some data", "tags": ["tag1", "tag2"]}) result = _parse_memory_value(raw_data) assert result == {"data": "some data", "tags": ["tag1", "tag2"]} + def test_parse_memory_value_invalid_json(): raw_data = "this is not json" result = _parse_memory_value(raw_data) assert result == {"data": "this is not json", "tags": []} + def test_parse_memory_value_type_error(): - # json.loads will raise TypeError if given something that isn't str, bytes, or bytearray raw_data = 12345 result = _parse_memory_value(raw_data) # type: ignore[arg-type] assert result == {"data": 12345, "tags": []} + def test_parse_memory_value_non_dict_json(): - # If the input is valid JSON but not a dictionary, it currently returns the parsed non-dict value, - # which violates the dict return type annotation and can cause downstream KeyErrors/TypeErrors. raw_data = '"just a string"' result = _parse_memory_value(raw_data) assert result == "just a string" - -if __name__ == "__main__": - sys.exit(pytest.main(["-v", __file__])) From 36fa94a0fde0d19f831c6f353385bd331449c6c1 Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Wed, 1 Jul 2026 23:44:18 +0200 Subject: [PATCH 07/12] chore: address review feedback, restore async agy log reading and classifier thread pool optimization --- debug-homepage.png | Bin 0 -> 310637 bytes router/agy_proxy.py | 15 +++--- router/tests/test_agy_proxy.py | 41 ++++++++------- router/tests/test_detect_active_tool.py | 2 +- scripts/benchmark_classifier.py | 65 ++++++++++++++++-------- scripts/get_pr_status.py | 2 +- start-stack.sh | 4 +- tests/test_get_pr_status.py | 17 +++++++ 8 files changed, 97 insertions(+), 49 deletions(-) create mode 100644 debug-homepage.png diff --git a/debug-homepage.png b/debug-homepage.png new file mode 100644 index 0000000000000000000000000000000000000000..8a45fdc26b25534298e44d04c12f99426641139b GIT binary patch literal 310637 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

=%ml#{3p1^?xfI^V|ke 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%0DXJI;kIu)V($>wZ9yjYpj!noMuZWE4 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 bool: +async def _is_quota_exhausted(returncode: int, stdout: str, stderr: str) -> bool: """ Detect quota exhaustion from agy subprocess results. @@ -152,8 +153,9 @@ def _is_quota_exhausted(returncode: int, stdout: str, stderr: str) -> bool: log_path = os.path.expanduser("~/.gemini/antigravity-cli/cli.log") try: if os.path.exists(log_path): - with open(log_path, "r") as f: - for line in f.readlines()[-5:]: + async with aiofiles.open(log_path, "r") as f: + lines = await f.readlines() + for line in lines[-5:]: if "RESOURCE_EXHAUSTED" in line or "code 429" in line: return True except Exception: @@ -346,8 +348,9 @@ async def try_agy_proxy(prompt: str, messages: list = None, rc = 0 if raw_rc is None else raw_rc raw_stderr = first_data.get("stderr", "") stderr_content = "" if raw_stderr is None else raw_stderr - if _is_quota_exhausted(rc, "", stderr_content) or rc != 0: - if _is_quota_exhausted(rc, "", stderr_content): + is_exhausted = await _is_quota_exhausted(rc, "", stderr_content) + if is_exhausted or rc != 0: + if is_exhausted: tier_breaker.record_failure() if cooldown_persistence is not None: try: @@ -420,7 +423,7 @@ async def token_generator(stream_resp, httpx_client, initial_line, current_conv_ last_conv_id = result_conv_id # Check for quota exhaustion - if _is_quota_exhausted(returncode, stdout, stderr): + if await _is_quota_exhausted(returncode, stdout, stderr): tier_breaker.record_failure() if cooldown_persistence is not None: try: diff --git a/router/tests/test_agy_proxy.py b/router/tests/test_agy_proxy.py index 404059eb..f4cd540d 100644 --- a/router/tests/test_agy_proxy.py +++ b/router/tests/test_agy_proxy.py @@ -1,4 +1,5 @@ -from unittest.mock import patch, MagicMock +import pytest +from unittest.mock import patch, MagicMock, AsyncMock from router.agy_proxy import _wrap_response, _is_quota_exhausted def test_wrap_response_basic(): @@ -58,45 +59,51 @@ def test_wrap_response_long_strings(): assert result["usage"]["completion_tokens"] == 250 assert result["usage"]["total_tokens"] == 375 -def test_is_quota_exhausted_stderr_markers(): +@pytest.mark.asyncio +async def test_is_quota_exhausted_stderr_markers(): markers = ["RESOURCE_EXHAUSTED", "code 429", "quota reached", "rate limit"] for marker in markers: - assert _is_quota_exhausted(0, "", marker) is True - assert _is_quota_exhausted(1, "", f"Error: {marker}") is True + assert await _is_quota_exhausted(0, "", marker) is True + assert await _is_quota_exhausted(1, "", f"Error: {marker}") is True -def test_is_quota_exhausted_success(): - assert _is_quota_exhausted(0, "some valid response", "") is False +@pytest.mark.asyncio +async def test_is_quota_exhausted_success(): + assert await _is_quota_exhausted(0, "some valid response", "") is False -def test_is_quota_exhausted_other_error(): - assert _is_quota_exhausted(1, "", "some other random error") is False +@pytest.mark.asyncio +async def test_is_quota_exhausted_other_error(): + assert await _is_quota_exhausted(1, "", "some other random error") is False @patch("router.agy_proxy.os.path.exists") -@patch("builtins.open") +@patch("aiofiles.open") @patch("router.agy_proxy.time.time") -def test_is_quota_exhausted_empty_reads_log(mock_time, mock_open, mock_exists): +@pytest.mark.asyncio +async def test_is_quota_exhausted_empty_reads_log(mock_time, mock_open, mock_exists): mock_time.return_value = 1000.0 mock_exists.return_value = True - mock_file = MagicMock() + mock_file = AsyncMock() mock_file.readlines.return_value = ["line 1\n", "RESOURCE_EXHAUSTED info\n", "line 3\n"] - mock_open.return_value.__enter__.return_value = mock_file + mock_open.return_value.__aenter__.return_value = mock_file with patch("router.agy_proxy._last_log_check", 0): - assert _is_quota_exhausted(0, "", "") is True + assert await _is_quota_exhausted(0, "", "") is True @patch("router.agy_proxy.time.time") -def test_is_quota_exhausted_empty_throttled(mock_time): +@pytest.mark.asyncio +async def test_is_quota_exhausted_empty_throttled(mock_time): # Set time diff to be < 2.0 mock_time.return_value = 1001.0 with patch("router.agy_proxy._last_log_check", 1000.0): # Even without reading log, falls back to True - assert _is_quota_exhausted(0, "", "") is True + assert await _is_quota_exhausted(0, "", "") is True @patch("router.agy_proxy.os.path.exists") @patch("router.agy_proxy.time.time") -def test_is_quota_exhausted_empty_no_log_fallback(mock_time, mock_exists): +@pytest.mark.asyncio +async def test_is_quota_exhausted_empty_no_log_fallback(mock_time, mock_exists): mock_time.return_value = 1000.0 mock_exists.return_value = False with patch("router.agy_proxy._last_log_check", 0): - assert _is_quota_exhausted(0, "", "") is True + assert await _is_quota_exhausted(0, "", "") is True diff --git a/router/tests/test_detect_active_tool.py b/router/tests/test_detect_active_tool.py index 3105ab1e..c5b359d1 100644 --- a/router/tests/test_detect_active_tool.py +++ b/router/tests/test_detect_active_tool.py @@ -9,7 +9,7 @@ # Add the parent directory to the path so we can import from router sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) -from router.main import detect_active_tool +from main import detect_active_tool def test_detect_active_tool_empty(): assert detect_active_tool({}) == "none" diff --git a/scripts/benchmark_classifier.py b/scripts/benchmark_classifier.py index cb1f5a4a..9ff795b4 100644 --- a/scripts/benchmark_classifier.py +++ b/scripts/benchmark_classifier.py @@ -54,9 +54,11 @@ def classify(prompt): per_tier = {t: {"correct": 0, "total": 0} for t in TIERS} confusion = defaultdict(Counter) # confusion[expected][predicted] -for i, item in enumerate(dataset.get("prompts", [])): +import concurrent.futures +import threading + +def process_item(item): prompt = item["prompt"] - # Support both old schema ("tier") and new schema ("llm_tier" / "clf_tier") expected = item.get("tier") or item.get("llm_tier") or item.get("clf_tier", "") try: @@ -64,31 +66,50 @@ def classify(prompt): except Exception as e: predicted = f"ERROR: {str(e)[:50]}" - results.append({ - "prompt": prompt[:100], - "expected": expected, - "predicted": predicted, - }) + return expected, predicted + +results_list = [None] * total - # Only score against known tiers — skip ERROR/unknown labels gracefully - if expected not in per_tier: - confusion[expected][predicted] += 1 - continue +with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor: + rate_limit_lock = threading.Lock() + + def process_item_with_rate_limit(index_and_item): + i, item = index_and_item + with rate_limit_lock: + time.sleep(0.05) - per_tier[expected]["total"] += 1 - if predicted == expected: - correct += 1 - per_tier[expected]["correct"] += 1 + expected, predicted = process_item(item) + return i, item, expected, predicted - confusion[expected][predicted] += 1 + futures = [executor.submit(process_item_with_rate_limit, (i, item)) for i, item in enumerate(dataset.get("prompts", []))] - # Progress - if (i + 1) % 20 == 0: - scored_so_far = sum(t["total"] for t in per_tier.values()) - acc = (correct / scored_so_far * 100) if scored_so_far > 0 else 0.0 - print(f" {i+1}/{total} — accuracy {acc:.1f}%") + completed_count = 0 + for future in concurrent.futures.as_completed(futures): + i, item, expected, predicted = future.result() + + results_list[i] = { + "prompt": item["prompt"][:100], + "expected": expected, + "predicted": predicted, + } + + if expected not in per_tier: + confusion[expected][predicted] += 1 + else: + per_tier[expected]["total"] += 1 + if predicted == expected: + correct += 1 + per_tier[expected]["correct"] += 1 + confusion[expected][predicted] += 1 + + completed_count += 1 + + if completed_count % 20 == 0: + scored_so_far = sum(t["total"] for t in per_tier.values()) + acc = (correct / scored_so_far * 100) if scored_so_far > 0 else 0.0 + print(f" {completed_count}/{total} — accuracy {acc:.1f}%") - time.sleep(0.05) # minimal rate-limit (model handles concurrency via llama-server slots) +results = [r for r in results_list if r is not None] # Report scored_total = sum(t["total"] for t in per_tier.values()) diff --git a/scripts/get_pr_status.py b/scripts/get_pr_status.py index d65f65f1..c64bac43 100644 --- a/scripts/get_pr_status.py +++ b/scripts/get_pr_status.py @@ -24,7 +24,7 @@ def get_pr_status(pr_id: str = "") -> None: state = data.get("state") review = data.get("reviewDecision") or "NONE" - checks = data.get("statusCheckRollup", []) + checks = data.get("statusCheckRollup") or [] # Summarize checks success_count = 0 diff --git a/start-stack.sh b/start-stack.sh index 03bb1220..bfd17edf 100755 --- a/start-stack.sh +++ b/start-stack.sh @@ -95,7 +95,7 @@ else echo "⚠️ Warning: Host agy daemon not responding on port 5005" fi -if [ -z "$POSTGRES_PASSWORD" ] || [ -z "$NEXTAUTH_SECRET" ] || [ -z "$SALT" ] || [ -z "$ENCRYPTION_KEY" ] || [ -z "$LITELLM_MASTER_KEY" ] || [ -z "$ROUTER_API_KEY" ] || [ -z "$MINIO_ROOT_USER" ] || [ -z "$MINIO_ROOT_PASSWORD" ]; then +if [ -z "$POSTGRES_PASSWORD" ] || [ -z "$NEXTAUTH_SECRET" ] || [ -z "$SALT" ] || [ -z "$ENCRYPTION_KEY" ] || [ -z "$LITELLM_MASTER_KEY" ] || [ -z "$ROUTER_API_KEY" ] || [ -z "$MINIO_ROOT_USER" ] || [ -z "$MINIO_ROOT_PASSWORD" ] || [ -z "$LANGFUSE_INIT_USER_PASSWORD" ] || [ -z "$REDIS_AUTH" ] || [ -z "$CLICKHOUSE_PASSWORD" ]; then if ! command -v openssl &>/dev/null; then echo "❌ Error: 'openssl' is required to generate secure random keys but was not found in PATH." exit 1 @@ -398,7 +398,7 @@ placeholders = [ "ENCRYPTION_KEY_PLACEHOLDER", "postgres-password-***", "MINIO_USER_PLACEHOLDER", - "MINIO_PASSWORD_PLACEHOLDER" + "MINIO_PASSWORD_PLACEHOLDER", "LANGFUSE_INIT_USER_PASSWORD_PLACEHOLDER" ] for ph in placeholders: diff --git a/tests/test_get_pr_status.py b/tests/test_get_pr_status.py index 93885a14..f5fcbf55 100644 --- a/tests/test_get_pr_status.py +++ b/tests/test_get_pr_status.py @@ -82,3 +82,20 @@ def test_get_pr_status_invalid_json(mock_run_cmd, capsys): assert e.value.code == 1 captured = capsys.readouterr() assert "Error: Failed to parse gh CLI output" in captured.err + + +@patch("scripts.get_pr_status.run_cmd") +def test_get_pr_status_null_checks(mock_run_cmd, capsys): + mock_data = { + "state": "OPEN", + "reviewDecision": "REVIEW_REQUIRED", + "statusCheckRollup": None + } + mock_run_cmd.return_value = json.dumps(mock_data) + + get_pr_status("123") + + captured = capsys.readouterr() + assert "PR Status: OPEN" in captured.out + assert "Review Decision: REVIEW_REQUIRED" in captured.out + assert "Checks: 0/0 passed" in captured.out From 6cdf604443cccac6376f12eba80070ef7cb3d763 Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Wed, 1 Jul 2026 23:54:42 +0200 Subject: [PATCH 08/12] chore: restore clean secret placeholders in pod.yaml/start-stack.sh and Prisma serialization monkey-patch --- litellm/entrypoint.py | 20 +++++++++++ pod.yaml | 34 +++++++++---------- start-stack.sh | 77 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 105 insertions(+), 26 deletions(-) diff --git a/litellm/entrypoint.py b/litellm/entrypoint.py index 1b987365..20d4baf0 100644 --- a/litellm/entrypoint.py +++ b/litellm/entrypoint.py @@ -98,6 +98,26 @@ def strptime(cls, date_str: str, fmt: str) -> original_datetime: datetime.datetime = RobustDatetime sys.stdout.flush() +# Register both RobustDatetime AND the original datetime with Prisma's +# singledispatch serializer. When entrypoint.py replaces datetime.datetime +# with RobustDatetime before Prisma loads, Prisma's own +# @serializer.register(datetime.datetime) ends up registering RobustDatetime. +# But database drivers (psycopg2) return the *original* C-level datetime +# instances, which no longer match. We must register both classes. +try: + from prisma.builder import serializer + def _serialize_dt(dt): + """Serialize datetime to ISO8601 with timezone (UTC if naive).""" + if dt.tzinfo is None: + dt = dt.replace(tzinfo=timezone.utc) + return dt.isoformat() + serializer.register(original_datetime, _serialize_dt) + serializer.register(RobustDatetime, _serialize_dt) + print("🩹 Registered original_datetime + RobustDatetime with Prisma serializer") +except Exception: + pass +sys.stdout.flush() + # Start LiteLLM Proxy import litellm from litellm.proxy.proxy_cli import run_server diff --git a/pod.yaml b/pod.yaml index 28a5b572..b8ed35b8 100644 --- a/pod.yaml +++ b/pod.yaml @@ -4,7 +4,7 @@ metadata: name: agent-router-pod spec: containers: - # Valkey Cache 9.1.0-alpine — LiteLLM response cache (exact-match & semantic) + # Valkey Cache — LiteLLM response cache (exact-match & semantic) - command: - valkey-server - --protected-mode @@ -34,7 +34,7 @@ spec: - /app/entrypoint.py env: - name: DATABASE_URL - value: postgresql://postgres:***@127.0.0.1:5432/postgres + value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:5432/postgres - name: STORE_MODEL_IN_DB value: 'True' - name: LITELLM_LOG @@ -42,9 +42,9 @@ spec: - name: LANGFUSE_HOST value: http://127.0.0.1:3001 - name: LITELLM_MASTER_KEY - value: sk-lit...33bf + value: LITELLM_MASTER_KEY_PLACEHOLDER - name: OLLAMA_API_KEY - value: 3cd542f8fca14fd08bedfd4f2ab36f9f.6G7Iukbvu1Keyi9x8eKckNEO + value: OLLAMA_API_KEY_PLACEHOLDER image: ghcr.io/berriai/litellm:v1.90.2 livenessProbe: exec: @@ -89,19 +89,19 @@ spec: - name: LITELLM_CONFIG_PATH value: /config/litellm_dir/config.yaml - name: DATABASE_URL - value: postgresql://postgres:***@127.0.0.1:5432/postgres + value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:5432/postgres - name: DBUS_SESSION_BUS_ADDRESS value: unix:path=/run/user/1000/bus - name: LITELLM_MASTER_KEY - value: sk-lit...33bf + value: LITELLM_MASTER_KEY_PLACEHOLDER - name: LANGFUSE_PUBLIC_KEY - value: pk-lf-200bbf48-1d23-447d-a79a-8614106497e6 + value: LANGFUSE_PUBLIC_KEY_PLACEHOLDER - name: LANGFUSE_SECRET_KEY - value: sk-lf-...3b49 + value: LANGFUSE_SECRET_KEY_PLACEHOLDER - name: LANGFUSE_HOST value: http://127.0.0.1:3001 - name: OLLAMA_API_KEY - value: 3cd542f8fca14fd08bedfd4f2ab36f9f.6G7Iukbvu1Keyi9x8eKckNEO + value: OLLAMA_API_KEY_PLACEHOLDER - name: LOG_LEVEL value: info image: localhost/llm-triage-router:latest @@ -154,10 +154,10 @@ spec: - name: POSTGRES_USER value: postgres - name: POSTGRES_PASSWORD - value: postgres-password-*** + value: POSTGRES_PASSWORD_RAW_PLACEHOLDER - name: POSTGRES_DB value: langfuse - image: docker.io/pgvector/pgvector:pg18 + image: docker.io/pgvector/pgvector:0.8.3-pg18 livenessProbe: exec: command: @@ -188,7 +188,7 @@ spec: value: clickhouse - name: CLICKHOUSE_PASSWORD value: clickhouse - image: docker.io/clickhouse/clickhouse-server:26.5.1 + image: docker.io/clickhouse/clickhouse-server:26.6.1.1193 livenessProbe: exec: command: @@ -253,7 +253,7 @@ spec: # Langfuse Web — observability dashboard - env: - name: DATABASE_URL - value: postgresql://postgres:***@127.0.0.1:5432/langfuse + value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:5432/langfuse - name: NEXTAUTH_SECRET value: NEXTAUTH_SECRET_PLACEHOLDER - name: NEXTAUTH_URL @@ -310,7 +310,7 @@ spec: value: LANGFUSE_INIT_USER_PASSWORD_PLACEHOLDER - name: LANGFUSE_LOG_LEVEL value: warn - image: docker.io/langfuse/langfuse:3 + image: docker.io/langfuse/langfuse:3.202.1 livenessProbe: exec: command: @@ -337,7 +337,7 @@ spec: # Langfuse Worker — background job processor - env: - name: DATABASE_URL - value: postgresql://postgres:***@127.0.0.1:5432/langfuse + value: postgresql://postgres:POSTGRES_PASSWORD_ENCODED_PLACEHOLDER@127.0.0.1:5432/langfuse - name: CLICKHOUSE_URL value: http://127.0.0.1:8123 - name: CLICKHOUSE_USER @@ -372,7 +372,7 @@ spec: value: MINIO_PASSWORD_PLACEHOLDER - name: LANGFUSE_LOG_LEVEL value: warn - image: docker.io/langfuse/langfuse-worker:3 + image: docker.io/langfuse/langfuse-worker:3.202.1 livenessProbe: exec: command: @@ -396,7 +396,7 @@ spec: value: MINIO_USER_PLACEHOLDER - name: MINIO_ROOT_PASSWORD value: MINIO_PASSWORD_PLACEHOLDER - image: docker.io/minio/minio:latest + image: docker.io/minio/minio:RELEASE.2025-09-07T16-13-09Z livenessProbe: httpGet: path: /minio/health/live diff --git a/start-stack.sh b/start-stack.sh index bfd17edf..1f751823 100755 --- a/start-stack.sh +++ b/start-stack.sh @@ -95,7 +95,7 @@ else echo "⚠️ Warning: Host agy daemon not responding on port 5005" fi -if [ -z "$POSTGRES_PASSWORD" ] || [ -z "$NEXTAUTH_SECRET" ] || [ -z "$SALT" ] || [ -z "$ENCRYPTION_KEY" ] || [ -z "$LITELLM_MASTER_KEY" ] || [ -z "$ROUTER_API_KEY" ] || [ -z "$MINIO_ROOT_USER" ] || [ -z "$MINIO_ROOT_PASSWORD" ] || [ -z "$LANGFUSE_INIT_USER_PASSWORD" ] || [ -z "$REDIS_AUTH" ] || [ -z "$CLICKHOUSE_PASSWORD" ]; then +if [ -z "$POSTGRES_PASSWORD" ] || [ -z "$NEXTAUTH_SECRET" ] || [ -z "$SALT" ] || [ -z "$ENCRYPTION_KEY" ] || [ -z "$LITELLM_MASTER_KEY" ] || [ -z "$ROUTER_API_KEY" ] || [ -z "$MINIO_ROOT_USER" ] || [ -z "$MINIO_ROOT_PASSWORD" ] || [ -z "$LANGFUSE_INIT_USER_PASSWORD" ] || [ -z "$REDIS_AUTH" ] || [ -z "$CLICKHOUSE_PASSWORD" ] || [ -z "$LANGFUSE_PUBLIC_KEY" ] || [ -z "$LANGFUSE_SECRET_KEY" ]; then if ! command -v openssl &>/dev/null; then echo "❌ Error: 'openssl' is required to generate secure random keys but was not found in PATH." exit 1 @@ -106,6 +106,17 @@ fi touch "$ENV_FILE" chmod 600 "$ENV_FILE" +generate_uuid() { + local val + val=$(openssl rand -hex 16 2>/dev/null) + local status=$? + if [ $status -ne 0 ] || [ ${#val} -ne 32 ]; then + echo "❌ Error: Failed to generate secure random UUID (openssl rand returned exit status $status, length ${#val})." >&2 + return 1 + fi + echo "${val:0:8}-${val:8:4}-${val:12:4}-${val:16:4}-${val:20:12}" +} + if [ -z "$NEXTAUTH_SECRET" ]; then NEXTAUTH_SECRET="$(openssl rand -base64 32)" echo "NEXTAUTH_SECRET=\"$NEXTAUTH_SECRET\"" >> "$ENV_FILE" @@ -171,6 +182,48 @@ if [ -z "$MINIO_ROOT_PASSWORD" ]; then echo "✓ Generated new MINIO_ROOT_PASSWORD and saved to $ENV_FILE" fi +if [ -z "$LANGFUSE_PUBLIC_KEY" ]; then + uuid=$(generate_uuid) + if [ $? -ne 0 ] || [ -z "$uuid" ]; then + echo "❌ Error: Failed to generate LANGFUSE_PUBLIC_KEY." >&2 + exit 1 + fi + LANGFUSE_PUBLIC_KEY="pk-lf-$uuid" + echo "LANGFUSE_PUBLIC_KEY=\"$LANGFUSE_PUBLIC_KEY\"" >> "$ENV_FILE" + chmod 600 "$ENV_FILE" + echo "✓ Generated new LANGFUSE_PUBLIC_KEY and saved to $ENV_FILE" +fi + +if [ -z "$LANGFUSE_SECRET_KEY" ]; then + uuid=$(generate_uuid) + if [ $? -ne 0 ] || [ -z "$uuid" ]; then + echo "❌ Error: Failed to generate LANGFUSE_SECRET_KEY." >&2 + exit 1 + fi + LANGFUSE_SECRET_KEY="sk-lf-$uuid" + echo "LANGFUSE_SECRET_KEY=\"$LANGFUSE_SECRET_KEY\"" >> "$ENV_FILE" + chmod 600 "$ENV_FILE" + echo "✓ Generated new LANGFUSE_SECRET_KEY and saved to $ENV_FILE" +fi + +if [ -z "$OLLAMA_API_KEY" ]; then + if [ -t 0 ]; then + echo "🔑 OLLAMA_API_KEY not found." + echo -n "Please enter your Ollama API Key (input will be hidden): " + read -rs OLLAMA_API_KEY + echo "" + echo "OLLAMA_API_KEY=\"$OLLAMA_API_KEY\"" >> "$ENV_FILE" + chmod 600 "$ENV_FILE" + echo "✓ Ollama API key saved securely to $ENV_FILE" + else + echo "❌ Error: OLLAMA_API_KEY is not set in your environment or in $ENV_FILE." + echo "Please run this script interactively first, or create the file manually:" + echo " echo 'OLLAMA_API_KEY=your_key_here' >> $ENV_FILE" + echo " chmod 600 $ENV_FILE" + exit 1 + fi +fi + # DYNAMIC_LITELLM_MASTER_KEY_PLACEHOLDER in router config is resolved at runtime from env @@ -381,7 +434,7 @@ if podman pod exists agent-router-pod 2>/dev/null; then fi render_pod_yaml() { - export WORKDIR HOME LITELLM_MASTER_KEY POSTGRES_PASSWORD NEXTAUTH_SECRET SALT ENCRYPTION_KEY LANGFUSE_INIT_USER_PASSWORD MINIO_ROOT_USER MINIO_ROOT_PASSWORD + export WORKDIR HOME LITELLM_MASTER_KEY POSTGRES_PASSWORD NEXTAUTH_SECRET SALT ENCRYPTION_KEY LANGFUSE_INIT_USER_PASSWORD MINIO_ROOT_USER MINIO_ROOT_PASSWORD OLLAMA_API_KEY LANGFUSE_PUBLIC_KEY LANGFUSE_SECRET_KEY python3 - "$WORKDIR/pod.yaml" <<'PY' import os, sys, urllib.parse uid = os.getuid() @@ -391,12 +444,15 @@ placeholders = [ "/home/gpav/Vrac/LAB/AI/LLM-Routing", "/home/gpav/", "/run/user/1000", - "sk-lit...33bf", - "postgres:***", + "LITELLM_MASTER_KEY_PLACEHOLDER", + "POSTGRES_PASSWORD_RAW_PLACEHOLDER", + "POSTGRES_PASSWORD_ENCODED_PLACEHOLDER", "NEXTAUTH_SECRET_PLACEHOLDER", "SALT_PLACEHOLDER", "ENCRYPTION_KEY_PLACEHOLDER", - "postgres-password-***", + "OLLAMA_API_KEY_PLACEHOLDER", + "LANGFUSE_PUBLIC_KEY_PLACEHOLDER", + "LANGFUSE_SECRET_KEY_PLACEHOLDER", "MINIO_USER_PLACEHOLDER", "MINIO_PASSWORD_PLACEHOLDER", "LANGFUSE_INIT_USER_PASSWORD_PLACEHOLDER" @@ -408,14 +464,17 @@ for ph in placeholders: text = text.replace("/home/gpav/Vrac/LAB/AI/LLM-Routing", os.environ["WORKDIR"]) text = text.replace("/home/gpav/", os.environ["HOME"] + "/") text = text.replace("/run/user/1000", f"/run/user/{uid}") -text = text.replace("sk-lit...33bf", os.environ["LITELLM_MASTER_KEY"]) +text = text.replace("LITELLM_MASTER_KEY_PLACEHOLDER", os.environ["LITELLM_MASTER_KEY"]) +text = text.replace("POSTGRES_PASSWORD_RAW_PLACEHOLDER", os.environ["POSTGRES_PASSWORD"]) # URL-encode the postgres password for DSN insertion -encoded_password = urllib.parse.quote_plus(os.environ['POSTGRES_PASSWORD']) -text = text.replace("postgres:***", f"postgres:{encoded_password}") -text = text.replace("postgres-password-***", os.environ["POSTGRES_PASSWORD"]) +encoded_password = urllib.parse.quote(os.environ['POSTGRES_PASSWORD']) +text = text.replace("POSTGRES_PASSWORD_ENCODED_PLACEHOLDER", encoded_password) text = text.replace("NEXTAUTH_SECRET_PLACEHOLDER", os.environ["NEXTAUTH_SECRET"]) text = text.replace("SALT_PLACEHOLDER", os.environ["SALT"]) text = text.replace("ENCRYPTION_KEY_PLACEHOLDER", os.environ["ENCRYPTION_KEY"]) +text = text.replace("OLLAMA_API_KEY_PLACEHOLDER", os.environ["OLLAMA_API_KEY"]) +text = text.replace("LANGFUSE_PUBLIC_KEY_PLACEHOLDER", os.environ["LANGFUSE_PUBLIC_KEY"]) +text = text.replace("LANGFUSE_SECRET_KEY_PLACEHOLDER", os.environ["LANGFUSE_SECRET_KEY"]) text = text.replace("MINIO_USER_PLACEHOLDER", os.environ["MINIO_ROOT_USER"]) text = text.replace("MINIO_PASSWORD_PLACEHOLDER", os.environ["MINIO_ROOT_PASSWORD"]) text = text.replace("LANGFUSE_INIT_USER_PASSWORD_PLACEHOLDER", os.environ["LANGFUSE_INIT_USER_PASSWORD"]) From 660811f68f7aae8d096888a800b114bd0c40a2e5 Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Thu, 2 Jul 2026 09:32:33 +0200 Subject: [PATCH 09/12] chore: add branch audit plan and restore offload-aa-scores performance optimization --- .agents/branch_audit_plan.md | 56 ++++++++++++++++++++++++++ router/main.py | 5 ++- tests/test_compute_free_model_score.py | 4 ++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 .agents/branch_audit_plan.md diff --git a/.agents/branch_audit_plan.md b/.agents/branch_audit_plan.md new file mode 100644 index 00000000..f1a9374c --- /dev/null +++ b/.agents/branch_audit_plan.md @@ -0,0 +1,56 @@ +# Git Merges & Regressions Audit Report + +## Problem Overview +During the merging of concurrent pull requests, automated conflict-resolution bots (`jules[bot]`) silently discarded or reverted several code blocks and logic optimizations. + +To ensure complete stability, we performed a systematic, automated three-dot diffing audit (`git diff CURRENT_BRANCH...TARGET_BRANCH`) comparing our current workspace against every active and merged remote branch in the repository. + +--- + +## Branch-by-Branch Audit Checklist + +| Branch Name / PR | Status | Notes / Discrepancies Checked | +| :--- | :---: | :--- | +| `origin/cleanup/remove-unused-get-live-gemini-oauth-token` (PR #195) | **CLEAN** | All changes present in current codebase. | +| `origin/perf-optimize-gemini-oauth-token-7488735575783948165` (PR #158) | **CLEAN** | All changes present in current codebase. | +| `origin/refactor-record-tool-usage-17779903941173107649` (PR #157) | **CLEAN** | All changes present in current codebase. | +| `origin/chore/get-pr-status-tests-18330387033569416831` (PR #193) | **CLEAN** | All changes present in current codebase. | +| `origin/chore/perf-async-annotations-4499495305587811104` (PR #172) | **CLEAN** | All changes present in current codebase. | +| `origin/chore/add-gemini-oauth-tests-17524029845400706758` (PR #163) | **CLEAN** | All changes present in current codebase. | +| `origin/dependabot/docker/berriai/litellm-v1.90.2` (PR #192) | **CLEAN** | Diff showed `v1.90.2` LiteLLM image version bump, which is already applied. | +| `origin/security/fix-memory-mcp-category-injection-14795006529015952965` (PR #173) | **CLEAN** | All changes present in current codebase. | +| `origin/test/add-read-annotations-sync-tests-12043640228306609857` (PR #168) | **CLEAN** | All changes present in current codebase. | +| `origin/chore/test-parse-key-parameterized-14651890987031951450` (PR #169) | **CLEAN** | All changes present in current codebase. | +| `origin/perf/async-quota-exhausted-4722057800691922723` (PR #156) | **CLEAN** | All changes present in current codebase. | +| `origin/perf-benchmark-classifier-14678555128983342452` (PR #155) | **CLEAN** | All changes present in current codebase. | +| `origin/chore/add-test-redis-from-url-12746122485451637611` (PR #174) | **CLEAN** | All changes present in current codebase. | +| `origin/chore/test-is-memory-key-14668590644102848561` (PR #164) | **CLEAN** | All changes present in current codebase. | +| `origin/⚡/optimize-agy-log-read-1519383298987985129` (PR #170) | **CLEAN** | All changes present in current codebase. | +| `origin/chore/add-oauth-status-tests-15591368961301252072` (PR #166) | **CLEAN** | All changes present in current codebase. | +| `origin/chore/test-get-goose-sessions-16558526271462662412` (PR #165) | **CLEAN** | All changes present in current codebase. | +| `origin/fix-http-client-proliferation-11317864999360875839` | **CLEAN** | HTTP client unification is fully present in our workspace. | +| `origin/fix/test-record-tool-usage-3580129709200353766` | **CLEAN** | Root-level test files were reorganized to `/tests`, fully preserved. | +| `origin/fix/secrets-relocation` (PR #184) | **CLEAN** | Checked out placeholders and updated `start-stack.sh`/`pod.yaml` securely. | +| `origin/perf/offload-aa-scores-sync-16551127323385849872` (PR #98) | **RESTORED** | **Regression Found**: The asynchronous scores loading optimization was lost on master. Re-implemented and verified. | + +--- + +## Detailed Regression Analysis & Fix: Offload AA Scores Loading + +### The Regression +* **File:** `router/main.py` +* **Issue:** `_load_aa_scores()` (which does a blocking synchronous JSON disk read of `aa_scores.json`) was called directly inside `compute_free_model_score()`. When resolving or syncing OpenRouter free models, this synchronous file read was executed sequentially in a loop, blocking the main event loop. +* **Merged Fix Lost:** The merged PR #98 had offloaded this operation to a background thread pool using `await asyncio.to_thread(_load_aa_scores)` outside the loops in `sync_adaptive_router_roster` and `get_best_free_model`, but this change was completely discarded during automated conflict resolution. + +### The Resolution +1. **`router/main.py`**: + * Restored `await asyncio.to_thread(_load_aa_scores)` inside `sync_adaptive_router_roster()` and `get_best_free_model()` if the cache is not yet loaded. + * Removed the blocking `_load_aa_scores()` call from inside `compute_free_model_score()`. +2. **`tests/test_compute_free_model_score.py`**: + * Updated the test cases to explicitly call `router_main._load_aa_scores()` within the test setups to align with the asynchronous offloading. + +--- + +## Verification Status +* **Test Suite:** Ran `PYTHONPATH=router:. pytest` +* **Result:** **176 tests passed** successfully (100% success rate). diff --git a/router/main.py b/router/main.py index 9e379255..1f13d37a 100644 --- a/router/main.py +++ b/router/main.py @@ -530,6 +530,8 @@ async def sync_adaptive_router_roster(master_key: str): except Exception as e: logger.warning(f"Failed to fetch OpenRouter models: {e}") return + if not _AA_SCORES_LOADED: + await asyncio.to_thread(_load_aa_scores) free_models = [] model_contexts = {} model_supported_params = {} @@ -1450,7 +1452,6 @@ def _load_aa_scores(): def compute_free_model_score(m: dict) -> float: """Return AA agentic index score, or a low default for unknown models.""" - _load_aa_scores() mid = m.get("id", "") return _AA_SCORES_CACHE.get(mid, 25.0) @@ -1486,6 +1487,8 @@ async def _save_best_model_to_disk(best_model: dict) -> None: async def get_best_free_model() -> dict: """Fetches currently free models from OpenRouter, matches against agentic scores, and returns the highest.""" global free_model_cache + if not _AA_SCORES_LOADED: + await asyncio.to_thread(_load_aa_scores) now = time.time() # Check if cache is still valid diff --git a/tests/test_compute_free_model_score.py b/tests/test_compute_free_model_score.py index 2fab732c..1ea59751 100644 --- a/tests/test_compute_free_model_score.py +++ b/tests/test_compute_free_model_score.py @@ -18,6 +18,7 @@ def test_compute_free_model_score_known_model(): """Test when the model id exists in the cache.""" mock_data = json.dumps({"scores": {"model-a": 85.5}}) with patch("builtins.open", mock_open(read_data=mock_data)): + router_main._load_aa_scores() score = compute_free_model_score({"id": "model-a"}) assert score == 85.5 @@ -25,6 +26,7 @@ def test_compute_free_model_score_unknown_model(): """Test when the model id is not in the cache.""" mock_data = json.dumps({"scores": {"model-a": 85.5}}) with patch("builtins.open", mock_open(read_data=mock_data)): + router_main._load_aa_scores() score = compute_free_model_score({"id": "model-b"}) assert score == 25.0 @@ -32,12 +34,14 @@ def test_compute_free_model_score_missing_id(): """Test when the model dictionary is missing an 'id'.""" mock_data = json.dumps({"scores": {"model-a": 85.5}}) with patch("builtins.open", mock_open(read_data=mock_data)): + router_main._load_aa_scores() score = compute_free_model_score({"name": "just a name"}) assert score == 25.0 def test_compute_free_model_score_file_not_found(): """Test fallback when the aa_scores.json file is missing or fails to load.""" with patch("builtins.open", side_effect=FileNotFoundError): + router_main._load_aa_scores() score = compute_free_model_score({"id": "model-a"}) assert score == 25.0 assert router_main._AA_SCORES_LOADED is True From ad447547c919b179d4a5b364f94b013902e33a01 Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Thu, 2 Jul 2026 09:39:19 +0200 Subject: [PATCH 10/12] chore: address CodeRabbit review feedback on PR #198 --- router/main.py | 1 + router/memory_mcp.py | 14 ++++++--- router/tests/test_get_redis.py | 3 +- router/tests/test_load_persisted_stats.py | 3 ++ router/tests/test_memory_mcp.py | 37 +++++++++++++++++------ scripts/benchmark_classifier.py | 2 +- scripts/benchmark_tokens.py | 5 +-- 7 files changed, 47 insertions(+), 18 deletions(-) diff --git a/router/main.py b/router/main.py index 1f13d37a..036cfee2 100644 --- a/router/main.py +++ b/router/main.py @@ -3965,6 +3965,7 @@ async def save_annotations(payload: AnnotationPayload): else: existing[k] = item.model_dump() await _atomic_write_json_async(str(ann_path), existing) + _annotations_cache.pop(str(ann_path), None) return JSONResponse({"status": "ok", "saved": len(data)}) except Exception as e: diff --git a/router/memory_mcp.py b/router/memory_mcp.py index 7ec87c26..326ad66a 100755 --- a/router/memory_mcp.py +++ b/router/memory_mcp.py @@ -45,17 +45,21 @@ def _make_key(category: str, is_global: bool, data: str) -> str: # BLAKE2b: SOTA crypto hash, stdlib, faster than MD5, deterministic across restarts. # Provides uniqueness within the same millisecond. h = hashlib.blake2b((data + str(ts)).encode("utf-8"), digest_size=HASH_DIGEST_SIZE).hexdigest() - safe_category = urllib.parse.quote(category) - return f"{PREFIX}:{scope}:{safe_category}::{ts}:{h}" + safe_category = urllib.parse.quote(category, safe="") + return f"{PREFIX}:v2:{scope}:{safe_category}::{ts}:{h}" def _parse_key(key: str): """Parse a structured key back into (scope, category, timestamp, hash).""" try: parts = key.split("::") - prefix = parts[0].split(":") # memory:{scope}:{category} - scope = prefix[1] if len(prefix) > 1 else "" - category = urllib.parse.unquote(prefix[2]) if len(prefix) > 2 else "" + prefix = parts[0].split(":") # memory:{scope}:{category} or memory:v2:{scope}:{category} + if len(prefix) > 1 and prefix[1] == "v2": + scope = prefix[2] if len(prefix) > 2 else "" + category = urllib.parse.unquote(prefix[3]) if len(prefix) > 3 else "" + else: + scope = prefix[1] if len(prefix) > 1 else "" + category = prefix[2] if len(prefix) > 2 else "" ts_hash = parts[1] if len(parts) > 1 else "" ts = ts_hash.split(":")[0] if ts_hash else "" return {"scope": scope, "category": category, "timestamp": ts} diff --git a/router/tests/test_get_redis.py b/router/tests/test_get_redis.py index 0fdeaed2..10070ed5 100644 --- a/router/tests/test_get_redis.py +++ b/router/tests/test_get_redis.py @@ -7,8 +7,9 @@ import router.main as main @pytest.fixture(autouse=True) -def reset_redis_globals(): +def reset_redis_globals(monkeypatch): """Reset the global variables before and after each test.""" + monkeypatch.delenv("VALKEY_URL", raising=False) original_client = main._redis_client original_last_attempt = main._redis_last_init_attempt diff --git a/router/tests/test_load_persisted_stats.py b/router/tests/test_load_persisted_stats.py index 76edbf51..ea0f9ad2 100644 --- a/router/tests/test_load_persisted_stats.py +++ b/router/tests/test_load_persisted_stats.py @@ -1,3 +1,6 @@ +import os +os.environ.setdefault("CONFIG_PATH", "/config/router_dir/config.yaml") + import json import pytest from unittest.mock import patch, mock_open diff --git a/router/tests/test_memory_mcp.py b/router/tests/test_memory_mcp.py index 8c93f1f6..f0e6a6b8 100644 --- a/router/tests/test_memory_mcp.py +++ b/router/tests/test_memory_mcp.py @@ -37,11 +37,11 @@ def test_make_key_global(): key = _make_key(category, True, data) after_ts = int(time.time() * 1000) - # Expected format: f"{PREFIX}:{scope}:{category}::{ts}:{h}" - assert key.startswith(f"{PREFIX}:{SCOPE_GLOBAL}:{category}::") + # Expected format: f"{PREFIX}:v2:{scope}:{category}::{ts}:{h}" + assert key.startswith(f"{PREFIX}:v2:{SCOPE_GLOBAL}:{category}::") # Extract timestamp and hash part - match = re.match(rf"^{PREFIX}:{SCOPE_GLOBAL}:{category}::(\d+):([a-f0-9]+)$", key) + match = re.match(rf"^{PREFIX}:v2:{SCOPE_GLOBAL}:{category}::(\d+):([a-f0-9]+)$", key) assert match is not None, f"Key {key} does not match expected format" ts = int(match.group(1)) @@ -60,9 +60,9 @@ def test_make_key_local(): key = _make_key(category, False, data) after_ts = int(time.time() * 1000) - assert key.startswith(f"{PREFIX}:{SCOPE_LOCAL}:{category}::") + assert key.startswith(f"{PREFIX}:v2:{SCOPE_LOCAL}:{category}::") - match = re.match(rf"^{PREFIX}:{SCOPE_LOCAL}:{category}::(\d+):([a-f0-9]+)$", key) + match = re.match(rf"^{PREFIX}:v2:{SCOPE_LOCAL}:{category}::(\d+):([a-f0-9]+)$", key) assert match is not None, f"Key {key} does not match expected format" ts = int(match.group(1)) @@ -79,10 +79,10 @@ def test_make_key_formatting_details(monkeypatch): # data="data", ts=1620000000123 -> blake2b("data1620000000123", digest_size=10) -> 5e5dad075ca7764bc51f key1 = _make_key("cat1", True, "data") - assert key1 == f"{PREFIX}:{SCOPE_GLOBAL}:cat1::1620000000123:5e5dad075ca7764bc51f" + assert key1 == f"{PREFIX}:v2:{SCOPE_GLOBAL}:cat1::1620000000123:5e5dad075ca7764bc51f" key2 = _make_key("cat2", False, "data") - assert key2 == f"{PREFIX}:{SCOPE_LOCAL}:cat2::1620000000123:5e5dad075ca7764bc51f" + assert key2 == f"{PREFIX}:v2:{SCOPE_LOCAL}:cat2::1620000000123:5e5dad075ca7764bc51f" def test_make_key_determinism_and_uniqueness(): @@ -272,6 +272,10 @@ def test_memory_entry_missing_fields(): "memory:global:general::20240101T120000Z", {"scope": "global", "category": "general", "timestamp": "20240101T120000Z"}, ), + ( + "memory:v2:local:proj%3Aalpha%2F100%25%20ready::20240101T120000Z:abc123hash", + {"scope": "local", "category": "proj:alpha/100% ready", "timestamp": "20240101T120000Z"}, + ), ], ids=[ "happy_path", @@ -282,6 +286,7 @@ def test_memory_entry_missing_fields(): "invalid_type", "extra_colons_in_category", "missing_hash_but_has_timestamp", + "v2_escaped_category", ] ) def test_parse_key(key, expected): @@ -295,13 +300,13 @@ def test_parse_memory_value_valid_json(): assert result == {"data": "some data", "tags": ["tag1", "tag2"]} -def test_parse_memory_value_invalid_json(): +def test_parse_memory_value_invalid_json_fallback(): raw_data = "this is not json" result = _parse_memory_value(raw_data) assert result == {"data": "this is not json", "tags": []} -def test_parse_memory_value_type_error(): +def test_parse_memory_value_type_error_fallback(): raw_data = 12345 result = _parse_memory_value(raw_data) # type: ignore[arg-type] assert result == {"data": 12345, "tags": []} @@ -311,3 +316,17 @@ def test_parse_memory_value_non_dict_json(): raw_data = '"just a string"' result = _parse_memory_value(raw_data) assert result == "just a string" + + +def test_make_key_and_parse_key_round_trip(): + """Verify that _make_key and _parse_key correctly quote and unquote complex categories.""" + category = "proj:alpha/100% ready" + key = _make_key(category, is_global=False, data="test-data") + + # Assert that the category in the key is URL-encoded + assert "proj%3Aalpha%2F100%25%20ready" in key + + # Assert that the parsed key returns the original unencoded category + parsed = _parse_key(key) + assert parsed["scope"] == "local" + assert parsed["category"] == category diff --git a/scripts/benchmark_classifier.py b/scripts/benchmark_classifier.py index 9ff795b4..8e5f0766 100644 --- a/scripts/benchmark_classifier.py +++ b/scripts/benchmark_classifier.py @@ -59,7 +59,7 @@ def classify(prompt): def process_item(item): prompt = item["prompt"] - expected = item.get("tier") or item.get("llm_tier") or item.get("clf_tier", "") + expected = item.get("tier") or item.get("clf_tier") or item.get("llm_tier", "") try: predicted = classify(prompt) diff --git a/scripts/benchmark_tokens.py b/scripts/benchmark_tokens.py index d701b4eb..1fe8da63 100644 --- a/scripts/benchmark_tokens.py +++ b/scripts/benchmark_tokens.py @@ -65,12 +65,13 @@ def calculate_factorial(n): print(f" --> FAILURE: {case['name']} error exceeds target threshold") all_passed = False - assert all_passed, "Token estimation accuracy benchmark failed" + if not all_passed: + raise ValueError("Token estimation accuracy benchmark failed") if __name__ == "__main__": try: verify_accuracy() sys.exit(0) - except AssertionError as e: + except ValueError as e: print(f"\nERROR: {e}") sys.exit(1) From b0a8605600e42eb1f89c04220755252ba235b840 Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Thu, 2 Jul 2026 10:09:09 +0200 Subject: [PATCH 11/12] perf: optimize async log checking in agy_proxy to seek and read 1KB --- router/agy_proxy.py | 18 ++++++++++++------ router/tests/test_agy_proxy.py | 14 +++++++------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/router/agy_proxy.py b/router/agy_proxy.py index 8b77ac18..4e911c42 100644 --- a/router/agy_proxy.py +++ b/router/agy_proxy.py @@ -152,12 +152,18 @@ async def _is_quota_exhausted(returncode: int, stdout: str, stderr: str) -> bool _last_log_check = now log_path = os.path.expanduser("~/.gemini/antigravity-cli/cli.log") try: - if os.path.exists(log_path): - async with aiofiles.open(log_path, "r") as f: - lines = await f.readlines() - for line in lines[-5:]: - if "RESOURCE_EXHAUSTED" in line or "code 429" in line: - return True + async with aiofiles.open(log_path, "rb") as f: + try: + await f.seek(0, 2) + file_size = await f.tell() + await f.seek(max(0, file_size - 1024)) + except OSError: + pass + content_bytes = await f.read() + content = content_bytes.decode("utf-8", errors="ignore") + for line in content.splitlines()[-5:]: + if "RESOURCE_EXHAUSTED" in line or "code 429" in line: + return True except Exception: pass # Empty stdout+stderr with rc=0 strongly suggests quota exhaustion diff --git a/router/tests/test_agy_proxy.py b/router/tests/test_agy_proxy.py index f4cd540d..8ca6ee3b 100644 --- a/router/tests/test_agy_proxy.py +++ b/router/tests/test_agy_proxy.py @@ -74,16 +74,16 @@ async def test_is_quota_exhausted_success(): async def test_is_quota_exhausted_other_error(): assert await _is_quota_exhausted(1, "", "some other random error") is False -@patch("router.agy_proxy.os.path.exists") @patch("aiofiles.open") @patch("router.agy_proxy.time.time") @pytest.mark.asyncio -async def test_is_quota_exhausted_empty_reads_log(mock_time, mock_open, mock_exists): +async def test_is_quota_exhausted_empty_reads_log(mock_time, mock_open): mock_time.return_value = 1000.0 - mock_exists.return_value = True mock_file = AsyncMock() - mock_file.readlines.return_value = ["line 1\n", "RESOURCE_EXHAUSTED info\n", "line 3\n"] + mock_file.seek = AsyncMock() + mock_file.tell = AsyncMock(return_value=100) + mock_file.read = AsyncMock(return_value=b"line 1\nRESOURCE_EXHAUSTED info\nline 3\n") mock_open.return_value.__aenter__.return_value = mock_file with patch("router.agy_proxy._last_log_check", 0): @@ -98,12 +98,12 @@ async def test_is_quota_exhausted_empty_throttled(mock_time): # Even without reading log, falls back to True assert await _is_quota_exhausted(0, "", "") is True -@patch("router.agy_proxy.os.path.exists") +@patch("aiofiles.open") @patch("router.agy_proxy.time.time") @pytest.mark.asyncio -async def test_is_quota_exhausted_empty_no_log_fallback(mock_time, mock_exists): +async def test_is_quota_exhausted_empty_no_log_fallback(mock_time, mock_open): mock_time.return_value = 1000.0 - mock_exists.return_value = False + mock_open.side_effect = FileNotFoundError() with patch("router.agy_proxy._last_log_check", 0): assert await _is_quota_exhausted(0, "", "") is True From 186c9d43bff2c13750271054802514a289e24b4f Mon Sep 17 00:00:00 2001 From: sheepdestroyer Date: Thu, 2 Jul 2026 11:09:47 +0200 Subject: [PATCH 12/12] chore: address new CodeRabbit and Gemini Code Assist reviews --- .agents/jules_regression_analysis.md | 2 +- README.md | 2 +- litellm/entrypoint.py | 6 ++++-- router/main.py | 2 +- router/tests/test_memory_mcp.py | 9 +++++++++ scripts/benchmark_classifier.py | 19 ++++++++----------- start-stack.sh | 16 +++++++--------- 7 files changed, 31 insertions(+), 25 deletions(-) diff --git a/.agents/jules_regression_analysis.md b/.agents/jules_regression_analysis.md index 78899f39..37b17229 100644 --- a/.agents/jules_regression_analysis.md +++ b/.agents/jules_regression_analysis.md @@ -61,7 +61,7 @@ To prevent automated agents from causing directory and code regressions, the fol Add a post-conflict verification script step to the agent workflow: ```bash # Verify no files were moved to root unexpectedly -git status | grep -E "renamed:|deleted:|new file:" +git status --porcelain ``` --- diff --git a/README.md b/README.md index 7c80825c..8b22f7f3 100644 --- a/README.md +++ b/README.md @@ -269,7 +269,7 @@ Exposes the entry endpoint (`http://localhost:5000/v1`) and evaluates prompt com > Model capabilities, token limits, and costs are visible in LiteLLM's Model Hub Table at `http://localhost:4000/ui/?page=model-hub-table` (or port 4000 on the gateway host). ### B. LiteLLM Proxy Gateway (`litellm/config.yaml`) -- **Version Pinning**: The LiteLLM gateway runs `ghcr.io/berriai/litellm:v1.90.2` (latest stable as of June 2026). The tag is explicitly pinned in `pod.yaml` — never use `:latest`. Check available tags with `skopeo list-tags docker://ghcr.io/berriai/litellm` before upgrading. ClickHouse runs `docker.io/clickhouse/clickhouse-server:26.5.1` (upgraded from 24.8, June 2026). Valkey Cache runs `docker.io/valkey/valkey:9.1.0-alpine` (upgraded from 8, June 2026). +- **Version Pinning**: The LiteLLM gateway, ClickHouse, and Valkey Cache image tags are explicitly pinned in `pod.yaml` — never use `:latest`. Check available tags with `skopeo list-tags` or registry hubs before upgrading. Orchestrates routing fallback chains, Redis caching, and telemetry callbacks: - **`drop_params: true`**: Automatically strips unsupported arguments when transitioning to models that don't support them. - **Request Timeouts (`300s`)**: Provides ample padding to prevent connection aborts during dynamic RAM swapping operations on the local GPU `llama-server`. diff --git a/litellm/entrypoint.py b/litellm/entrypoint.py index 20d4baf0..df7a2ec8 100644 --- a/litellm/entrypoint.py +++ b/litellm/entrypoint.py @@ -106,6 +106,10 @@ def strptime(cls, date_str: str, fmt: str) -> original_datetime: # instances, which no longer match. We must register both classes. try: from prisma.builder import serializer +except ImportError: + serializer = None + +if serializer is not None: def _serialize_dt(dt): """Serialize datetime to ISO8601 with timezone (UTC if naive).""" if dt.tzinfo is None: @@ -114,8 +118,6 @@ def _serialize_dt(dt): serializer.register(original_datetime, _serialize_dt) serializer.register(RobustDatetime, _serialize_dt) print("🩹 Registered original_datetime + RobustDatetime with Prisma serializer") -except Exception: - pass sys.stdout.flush() # Start LiteLLM Proxy diff --git a/router/main.py b/router/main.py index 036cfee2..d9292f99 100644 --- a/router/main.py +++ b/router/main.py @@ -142,7 +142,7 @@ def estimate_prompt_tokens(body: dict) -> int: # Include a flat estimate for system prompt / metadata overhead. # Use rounding to avoid truncation bias (e.g., 1.9 -> 1). - return max(1, int(round(total)) + 50) + return max(1, round(total) + 50) async def sync_cooldowns_from_valkey() -> None: diff --git a/router/tests/test_memory_mcp.py b/router/tests/test_memory_mcp.py index f0e6a6b8..236853eb 100644 --- a/router/tests/test_memory_mcp.py +++ b/router/tests/test_memory_mcp.py @@ -16,6 +16,7 @@ PREFIX, SCOPE_GLOBAL, SCOPE_LOCAL, + _is_memory_key, _make_key, _memory_entry, _memory_value, @@ -236,6 +237,14 @@ def test_memory_entry_missing_fields(): result3 = _memory_entry({}) assert result3 is None +def test_is_memory_key_types(): + """Test _is_memory_key works with both string and non-string inputs.""" + assert _is_memory_key("memory:local:test") is True + assert _is_memory_key("other:prefix") is False + assert _is_memory_key(None) is False + assert _is_memory_key(12345) is False + assert _is_memory_key([]) is False + @pytest.mark.parametrize( "key, expected", diff --git a/scripts/benchmark_classifier.py b/scripts/benchmark_classifier.py index 8e5f0766..8000fa5e 100644 --- a/scripts/benchmark_classifier.py +++ b/scripts/benchmark_classifier.py @@ -1,6 +1,8 @@ """Benchmark gemma4-26a4b-routing classifier against labeled dataset.""" import os import json, urllib.request, time, sys +import concurrent.futures +import threading from collections import defaultdict, Counter from pathlib import Path @@ -54,9 +56,6 @@ def classify(prompt): per_tier = {t: {"correct": 0, "total": 0} for t in TIERS} confusion = defaultdict(Counter) # confusion[expected][predicted] -import concurrent.futures -import threading - def process_item(item): prompt = item["prompt"] expected = item.get("tier") or item.get("clf_tier") or item.get("llm_tier", "") @@ -71,14 +70,14 @@ def process_item(item): results_list = [None] * total with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor: - rate_limit_lock = threading.Lock() + sem = threading.Semaphore(5) def process_item_with_rate_limit(index_and_item): i, item = index_and_item - with rate_limit_lock: + with sem: + # Add a small delay between acquisitions to stagger server load time.sleep(0.05) - - expected, predicted = process_item(item) + expected, predicted = process_item(item) return i, item, expected, predicted futures = [executor.submit(process_item_with_rate_limit, (i, item)) for i, item in enumerate(dataset.get("prompts", []))] @@ -93,14 +92,12 @@ def process_item_with_rate_limit(index_and_item): "predicted": predicted, } - if expected not in per_tier: - confusion[expected][predicted] += 1 - else: + if expected in per_tier: per_tier[expected]["total"] += 1 if predicted == expected: correct += 1 per_tier[expected]["correct"] += 1 - confusion[expected][predicted] += 1 + confusion[expected][predicted] += 1 completed_count += 1 diff --git a/start-stack.sh b/start-stack.sh index 1f751823..e69929ea 100755 --- a/start-stack.sh +++ b/start-stack.sh @@ -31,7 +31,12 @@ if [ -f "$ENV_FILE" ]; then fi # Ensure openssl is installed if we need to generate passwords/keys - +if [ -z "$POSTGRES_PASSWORD" ] || [ -z "$NEXTAUTH_SECRET" ] || [ -z "$SALT" ] || [ -z "$ENCRYPTION_KEY" ] || [ -z "$LITELLM_MASTER_KEY" ] || [ -z "$ROUTER_API_KEY" ] || [ -z "$MINIO_ROOT_USER" ] || [ -z "$MINIO_ROOT_PASSWORD" ] || [ -z "$LANGFUSE_INIT_USER_PASSWORD" ] || [ -z "$REDIS_AUTH" ] || [ -z "$CLICKHOUSE_PASSWORD" ] || [ -z "$LANGFUSE_PUBLIC_KEY" ] || [ -z "$LANGFUSE_SECRET_KEY" ]; then + if ! command -v openssl &>/dev/null; then + echo "❌ Error: 'openssl' is required to generate secure random keys but was not found in PATH." + exit 1 + fi +fi if [ -z "$OPENROUTER_API_KEY" ]; then if [ -t 0 ]; then @@ -95,13 +100,6 @@ else echo "⚠️ Warning: Host agy daemon not responding on port 5005" fi -if [ -z "$POSTGRES_PASSWORD" ] || [ -z "$NEXTAUTH_SECRET" ] || [ -z "$SALT" ] || [ -z "$ENCRYPTION_KEY" ] || [ -z "$LITELLM_MASTER_KEY" ] || [ -z "$ROUTER_API_KEY" ] || [ -z "$MINIO_ROOT_USER" ] || [ -z "$MINIO_ROOT_PASSWORD" ] || [ -z "$LANGFUSE_INIT_USER_PASSWORD" ] || [ -z "$REDIS_AUTH" ] || [ -z "$CLICKHOUSE_PASSWORD" ] || [ -z "$LANGFUSE_PUBLIC_KEY" ] || [ -z "$LANGFUSE_SECRET_KEY" ]; then - if ! command -v openssl &>/dev/null; then - echo "❌ Error: 'openssl' is required to generate secure random keys but was not found in PATH." - exit 1 - fi -fi - # Ensure the env file exists and has secure permissions (owner read/write only) touch "$ENV_FILE" chmod 600 "$ENV_FILE" @@ -467,7 +465,7 @@ text = text.replace("/run/user/1000", f"/run/user/{uid}") text = text.replace("LITELLM_MASTER_KEY_PLACEHOLDER", os.environ["LITELLM_MASTER_KEY"]) text = text.replace("POSTGRES_PASSWORD_RAW_PLACEHOLDER", os.environ["POSTGRES_PASSWORD"]) # URL-encode the postgres password for DSN insertion -encoded_password = urllib.parse.quote(os.environ['POSTGRES_PASSWORD']) +encoded_password = urllib.parse.quote(os.environ['POSTGRES_PASSWORD'], safe="") text = text.replace("POSTGRES_PASSWORD_ENCODED_PLACEHOLDER", encoded_password) text = text.replace("NEXTAUTH_SECRET_PLACEHOLDER", os.environ["NEXTAUTH_SECRET"]) text = text.replace("SALT_PLACEHOLDER", os.environ["SALT"])