@askalf/dario 3.2.3 → 3.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/proxy.js +44 -4
  2. package/package.json +1 -1
package/dist/proxy.js CHANGED
@@ -731,9 +731,9 @@ export async function startProxy(opts = {}) {
731
731
  beta += ',' + clientBeta;
732
732
  }
733
733
  else {
734
- // CC v2.1.104 beta set context-1m excluded (requires Extra Usage enabled,
735
- // CC only adds it via coral_reef_sonnet feature flag which most accounts don't have)
736
- beta = 'claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,context-management-2025-06-27,prompt-caching-scope-2026-01-05,advisor-tool-2026-03-01,effort-2025-11-24';
734
+ // CC v2.1.104 beta set (exact 8 from MITM capture, exact order).
735
+ // context-1m requires Extra Usage if it 400s, we auto-retry without it.
736
+ beta = 'claude-code-20250219,oauth-2025-04-20,context-1m-2025-08-07,interleaved-thinking-2025-05-14,context-management-2025-06-27,prompt-caching-scope-2026-01-05,advisor-tool-2026-03-01,effort-2025-11-24';
737
737
  if (clientBeta) {
738
738
  const baseSet = new Set(beta.split(','));
739
739
  const filtered = filterBillableBetas(clientBeta)
@@ -761,12 +761,52 @@ export async function startProxy(opts = {}) {
761
761
  // CC sends 600 on first request per session. With rotation, every request is "first"
762
762
  'x-stainless-timeout': '600',
763
763
  };
764
- const upstream = await fetch(targetBase, {
764
+ let upstream = await fetch(targetBase, {
765
765
  method: req.method ?? 'POST',
766
766
  headers,
767
767
  body: finalBody ? new Uint8Array(finalBody) : undefined,
768
768
  signal: AbortSignal.timeout(UPSTREAM_TIMEOUT_MS),
769
769
  });
770
+ // Auto-retry without context-1m if it triggers a long-context billing error
771
+ if (upstream.status === 429 && !passthrough) {
772
+ const peekBody = await upstream.text().catch(() => '');
773
+ if (peekBody.includes('long context') || peekBody.includes('Extra usage is required')) {
774
+ if (verbose)
775
+ console.log(`[dario] #${requestCount} context-1m rejected — retrying without it`);
776
+ const reducedBeta = beta.replace(',context-1m-2025-08-07', '').replace('context-1m-2025-08-07,', '');
777
+ const retryHeaders = { ...headers, 'anthropic-beta': reducedBeta };
778
+ const retry = await fetch(targetBase, {
779
+ method: req.method ?? 'POST',
780
+ headers: retryHeaders,
781
+ body: finalBody ? new Uint8Array(finalBody) : undefined,
782
+ signal: AbortSignal.timeout(UPSTREAM_TIMEOUT_MS),
783
+ });
784
+ // Use the retry response from here on
785
+ upstream = retry;
786
+ }
787
+ else {
788
+ // Not a context-1m issue — handle as normal 429 below
789
+ // Re-wrap the already-consumed body for downstream handling
790
+ const enriched = enrich429(peekBody, upstream.headers);
791
+ if (!(cliAvailable && !useCli)) {
792
+ const responseHeaders = {
793
+ 'Content-Type': 'application/json',
794
+ 'Access-Control-Allow-Origin': corsOrigin,
795
+ ...SECURITY_HEADERS,
796
+ };
797
+ for (const [key, value] of upstream.headers.entries()) {
798
+ if (key.startsWith('x-ratelimit') || key.startsWith('anthropic-ratelimit') || key === 'request-id') {
799
+ responseHeaders[key] = value;
800
+ }
801
+ }
802
+ requestCount++;
803
+ res.writeHead(429, responseHeaders);
804
+ res.end(enriched);
805
+ return;
806
+ }
807
+ // Fall through to CLI fallback below
808
+ }
809
+ }
770
810
  // Enrich 429 errors with rate limit details from headers (Anthropic only returns "Error")
771
811
  if (upstream.status === 429 && !(cliAvailable && !useCli)) {
772
812
  const errBody = await upstream.text().catch(() => '');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "3.2.3",
3
+ "version": "3.2.5",
4
4
  "description": "Use your Claude subscription as an API. No API key needed. Local proxy for Claude Max/Pro subscriptions.",
5
5
  "type": "module",
6
6
  "bin": {