Commit graph

37 commits

Author SHA1 Message Date
jedarden
624047e1df docs(bf-4lid): verify test environment configuration helpers
All acceptance criteria verified:
1. IsTestMode() correctly detects test mode
2. GetTestMaxRetries() returns DefaultTestMaxRetries (1) by default
3. GetTestMaxRetries() respects MAX_RETRIES environment variable
4. ConfigureTestEnv() sets all 7 required environment variables

All 19 subtests in TestHelperFunctions pass.
2026-07-02 18:05:40 -04:00
jedarden
1b597190b1 test(bf-4lid): add comprehensive test environment config helper tests
- Add GetTestMaxRetries_WithOverride test to verify MAX_RETRIES env var handling
- Add ConfigureTestEnv test to verify all required environment variables are set
- Test coverage includes: valid/invalid env values, all 7 required vars
- All acceptance criteria for bead bf-4lid are now verified
2026-07-02 17:39:34 -04:00
jedarden
2d508816e8 test(bf-4lid): add comprehensive test environment config helper tests
Added proxy/helpers_env_test.go with thorough coverage of:
- IsTestMode(): Verifies test mode detection via testing.Testing()
  and ZAI_PROXY_TEST_MODE env var
- GetTestMaxRetries(): Tests default value (1), valid overrides,
  and invalid value handling
- ConfigureTestEnv(): Validates all 7 required environment variables
  are set correctly (MAX_RETRIES, ZAI_PROXY_TEST_MODE,
  DEPLOYMENT_VARIANT, TOKEN_COUNTING_ENABLED, RATE_LIMIT_*)

Acceptance criteria met:
1. IsTestMode() correctly detects test mode ✓
2. GetTestMaxRetries() returns DefaultTestMaxRetries (1) ✓
3. GetTestMaxRetries() respects MAX_RETRIES override ✓
4. ConfigureTestEnv() sets all required env vars ✓

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 17:39:34 -04:00
jedarden
633df37649 refactor(bf-j6s): update default SCRAPE_TARGETS from mcp to devpod namespace
- Refactor dashboard/collector/collector.go to use config.GetScrapeTargets()
- Refactor dashboard/api/router.go to use config.GetScrapeTargets()
- Add dashboard/config/config.go with DefaultScrapeTarget set to devpod namespace
- Remove hardcoded mcp namespace defaults from both files

Acceptance: No occurrence of zai-proxy.mcp.svc.cluster.local remains in dashboard Go code, both DefaultConfig structs use devpod default, existing SCRAPE_TARGETS env override unchanged.
2026-07-02 17:18:32 -04:00
jedarden
ef301090ce docs(bf-2kk): verify response validation test coverage
All required tests already exist and pass:
- Empty/invalid JSON body (non-streaming) triggers retries → 502
- Empty streaming response (zero bytes) triggers retries → 502
- Upstream call counts verified (1 + MAX_RETRIES)
- Metric assertions verified (error_type labels)
- go test ./proxy/ -run TestResponseValidation -race PASS

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 15:33:08 -04:00
jedarden
fceff86231 docs(bf-244): verify 429 retry logic unit tests
- Confirmed comprehensive 429 retry tests exist in proxy/retry_test.go
- All tests pass with -race flag
- Test coverage includes:
  - 429 with Retry-After header (delay honored, metric tracked, call counts verified)
  - 429 without Retry-After (exponential backoff, metric tracked, call counts verified)
  - Multiple retries, metric labels, concurrent scenarios
  - Integration tests with real ProxyHandler

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 15:04:19 -04:00
jedarden
55fe16e130 test(bf-244): add comprehensive 429 retry logic unit tests
Add unit tests covering all 429 retry scenarios with proper backoff behavior:

- Test429WithRetryAfterMetricVerification: Verifies 429 with Retry-After header
  honours the delay before retry, returns success, makes exactly 2 upstream calls,
  and increments zai_proxy_retry_attempts_total{reason="429"} once

- Test429WithoutRetryAfterMetricVerification: Verifies 429 without Retry-After
  uses exponential backoff up to MAX_RETRIES, surfaces 429, makes MAX_RETRIES+1
  upstream calls, and increments metric MAX_RETRIES times

- Test429MultipleRetriesMetricVerification: Verifies multiple 429 retries with
  correct metric increments and upstream call counts

- Test429MetricLabelVerification: Verifies retry metric uses correct reason labels

- Test429ConcurrentMetricVerification: Verifies concurrent 429 responses are
  tracked correctly in metrics

- Integration tests: TestIntegration429WithRetryAfter, TestIntegration429NoHeader
  test retry behavior through real proxy handler

All tests pass with -race detector. Uses test infrastructure from bf-3zp.
2026-07-02 15:01:04 -04:00
jedarden
de0320d23d docs(bf-3zp): verify test infrastructure for mock upstream server
Verified comprehensive test infrastructure already exists in proxy/helpers_test.go:
- MockUpstream with configurable scenarios
- Test mode configuration (TestModeEnv, TestMaxRetriesEnv)
- Request builders and response assertions
- Proxy handler factory and execution helpers
- All helper tests pass successfully

No code changes needed - infrastructure is complete and functional.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 14:42:20 -04:00
jedarden
fa9a54faca chore: remove unused Dockerfile variants
Delete Dockerfile.minimal, Dockerfile.simple, and Dockerfile.binary
which were not referenced by CI, scripts, or documentation.
The production Dockerfile remains unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 14:06:16 -04:00
jedarden
1edb75ef1a fix(bf-3zp): correct package declaration in ratelimiter_test.go
Change package from 'proxy' to 'main' to match other test files in the
proxy directory. This fixes the package mismatch that prevented tests
from running properly.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 14:00:46 -04:00
jedarden
26ab25bc93 notes(bf-4k9): verify plan.md already up-to-date for dashboard 1.1.0
All required changes were already present in docs/plan/plan.md from
commit cadc7da. This note documents verification of acceptance criteria:
- Header versions match proxy/VERSION and dashboard/VERSION
- Tokens panel row includes cache-read/cache-write series
- Collector fields table includes cache token rates
- Docs inventory lists all four new documents
2026-07-02 13:53:45 -04:00
jedarden
cadc7daa6b docs(plan): update dashboard version to 1.1.0, document cache token features and new docs
- Bump header version: dashboard 1.0.0 → 1.1.0, last updated 2026-07-02
- Update Tokens panel row to reflect cache-read/cache-write token rates and running totals display
- Add cache token rate fields (token_rate_cache_read/write) to snapshot fields table
- Add new docs to Operations inventory: dashboard/README.md, DASHBOARD_API_REFERENCE.md, DEVELOPMENT.md, CONTRIBUTING.md

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 13:46:27 -04:00
jedarden
a9a8324c31 test(bf-3zp): validate test infrastructure for mock upstream server
Confirm that test infrastructure in helpers_test.go meets all acceptance criteria:

 MockUpstream and CountingMockServer for httptest-based mock upstreams
 Request builders (CreateProxyRequest, CreateMessagesRequest, etc.)
 Response assertions (AssertStatusCode, AssertJSONBody, etc.)
 Test-mode configuration (ConfigureTestEnv, GetTestMaxRetries)
 TestHelperFunctions and TestMockUpstreamBasic tests pass
 All tests use mock servers, never hit real api.z.ai

The infrastructure was already implemented. This commit validates it works correctly.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 13:26:28 -04:00
jedarden
906da31dec notes(bf-32n): document that bounds enforcement tests already exist
All acceptance criteria verified - TestAdaptiveRateLimiter_BasicBounds
already exists and passes with injected window duration.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 13:19:04 -04:00
jedarden
2cdef80126 test(bf-3zp): add mock upstream server test infrastructure
Add comprehensive test infrastructure for retry/response-validation tests
in proxy package. Provides httptest-based mock upstream server, test
helpers for request/response handling, and test-mode configuration for
fast test execution.

New file: proxy/helpers_test.go
- MockUpstream: Configurable HTTP server simulating Z.AI upstream
- Test scenarios: 429 with/without Retry-After, empty/invalid JSON body,
  empty streaming, 422/500/404 responses, network errors, success
- Request builders: CreateProxyRequest, CreateMessagesRequest,
  CreateStreaming/NonStreaming* helpers
- Response assertions: AssertStatusCode, AssertJSONBody, AssertResponseField,
  AssertEmptyBody, AssertHeader, AssertContentType
- Proxy handler factory: CreateTestProxyHandler for configured test handlers
- Test execution helpers: ExecuteProxyRequest, ExecuteMessagesRequest
- Test-mode config: ConfigureTestEnv, GetTestMaxRetries (defaults to 1 for fast tests)
- Backoff delay helpers: CalculateBackoffDelay, CalculateTotalMaxDelay

Acceptance criteria met:
 New test helpers with httptest servers
 Helper functions for requests and assertions
 Test-mode env var for fast tests (MAX_RETRIES=1 default)
 go test ./proxy/ -run TestHelper passes

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 12:45:10 -04:00
jedarden
22644eab33 test(ratelimiter): improve TestAdaptiveRateLimiter_BasicBounds to use injected window duration
- Use NewAdaptiveRateLimiterWithWindow with 10ms window for fast test execution
- Replace manual lastAdjustment manipulation with proper testWindow variable
- Maintain all existing test scenarios and verifications
- Tests now run faster without sleep calls while maintaining correctness

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 12:38:25 -04:00
jedarden
49471e87a7 docs(bf-47d): document that TestAdaptiveRateLimiter_BasicState already exists
- TestAdaptiveRateLimiter_BasicState already exists in proxy/ratelimiter_test.go
- All acceptance criteria already met and verified passing
- No code changes required

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 12:30:34 -04:00
jedarden
f878bf4f6e test(ratelimiter): verify TestAdaptiveRateLimiter_BasicState passes all acceptance criteria 2026-07-02 11:53:23 -04:00
jedarden
91746e79ac refactor(module): move go.mod to root and consolidate dependencies
- Move go.mod and go.sum from proxy/ to repository root
- Enables running tests with 'go test ./proxy' from project root
- Module path: git.ardenone.com/jedarden/zai-proxy
- Go 1.23 with toolchain go1.24.13

Co-Authored-By: Claude <noreply@anthropic.com>
Bead-Id: bf-1rb
2026-07-02 11:52:23 -04:00
jedarden
88358f949a test(ratelimiter): add basic state and bounds tests for AdaptiveRateLimiter
Add table-driven unit tests covering:
- Initial rate starts at ceiling (TestAdaptiveRateLimiter_BasicState)
- Rate never drops below minRate (TestAdaptiveRateLimiter_BasicBounds)
- Rate never exceeds maxRate (TestAdaptiveRateLimiter_BasicBounds)
- Reset() restores initial rate and ceiling (TestAdaptiveRateLimiter_BasicReset)
- getCurrentRate() returns expected values (TestAdaptiveRateLimiter_BasicGetCurrentRate)
- Edge cases: minRate==maxRate, zero ceiling (TestAdaptiveRateLimiter_BasicEdgeCases)

Tests complete in <5ms without sleep calls using injected window duration.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 11:47:57 -04:00
jedarden
ee39121cd9 test(ratelimiter): make AdaptiveRateLimiter testable via window duration injection
Add NewAdaptiveRateLimiterWithWindow constructor for test-only refactor:
- Production code uses NewAdaptiveRateLimiter with default 30s window
- Tests can inject shorter durations (e.g., 100ms) for fast execution
- No behavior changes to production rate limiting logic

Acceptance criteria:
- NewAdaptiveRateLimiterWithWindow accepts configurable window duration
- Production callers continue using default 30s window
- Tests can inject millisecond-scale windows for fast iteration
- No changes to rate limiting logic or defaults

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 10:55:06 -04:00
jedarden
688c0535f2 docs(readme): fix intro - describe Z.AI as Claude API not Anthropic-compatible
- Change description from 'Z.AI Anthropic-compatible API' to 'Z.AI Claude API'
- Z.AI is Claude-native, not merely compatible (per plan.md)
- No other changes needed - metrics, env defaults, and port were already correct

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 08:45:18 -04:00
jedarden
e5d0d11c3d docs(proxy): fix README - remove :latest tags, update namespace to devpod, fix go run command
- Change Kubernetes example image from ghcr.io/ardenone/zai-proxy:latest to ronaldraygun/zai-proxy:1.10.0
- Update namespace references from mcp to devpod (production deployment namespace)
- Fix 'go run main.go tokenizer.go' to 'go run .' (compilable command)
- Update Docker image examples to use version tag 1.10.0 instead of :latest/:dev
- Update cluster DNS from mcp.svc.cluster.local to devpod.svc.cluster.local

Verified against:
- docs/plan/plan.md (CI/CD, Deployment sections)
- proxy/VERSION (current version: 1.10.0)
- proxy/metrics.go (metric names)
- proxy/main.go (env vars)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 08:29:33 -04:00
jedarden
769c33ea3a docs(notes): document bead bf-4co completion - README fixes already done in a106abd 2026-07-02 07:59:17 -04:00
jedarden
a106abd09d docs(readme): fix metric names, dashboard port, and env var defaults
- Fix metric names to use zai_proxy_ prefix (matching proxy/metrics.go)
- Fix dashboard port from :3000 to :8080 (matching DefaultConfig)
- Fix env var defaults: RATE_LIMIT_INITIAL=10.0, RATE_LIMIT_MIN=1.0, RATE_LIMIT_MAX=50.0, MAX_RETRIES=3
- Add missing RATE_LIMIT_* tunables: CEILING_ALPHA=0.3, HOLD_MARGIN=0.02, PROBE_INTERVAL=10
- Fix ZAI_TARGET_URL default to https://api.z.ai/api/anthropic
- Update description to reflect Z.AI-specific implementation (not OpenAI-compatible)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 07:47:43 -04:00
jedarden
4dcafd8a52 docs: improve README for clarity and discoverability
Rewrite root README as a provider-agnostic description of the proxy
and dashboard. Remove internal git remote reference. Add quick-start,
environment variable table, and metrics inventory.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 07:07:50 -04:00
jedarden
36727ac66d docs(plan): mark migration checklist complete
All migration items completed:
- Workflow templates pushed to declarative-config (May 17)
- Documentation updated to point to new repo (ardenone-cluster commit 79b9a9cf8)
- Old container directories retired (ardenone-cluster commit 4b4468842)

The zai-proxy project now lives at git.ardenone.com/jedarden/zai-proxy
with CI/CD workflow templates deployed via ArgoCD.

Note: Commit pending push due to Forgejo network connectivity issue.
Bead-Id: bf-4a2
2026-06-21 10:38:46 -04:00
jedarden
c3289efcf9 docs(dashboard): enhance API reference with SSE implementation details and storage backend specs
- Add detailed SSE connection behavior and slow client detection
- Add server-side implementation details (broadcast hub, client management)
- Add automatic operations section (downsampling, cleanup, WAL mode)
- Add storage backend details (database, write strategy, query strategy)
- Fix retention period for metrics_5s (24h, not 6h)

Co-Authored-By: Claude <noreply@anthropic.com>
Bead-Id: bf-4rx
2026-06-21 10:32:03 -04:00
jedarden
8dcadbb051 docs: add comprehensive DEVELOPMENT.md developer guide
Bead-Id: bf-4bd
2026-06-21 10:05:18 -04:00
jedarden
5b648096bd docs: add comprehensive CONTRIBUTING.md
Covers:
- Development environment setup
- Code style and conventions
- Testing requirements (go test, regression tests, benchmarks)
- Commit message conventions (conventional commits)
- Pull request process
- How to add new features or fix bugs
- Documentation guidelines
- Getting help

Bead-Id: bf-4ys
2026-06-21 10:02:17 -04:00
jedarden
19e6e9c959 docs(dashboard): add comprehensive API reference documentation
- Document all 5 API endpoints: /healthz, /api/config, /api/status, /api/metrics, /api/events
- Include request parameters, response schemas, and example curl commands
- Document SSE event types and format with code examples in JavaScript and Go
- Add data retention policies, CORS information, and browser usage guidance
- Link to related documentation

Co-Authored-By: Claude <noreply@anthropic.com>
Bead-Id: bf-4rx
2026-06-21 09:59:26 -04:00
jedarden
225f7cfe51 docs(dashboard): add comprehensive README.md
- Architecture overview with component diagram
- Quick start for local, frontend dev, Docker, and Kubernetes
- Configuration environment variables reference
- Complete API endpoints documentation (REST + SSE)
- Data model and storage schema explanation
- Development setup and testing instructions
- Troubleshooting guide
- Performance characteristics

Co-Authored-By: Claude <noreply@anthropic.com>
Bead-Id: bf-2o7
2026-06-21 09:56:17 -04:00
jedarden
c45a974e2e fix(dashboard): remove unused formatRate import in TokenPanel
tsc -b fails with TS6133 (declared but never read). Breaks Docker build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 10:58:35 -04:00
jedarden
a95bea7c93 chore(dashboard): bump VERSION to 1.1.0
Adds cache token tracking (tokens_cache_read, tokens_cache_write) and
running window totals strip to TokenPanel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 06:55:49 -04:00
jedarden
9799d75d2b feat(dashboard): add cache token tracking and running totals panel
Adds cache_read and cache_write token directions throughout the
observability stack so Anthropic prompt-cache billing is visible.

- model/metrics.go: TokensCacheRead, TokensCacheWrite, TokenRateCacheRead,
  TokenRateCacheWrite fields on MetricSnapshot
- collector: reads direction=cache_read/cache_write from
  zai_proxy_tokens_total Prometheus metric
- frontend types.ts: matching TS fields
- TokenPanel: rewritten to show all 4 directions (input, output,
  cache_read, cache_write) on the rate chart; running-total summary
  strip above the chart shows window totals (e.g. "5h window: 1.2M
  input / 340k output / 89k cache_read / 12k cache_write")

Also updates docs/plan/plan.md to accurately document the full
dashboard architecture (backend API, storage schema, SSE hub,
frontend panels, Grafana layer, env vars).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 23:08:28 -04:00
jedarden
dee82a76a3 chore: update module paths and add evaluation package
- proxy/go.mod: github.com/ardenone/zai-proxy → git.ardenone.com/jedarden/zai-proxy
- dashboard/go.mod: github.com/ardenone/ardenone-cluster/containers/zai-proxy-dashboard → git.ardenone.com/jedarden/zai-proxy/dashboard
- Update all Go import paths in proxy/ and dashboard/ to match new module paths
- Add proxy/evaluation/ package (was missing from initial commit)
- Add docs/plan/plan.md with architecture, security model, telemetry design, and migration checklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 16:03:50 -04:00
jedarden
e7c24a0c08 feat: initial zai-proxy ecosystem repo
Extracted from ardenone-cluster/containers/zai-proxy and
ardenone-cluster/containers/zai-proxy-dashboard.

- proxy/: OpenAI-compatible ZAI reverse proxy (Go, v1.10.0)
  - Token counting, rate limiting, Prometheus metrics, canary support
- dashboard/: Metrics dashboard backend + React frontend (Go, v1.0.0)
  - Prometheus collector, SQLite storage, SSE live updates
- docs/: Operational notes, research, and plan subdirs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 15:53:52 -04:00