From b30346bcb6839428bd22d5b0d08a03edfcdb057b Mon Sep 17 00:00:00 2001 From: redshift <213178690+1ftredsh@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:17:22 +0530 Subject: [PATCH] chore: untrack stray local files & gitignore Remove accidentally-committed local-only files: - .wallet/wallet.sqlite3-shm / .wal (runtime DB sidecar files) - AGENTS.md, TEST_SUITE_OVERVIEW.md (local agent context artifacts) Add .wallet/, AGENTS.md, TEST_SUITE_OVERVIEW.md to .gitignore. --- .gitignore | 3 + .wallet/wallet.sqlite3-shm | Bin 32768 -> 0 bytes .wallet/wallet.sqlite3-wal | Bin 428512 -> 0 bytes AGENTS.md | 87 ------------------ TEST_SUITE_OVERVIEW.md | 180 ------------------------------------- 5 files changed, 3 insertions(+), 267 deletions(-) delete mode 100644 .wallet/wallet.sqlite3-shm delete mode 100644 .wallet/wallet.sqlite3-wal delete mode 100644 AGENTS.md delete mode 100644 TEST_SUITE_OVERVIEW.md diff --git a/.gitignore b/.gitignore index 13985d7..0d6c723 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,9 @@ dist/ *.db-shm *.db-wal .*wallet.sqlite3 +.wallet/ +AGENTS.md +TEST_SUITE_OVERVIEW.md *models.json .cashu .relay diff --git a/.wallet/wallet.sqlite3-shm b/.wallet/wallet.sqlite3-shm deleted file mode 100644 index 43eb655de1b564fe464db10a5f0c4a5dcaa9c1f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 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 4096 workaround) | `test_messages_litellm_dispatch.py` | -| Aggregator: text deltas โ†’ single message, tool_use `input_json_delta` concatenation, SSE byte chunk parsing | `test_messages_litellm_dispatch.py` | -| Cost accumulation across multiple message events (uses `+=` not `max()`) | `test_messages_dispatch_cost_accumulation.py` | -| Token/cost extraction, cache tokens, model name extraction/override, SSE encoding, malformed/negative cost clamping | `test_messages_dispatch_cost_accumulation.py` | - ---- - -## ๐Ÿท๏ธ Provider Field Injection - -| What's tested | Key files | -|---|---| -| Direct upstreams get bare `provider_type`, OpenRouter gets `openrouter:UpstreamProvider`, unknown/missing becomes `"unknown"` | `test_provider_field_injection.py` | -| Idempotency: double-stamping never nests prefix (`openrouter:openrouter:Google` โ†’ `openrouter:Google`) | `test_provider_field_injection.py` | -| Whitespace stripping, non-string/non-dict inputs skipped, `inject_cost_metadata` also stamps provider | `test_provider_field_injection.py` | - ---- - -## โš™๏ธ Upstream Providers - -| What's tested | Key files | -|---|---| -| Azure: `api-key` header instead of `Authorization`, BOM-stripped API version, deployment ID path construction, base URL stripping | `test_upstream_azure.py` | -| Gemini messages: `inject_thought_signatures` for tool calls, `_openai_chunks_to_anthropic_events` translator (text, tool_use, [DONE] sentinel, blank lines) | `test_upstream_gemini.py` | -| Routstr upstream: balance RPC (auth header omitted when api_key empty, connect timeout โ†’ None), `/v1` path preservation, native messages support | `test_upstream_routstr.py` | -| Error normalization: HTML/plaintext upstream errors โ†’ JSON envelope, JSON errors pass through unchanged, empty body handling | `test_upstream_error_response.py` | -| Litellm provider prefix detection: 40+ providers from URL patterns (Fireworks, Groq, xAI, DeepSeek, Together, Perplexity, Mistral, etc.) | `test_litellm_routing.py` | -| Azure ordering beats `api.openai.com`, Ollama localhost detection, casing/trailing slash normalization, custom defaults | `test_litellm_routing.py` | -| Subclass prefix override wins over URL detection, native messages support flags | `test_messages_litellm_dispatch.py` | - ---- - -## ๐Ÿ’ต Cost Calculation & Caching - -| What's tested | Key files | -|---|---| -| OpenAI vs Anthropic cache token formats (subtractive vs additive), cache_read exceeds prompt_tokens, malformed/boolean/float token coercion | `test_cost_calculation_caching.py` | -| Token field fallback order, missing/null usage blocks, both cache_read and cache_creation simultaneously | `test_cost_calculation_caching.py` | -| x-cashu cost injection in non-streaming/streaming responses, `cost_sats` rounding, existing usage fields preserved | `test_x_cashu_cost_sats.py` | - ---- - -## ๐Ÿงฎ Token Counting - -| What's tested | Key files | -|---|---| -| Local `count_tokens` shim: simple messages, litellm fallback, missing model object, empty body, malformed JSON, system prompts, Anthropic system block list, `forwarded_model_id` | `test_count_tokens_local.py` | -| Image token estimation: low/high/auto detail, small/large images, base64, multiple images, `input_image` type, no images | `test_image_tokens.py` | -| Invalid image data falls back to 512ร—512 defaults | `test_image_tokens.py` | - ---- - -## ๐Ÿง  Model Prioritization Algorithm - -| What's tested | Key files | -|---|---| -| Cost scores (basic, with request fee, expensive models), provider penalties (regular=1.0, OpenRouter=1.001) | `test_algorithm.py` | -| Model overrides for missing cached models, deduplication by provider identity (not provider type) | `test_algorithm.py` | - ---- - -## ๐Ÿ”„ Reactive Request Correction - -| What's tested | Key files | -|---|---| -| Stripping deprecated `temperature`, unsupported params from request body before retry | `test_request_correction.py` | -| No correction when param absent, label already applied, error message doesn't match, empty inputs, non-object body | `test_request_correction.py` | -| Deprecated model name NOT stripped as param, streaming 400 buffered error is correctable | `test_request_correction.py` | -| Sequential two-param correction (with `applied` set guard), immutability of input | `test_request_correction.py` | - ---- - -## ๐Ÿ—„๏ธ Database Consistency - -| What's tested | Key files | -|---|---| -| Transaction atomicity: balance update rollback on failure, top-up rollback on network error | `test_database_consistency.py` | -| Concurrent balance updates via direct DB operations, race condition prevention | `test_database_consistency.py` | -| Primary key uniqueness enforced, numeric field constraints | `test_database_consistency.py` | -| Connection pooling under load (50 concurrent requests), index usage (primary key lookup < 10ms) | `test_database_consistency.py` | - ---- - -## ๐Ÿ” Nostr Discovery & Analytics - -| What's tested | Key files | -|---|---| -| Provider discovery endpoint: default format, `include_json=true`, data structure validation, NIP-91-only parsing | `test_provider_management.py` | -| No-providers, offline providers, duplicate URLs, Nostr relay failures, malformed URLs, parameter validation | `test_provider_management.py` | -| Admin routstr top-up with transient upstream failure retry | `test_provider_management.py` | -| Analytics snapshot payload: top model usage aggregation, schema/shape, fingerprint ignores `generated_at` | `test_nostr_analytics.py` | -| Analytics disable/empty-nsec skip, deduplication of unchanged payloads | `test_nostr_analytics.py` | - ---- - -## โš™๏ธ Infrastructure & Settings - -| What's tested | Key files | -|---|---| -| Settings seed from env, DB precedence over env, unknown key discarding, payout settings defaults and validation | `test_settings.py` | -| Periodic upstream models refresh loop: picks up providers added after startup, disabled at non-positive interval | `test_models_refresh_loop.py` | -| Logging SecurityFilter: Bearer tokens, Cashu tokens, nsec keys, API keys โ€” redacted; case insensitivity, multiple secrets, non-sensitive messages left intact | `test_logging_securityfilter.py` | - ---- - -## ๐Ÿงช Integration Test Infrastructure - -The `conftest.py` (~400 lines) provides: - -- **`TestmintWallet`**: Simulated cashu mint with fallback token creation, secure token uniqueness via `secrets.token_hex` to prevent hash collisions in concurrent tests -- **`DatabaseSnapshot`**: Before/after diffing of API key state (added/modified/removed with field-level deltas) -- **App fixture**: Full FastAPI app with all wallet/proxy mocks patched in (credit_balance, send_token, recieve_token, etc.) -- **Authenticated client**: Client with persistent API key and 10k sat balance created automatically -- **WebSocket mock**: Nostr discovery patched to fail fast for performance -- **Docker vs mock mode**: Switches between real Docker services and in-memory mocks via `USE_LOCAL_SERVICES` env var