Skip to content

feat(ai-partner): Cloudflare Worker AI proxy (#1450)#1478

Merged
CraigBuckmaster merged 1 commit into
masterfrom
claude/issue-1450-ai-proxy
Apr 17, 2026
Merged

feat(ai-partner): Cloudflare Worker AI proxy (#1450)#1478
CraigBuckmaster merged 1 commit into
masterfrom
claude/issue-1450-ai-proxy

Conversation

@CraigBuckmaster
Copy link
Copy Markdown
Owner

Closes #1450. Phase 1 of epic #1446.

Summary

New ai-proxy/ directory containing the Cloudflare Worker that handles RevenueCat auth, rate limiting, zero-retention enforcement, streaming pass-through to Anthropic, and gap-signal detection for the downstream corpus-gap pipeline (#1471).

Endpoints

Method Path Auth Purpose
GET /ai/health none liveness probe
POST /ai/embed premium / partner_plus OpenAI text-embedding-3-small → 1536 floats
POST /ai/chat premium / partner_plus streaming Anthropic SSE

Key behaviors

  • Auth — RevenueCat receipt validated, cached in KV for 5 min keyed on SHA-256(receipt). Structured failure codes map to 401 (missing/malformed) / 402 (no entitlement) / 503 (RevenueCat down).
  • Rate limit — monthly + 10-min burst per receipt. premium 300 + 10, partner_plus 1500 + 30. 429 with retry_after and optional upgrade_url for premium users.
  • Anthropic clientanthropic-no-retention: true header set on every outbound call. partner_plus always routes to Sonnet regardless of client hint. System prompt assembled server-side from profile + chunks.
  • Gap detection — teed stream, server-side consumer extracts the trailing {"gap": true, ...} envelope, writes a stub D1 row + structured log. ai-partner: corpus gap capture (D1 + proxy detection + GitHub sync) #1471 replaces the stub with full persistence, semantic dedup, and GitHub sync.
  • Logging — metadata-only: user_hash (first 8 hex), endpoint, status, latency_ms, entitlement. Zero request/response body logging.

Test plan

  • npm install and npx tsc --noEmit — strict TypeScript passes
  • npm test — 37 Vitest tests pass
    • auth: bearer extraction, hashing, RevenueCat response parsing, cache behavior, malformed / missing / inactive cases
    • rateLimit: burst blocking, monthly blocking, per-user isolation, bucket semantics
    • gapDetection: valid/false/missing/invalid signal envelopes, embedded braces
    • anthropic: model routing (Haiku/Sonnet), partner_plus override, zero-retention header, body shape
  • Works offline — all outbound HTTP is fetch-interceptable
  • wrangler dev smoke — reviewer to verify once a dev KV namespace is wired up; tests cover the code paths wrangler would exercise

Out of scope

https://claude.ai/code/session_01Pht3kzgdvkn81DDfL9SnFe

New top-level ai-proxy/ directory with the Worker that sits between the
mobile client and Anthropic/OpenAI. Co-located with the rest of the repo
so the client and proxy evolve together.

Endpoints:
- GET  /ai/health — liveness; returns {status, version}
- POST /ai/embed  — OpenAI text-embedding-3-small, 1536-dim vector
- POST /ai/chat   — streaming Anthropic SSE with gap-signal detection

Auth: RevenueCat receipt validated with 5-min KV cache keyed on the
SHA-256 of the receipt; 401 / 402 / 503 classified by failure kind.

Rate limit: per-user monthly + 10-minute burst counters in KV.
  premium:      300/month + 10/burst
  partner_plus: 1,500/month + 30/burst

Anthropic client: zero-retention header, server-side system prompt
assembly, partner_plus always routes to Sonnet regardless of client
hint.

Gap detection: parses the trailing {"gap": ...} JSON envelope from the
streamed response; writes a stub D1 row + structured log today. #1471
replaces the stub with full D1 schema + semantic dedup + GitHub sync.

Logging: metadata-only — user_hash, endpoint, status, latency,
entitlement. Never logs request bodies, response text, retrieved
chunks, or profile summaries.

Tests: 37 Vitest tests across auth, rate-limit, gap-detection, and
Anthropic client. All run offline via fetch interception + in-memory
KV stub.

https://claude.ai/code/session_01Pht3kzgdvkn81DDfL9SnFe
@github-actions
Copy link
Copy Markdown

Test Results

✅ All tests passed

Passed Failed Total
Tests ✅ 3183 ❌ 0 3183
Suites ✅ 426 ❌ 0 426

Coverage

Statements Branches Functions Lines

⏱️ Duration: 77.8s

@CraigBuckmaster CraigBuckmaster merged commit 0b79ce2 into master Apr 17, 2026
6 checks passed
@CraigBuckmaster CraigBuckmaster deleted the claude/issue-1450-ai-proxy branch April 17, 2026 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ai-partner: Cloudflare Worker AI proxy stand-up

2 participants