Commit dab4dcf
feat: rectifier, OpenAI format support, React admin panel & observability (#23)
* feat: Add OpenAI format provider support (#11)
* feat: add OpenAI format provider support
Add bidirectional format conversion for OpenAI Chat Completions API, enabling fallback providers like OpenRouter, Together AI, and any OpenAI-compatible endpoint.
Changes:
- Add format field to ProviderConfig (anthropic|openai)
- Implement request/response conversion with tool_use support
- Add streaming SSE conversion via TransformStream
- Update admin UI with format selector
- Add 37 comprehensive tests (259 total passing)
- Validate format field at API boundary
Co-Authored-By: Claude Haiku 4.5 <[email protected]>
* test: improve format-converter coverage to 99%+
Add tests for edge cases: non-string/non-array content, invalid JSON
in stream, interleaved text+tool_calls, flush with remaining buffer,
and usage in regular chunks.
* chore: add Codecov configuration with relaxed thresholds
Allow coverage to decrease by up to 5% and set patch target to 70%
to prevent CI failures on minor coverage fluctuations.
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
* feat: test multiple Claude models in testConnection with mapping suggestions
Refactor testProvider to test 4 models (Sonnet, Opus 4, Opus 4.6, Haiku) in
parallel instead of a single hardcoded model. Shows per-model results in the
admin UI and suggests adding model mappings when models fail without one
configured. Also adds claude-opus-4-6-20250415 to CLAUDE_MODELS.
* feat: add provider disable/enable toggle in admin panel
Show Anthropic primary API as fixed first entry with toggle switch.
Replace reorder arrow buttons with enable/disable toggles on all
providers. Disabled providers are skipped during request routing.
* test: add tests for provider disable/enable skipping behavior
Verify disabled Anthropic primary and fallback providers are skipped
during request routing, and that 502 is returned when all are disabled.
---------
Co-authored-by: Claude Haiku 4.5 <[email protected]>
* chore: model rename
* chore: change model name
* chore: add more log info
* chore: add more log
* Refactor code for consistency and readability; update import styles, error messages, and logging format. Adjust provider configurations and enhance circuit breaker functionality. Remove DEBUG variable from wrangler configuration.
* feat: new fallback algo (#13)
* feat: implement sliding window circuit breaker with tiered backoff (#14)
* feat: new fallback algo
* docs: update documentation for circuit breaker implementation
- Update CLAUDE.md with circuit breaker architecture details
- Expand README.md with setup instructions
- Add comprehensive testing guide
- Update environment variables documentation
- Add contribution guidelines
- Expand runbook with troubleshooting steps
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
* feat: add debug curl logging and structured observability (#15)
* feat: add structured logging and observability
Implements comprehensive observability with structured JSON logging:
- Add structured logger utility with JSON format output
- Generate unique Request ID for end-to-end tracing
- Return Request ID in response headers (X-Request-ID)
- Support client-provided Request ID via header
- Replace all console.log with structured events
- Track latency for all provider attempts
- Add 11 event types: request.*, provider.*, circuit_breaker.*, safety_valve.*, auth.*, config.*
All logs include:
- timestamp (ISO 8601)
- level (debug/info/warn/error)
- event type
- requestId
- structured data (provider, model, status, latency, error)
Benefits:
- Full request tracing via Request ID
- Easy querying in Cloudflare Dashboard
- Ready for Logpush to Grafana/Datadog/Sentry
- Automatic tracing integration (already enabled in wrangler.jsonc)
Documentation:
- Added docs/observability.md with usage guide
- Updated CLAUDE.md with observability section
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
* fix: correct Headers type for x-request-id response header
Convert Record<string, string> from cleanHeaders to Headers object
before calling .set() method.
* chore: update
* feat: log reproducible curl command on request failure
When all providers fail, emit a `request.debug_curl` log entry containing
a copy-paste ready curl command that reproduces the original request to
the proxy. Accessible via `npm run tail` for local debugging.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Sonnet 4.5 <[email protected]>
* feat: redirect / to /admin
Replace the health check endpoint at / with a 302 redirect to /admin,
preparing for login page support on the admin panel.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: add login page handler
Add loginPage export to admin.ts that renders a standalone login form.
The page validates the admin token against /admin/config, stores it in
localStorage for session persistence, and redirects to the admin panel
on success.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: redirect unauthenticated /admin to login page
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: persist admin token in localStorage with logout
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: use Authorization header for admin API calls
Switch admin panel fetch calls from passing token as query parameter
to using Authorization: Bearer header. This is more secure as tokens
in query params can leak via server logs and referrer headers.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* chore: add script
* fix: id
* feat: add circuit breaker status display and manual reset to admin panel (#16)
* feat: add GET /admin/provider-states endpoint
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: add CSS for circuit breaker status badges
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: show circuit breaker status badges on admin provider cards
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: add manual reset button for provider circuit breaker
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* docs: add implementation plan for admin circuit breaker status
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
* feat(rectifier): implement Anthropic API rectifier system (#18)
* feat(rectifier): add type definitions for rectifier system
* feat(rectifier): implement Anthropic API rectifier system
Add automatic rectifier that detects and fixes Anthropic API request
compatibility issues with third-party providers. Includes thinking
signature rectification (removes thinking blocks, redacted_thinking
blocks, and signature fields) and thinking budget rectification
(adjusts budget_tokens and max_tokens to valid ranges). Each rectifier
retries once per request to prevent infinite loops. Configurable via
admin API endpoints with KV persistence.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* docs: add rectifier implementation plans
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
* Broven/admin cb status (#17)
* feat: add GET /admin/provider-states endpoint
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: add CSS for circuit breaker status badges
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: show circuit breaker status badges on admin provider cards
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat: add manual reset button for provider circuit breaker
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* docs: add implementation plan for admin circuit breaker status
* fix: syntax error in reset button onclick handler
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
* update: don't cooldown when there is only one provider in there
* fix: implement thinking signature rectification for primary Anthropic API (#19)
* feat: refact admin page (#21)
* request_idrequest_id
* fix: correct login redirect path to /admin/login (#22)
* feat: implement provider retry mechanism with exponential backoff
- Add `retry` field to ProviderConfig in types
- Implement retry loop in `src/utils/provider.ts` for network and 5xx errors
- Add retry configuration UI to Admin Panel provider modal
- Exclude 4xx/429 errors from retry logic
- Add exponential backoff (500ms * 2^attempt)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: apply signature rectification in safety valve mechanism
When the safety valve is triggered (all providers in cooldown), the request
was bypassing the thinking signature rectification logic. This caused 400
Invalid Signature errors to persist even when using the safety valve.
This change adds the rectification logic to the safety valve execution path,
ensuring that invalid thinking blocks are removed before retrying the request.
* test: add test case for safety valve signature rectification
* fix: prevent binary garbage in logs by stripping accept-encoding header
Updates request handling to remove the 'accept-encoding' header before forwarding requests to upstream providers. This ensures that the runtime handles compression negotiation automatically, preventing issues where the worker receives compressed error responses (like 403s) and logs them as binary garbage.
Changes:
- Added `cleanRequestHeaders` in `src/utils/headers.ts` to filter unsafe headers including `accept-encoding`.
- Updated `src/index.ts` to use `cleanRequestHeaders` for primary and fallback requests.
- Updated `src/utils/provider.ts` to exclude `accept-encoding` and use `cleanHeaders` for error responses.
- Updated `src/admin.ts` to strip unsafe headers in provider testing.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: strip cch parameter from billing header to improve caching
The x-anthropic-billing-header system message contains a 'cch' parameter
that changes with every request, preventing effective prompt caching.
This change strips that parameter while preserving the rest of the header.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: increase rectifier retry timeout and fallback on timeout
Rectifier retry was using 30s timeout which was too short for large
request bodies after stripping thinking blocks. When timeout occurred,
the original 400 error was returned directly instead of trying fallback
providers. Now uses 120s timeout and sets status to 504 on timeout so
the request continues to fallback providers.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* chore: update CLAUDE.md
* stop tracking .dev.vars
* stop tracking .dev.vars
* chore: add debug log
* docs: update README with new features (rectifier, OpenAI format, admin panel, observability)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* feat(rectifier): add tool-use concurrency rectifier (RECT-003)
Auto-detect orphaned tool_use blocks missing corresponding tool_result
and inject dummy error tool_result to unblock the request. Integrated
into primary, safety valve, and fallback provider flows. Also unify
debug-skip header filtering (x-ccf-* prefix) and add error snippet to
failure logs.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* ci: auto create github release on tag
* test: add config coverage for rectifier and admin flags
* chore: trigger PR head refresh
---------
Co-authored-by: Claude Haiku 4.5 <[email protected]>1 parent 56a403b commit dab4dcf
91 files changed
Lines changed: 18071 additions & 1778 deletions
File tree
- .config
- .github/workflows
- docs
- plans
- frontend
- frontend/src
- components
- providers
- sections
- ui
- hooks
- lib
- pages
- public
- src
- assets
- components
- providers
- sections
- ui
- hooks
- lib
- pages
- scripts
- src
- __tests__
- utils
- rectifier
- types
- utils
- rectifier
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
18 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
19 | 27 | | |
20 | 28 | | |
21 | 29 | | |
22 | 30 | | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
28 | 41 | | |
29 | 42 | | |
30 | 43 | | |
31 | 44 | | |
32 | | - | |
33 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
34 | 52 | | |
35 | 53 | | |
36 | 54 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
52 | 79 | | |
53 | 80 | | |
54 | 81 | | |
55 | 82 | | |
56 | 83 | | |
57 | | - | |
| 84 | + | |
58 | 85 | | |
59 | 86 | | |
60 | 87 | | |
61 | 88 | | |
62 | | - | |
| 89 | + | |
63 | 90 | | |
64 | 91 | | |
65 | 92 | | |
66 | 93 | | |
67 | | - | |
| 94 | + | |
68 | 95 | | |
69 | 96 | | |
70 | 97 | | |
| |||
74 | 101 | | |
75 | 102 | | |
76 | 103 | | |
77 | | - | |
78 | | - | |
79 | | - | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
80 | 109 | | |
81 | | - | |
| 110 | + | |
82 | 111 | | |
83 | | - | |
84 | | - | |
85 | | - | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
86 | 125 | | |
87 | 126 | | |
88 | 127 | | |
| |||
108 | 147 | | |
109 | 148 | | |
110 | 149 | | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | 150 | | |
121 | 151 | | |
122 | 152 | | |
| |||
129 | 159 | | |
130 | 160 | | |
131 | 161 | | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | 162 | | |
140 | 163 | | |
141 | | - | |
| 164 | + | |
142 | 165 | | |
143 | 166 | | |
144 | 167 | | |
145 | 168 | | |
146 | 169 | | |
147 | 170 | | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
159 | 176 | | |
160 | 177 | | |
161 | 178 | | |
| |||
170 | 187 | | |
171 | 188 | | |
172 | 189 | | |
173 | | - | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
184 | | - | |
185 | | - | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
0 commit comments