zevairouter 1.0.150 → 1.0.152
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.
- package/CHANGELOG.md +13 -0
- package/cli/app/.next-cli-build/BUILD_ID +1 -1
- package/cli/app/.next-cli-build/app-path-routes-manifest.json +7 -7
- package/cli/app/.next-cli-build/build-manifest.json +2 -2
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/automation/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/context/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/terminal/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.html +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.html +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/api/combos/[id]/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/models/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/[jobId]/cancel/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/[jobId]/manual/[workerId]/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/[jobId]/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/latest/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/cancel/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/manual/[workerId]/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/latest/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/cancel/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/manual/[workerId]/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/latest/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/settings/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/v1/audio/speech/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/v1/embeddings/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/v1/images/generations/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/v1/search/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/v1/web/fetch/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/callback.html +1 -1
- package/cli/app/.next-cli-build/server/app/callback.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.html +1 -1
- package/cli/app/.next-cli-build/server/app/index.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/landing.html +1 -1
- package/cli/app/.next-cli-build/server/app/landing.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/login.html +1 -1
- package/cli/app/.next-cli-build/server/app/login.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app-paths-manifest.json +7 -7
- package/cli/app/.next-cli-build/server/chunks/1019.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/3155.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/3579.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/4566.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/4746.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/5000.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/5307.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/5949.js +3 -3
- package/cli/app/.next-cli-build/server/chunks/8306.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/8371.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/8895.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/9621.js +1 -1
- package/cli/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/pages/404.html +1 -1
- package/cli/app/.next-cli-build/server/pages/500.html +1 -1
- package/cli/app/.next-cli-build/static/chunks/{620-4698719a19477138.js → 620-51d6fc84653a20a0.js} +1 -1
- package/cli/app/CHANGELOG.md +13 -0
- package/cli/app/package.json +1 -1
- package/cli/package.json +1 -1
- package/open-sse/services/accountFallback.js +37 -0
- package/package.json +1 -1
- package/src/lib/oauth/services/bulkImportBrowserEngine.js +241 -32
- package/src/lib/oauth/services/codebuddyCnBulkImportManager.js +39 -34
- package/src/sse/services/auth.js +28 -7
- /package/cli/app/.next-cli-build/static/{STIs6ehtw793h3BxKhNWo → i-IN0_JUvDPX2TawfW0UV}/_buildManifest.js +0 -0
- /package/cli/app/.next-cli-build/static/{STIs6ehtw793h3BxKhNWo → i-IN0_JUvDPX2TawfW0UV}/_ssgManifest.js +0 -0
package/cli/app/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# v1.0.152 (2026-07-27)
|
|
2
|
+
|
|
3
|
+
## Fixes
|
|
4
|
+
- **Accurate Codex quota recovery**: a newer quota snapshot that explicitly reports capacity can now supersede a stale per-model lock instead of returning a false long-lived 429 while quota remains available.
|
|
5
|
+
- **Bounded recovery probes**: recovered accounts are retried once only when the quota snapshot is newer than the locking error; a fresh upstream failure immediately restores the lock and prevents retry loops.
|
|
6
|
+
|
|
7
|
+
# v1.0.151 (2026-07-27)
|
|
8
|
+
|
|
9
|
+
## Fixes
|
|
10
|
+
- **Deterministic DataImpulse sticky sessions**: CodeBuddy CN now initializes pasted proxies with sequential CN-accessible exit checks, preventing parallel first requests from racing sticky-port assignment and falsely reporting an immediate rotation.
|
|
11
|
+
- **Exit-aligned CloakBrowser identity**: the verified residential exit is applied directly to WebRTC, timezone, and locale flags instead of allowing failed foreign echo services to substitute the proxy gateway address.
|
|
12
|
+
- **Safe pre-purchase verification**: browser-context checks use the same sequential fallback order and compare the initial exit with the exit immediately before the 5sim purchase, without modifying pasted credentials or Proxy Pool data.
|
|
13
|
+
|
|
1
14
|
# v1.0.150 (2026-07-27)
|
|
2
15
|
|
|
3
16
|
## Fixes
|
package/cli/app/package.json
CHANGED
package/cli/package.json
CHANGED
|
@@ -53,6 +53,43 @@ export function getQuotaExhaustedUntil(usage) {
|
|
|
53
53
|
return getQuotaResetAt(usage);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Return true only when a quota snapshot explicitly says every known window
|
|
58
|
+
* still has capacity. Requiring all windows avoids treating an account with an
|
|
59
|
+
* exhausted weekly window as recovered just because its short window is open.
|
|
60
|
+
*/
|
|
61
|
+
export function hasAvailableQuota(usage) {
|
|
62
|
+
if (!usage || usage.limitReached === true) return false;
|
|
63
|
+
const quotas = Object.values(usage.quotas || {});
|
|
64
|
+
const remaining = quotas.map((quota) => {
|
|
65
|
+
if (Number.isFinite(quota?.remaining)) return quota.remaining;
|
|
66
|
+
if (Number.isFinite(quota?.remainingPercentage)) return quota.remainingPercentage;
|
|
67
|
+
return null;
|
|
68
|
+
}).filter((value) => value !== null);
|
|
69
|
+
|
|
70
|
+
return remaining.length > 0
|
|
71
|
+
&& remaining.length === quotas.length
|
|
72
|
+
&& remaining.every((value) => value > 0);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A successful quota poll newer than the error which created a model lock is
|
|
77
|
+
* authoritative evidence that a Codex account recovered. The caller may probe
|
|
78
|
+
* the account once; a fresh upstream failure updates lastErrorAt and makes the
|
|
79
|
+
* same snapshot too old to bypass the replacement lock.
|
|
80
|
+
*/
|
|
81
|
+
export function isModelLockRecoveredByQuota(connection, model, snapshot) {
|
|
82
|
+
if (!isModelLockActive(connection, model) || !hasAvailableQuota(snapshot?.usage)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const fetchedAt = Date.parse(snapshot?.fetchedAt);
|
|
87
|
+
const errorAt = Date.parse(connection?.lastErrorAt);
|
|
88
|
+
return Number.isFinite(fetchedAt)
|
|
89
|
+
&& Number.isFinite(errorAt)
|
|
90
|
+
&& fetchedAt > errorAt;
|
|
91
|
+
}
|
|
92
|
+
|
|
56
93
|
/**
|
|
57
94
|
* Calculate exponential backoff cooldown for rate limits (429)
|
|
58
95
|
* Level 1: 1s, Level 2: 2s, Level 3: 4s... → max 4 min
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
+
import net from "node:net";
|
|
4
|
+
import { ProxyAgent, fetch as undiciFetch } from "undici";
|
|
3
5
|
|
|
4
6
|
const requireFromHere = createRequire(import.meta.url);
|
|
5
7
|
|
|
@@ -14,6 +16,27 @@ export const DEFAULT_BULK_IMPORT_ENGINE = "cloakbrowser";
|
|
|
14
16
|
const SUPPORTED_ENGINES = new Set(["cloakbrowser"]);
|
|
15
17
|
const CLOAK_PROXY_PROFILES = new WeakMap();
|
|
16
18
|
|
|
19
|
+
export const PROXY_EGRESS_ECHO_URLS = Object.freeze([
|
|
20
|
+
"https://myip.ipip.net",
|
|
21
|
+
"https://ip.3322.net",
|
|
22
|
+
"https://cip.cc",
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
const PROXY_GEO_PROFILES = Object.freeze({
|
|
26
|
+
CN: { timezone: "Asia/Shanghai", locale: "zh-CN" },
|
|
27
|
+
HK: { timezone: "Asia/Hong_Kong", locale: "zh-HK" },
|
|
28
|
+
MO: { timezone: "Asia/Macau", locale: "zh-MO" },
|
|
29
|
+
TW: { timezone: "Asia/Taipei", locale: "zh-TW" },
|
|
30
|
+
SG: { timezone: "Asia/Singapore", locale: "en-SG" },
|
|
31
|
+
JP: { timezone: "Asia/Tokyo", locale: "ja-JP" },
|
|
32
|
+
KR: { timezone: "Asia/Seoul", locale: "ko-KR" },
|
|
33
|
+
US: { locale: "en-US" },
|
|
34
|
+
GB: { locale: "en-GB" },
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const DEFAULT_PROXY_PROBE_TIMEOUT_MS = 8_000;
|
|
38
|
+
const DEFAULT_PROXY_GEO_TIMEOUT_MS = 5_000;
|
|
39
|
+
|
|
17
40
|
export function normalizeBulkImportEngine(value) {
|
|
18
41
|
if (typeof value !== "string" || !value.trim()) return DEFAULT_BULK_IMPORT_ENGINE;
|
|
19
42
|
const lower = value.trim().toLowerCase();
|
|
@@ -208,6 +231,220 @@ export async function newStealthContext(browser, options = {}) {
|
|
|
208
231
|
return context;
|
|
209
232
|
}
|
|
210
233
|
|
|
234
|
+
export function parseProxyEgressIp(value) {
|
|
235
|
+
const raw = String(value || "").trim();
|
|
236
|
+
if (!raw) return null;
|
|
237
|
+
if (net.isIP(raw)) return raw;
|
|
238
|
+
|
|
239
|
+
try {
|
|
240
|
+
const parsed = JSON.parse(raw);
|
|
241
|
+
for (const key of ["ip", "query", "address", "origin"]) {
|
|
242
|
+
const candidate = String(parsed?.[key] || "").trim();
|
|
243
|
+
if (net.isIP(candidate)) return candidate;
|
|
244
|
+
}
|
|
245
|
+
} catch {
|
|
246
|
+
// Plain-text echo services are expected here.
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
for (const match of raw.matchAll(/(?:\d{1,3}\.){3}\d{1,3}/g)) {
|
|
250
|
+
if (net.isIP(match[0])) return match[0];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const tokens = raw.split(/[\s,;()[\]{}<>"'=\uFF1A]+/);
|
|
254
|
+
for (const token of tokens) {
|
|
255
|
+
const candidate = token.replace(/^[^0-9a-f:]+|[^0-9a-f:]+$/gi, "");
|
|
256
|
+
if (candidate.includes(":") && net.isIP(candidate)) return candidate;
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function inferProxyRegionalProfile(proxyUrl) {
|
|
262
|
+
try {
|
|
263
|
+
const parsed = new URL(String(proxyUrl || "").trim());
|
|
264
|
+
const username = decodeURIComponent(parsed.username || "");
|
|
265
|
+
const matches = [...username.matchAll(/(?:^|__)cr\.([a-z]{2})(?=__|$)/gi)];
|
|
266
|
+
const countryCode = matches.at(-1)?.[1]?.toUpperCase() || null;
|
|
267
|
+
const regional = countryCode ? PROXY_GEO_PROFILES[countryCode] : null;
|
|
268
|
+
return regional?.timezone && regional?.locale
|
|
269
|
+
? { countryCode, ...regional, source: "proxy-country" }
|
|
270
|
+
: null;
|
|
271
|
+
} catch {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async function closeProxyAgent(agent) {
|
|
277
|
+
if (!agent) return;
|
|
278
|
+
if (typeof agent.close === "function") {
|
|
279
|
+
await Promise.resolve(agent.close()).catch(() => null);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (typeof agent.destroy === "function") {
|
|
283
|
+
await Promise.resolve(agent.destroy()).catch(() => null);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Pin a fresh sticky proxy with one request at a time. Parallel first-use
|
|
289
|
+
* requests can race session assignment on providers such as DataImpulse.
|
|
290
|
+
*/
|
|
291
|
+
export async function probeProxyEgressBeforeLaunch(
|
|
292
|
+
proxyUrl,
|
|
293
|
+
{
|
|
294
|
+
timeoutMs = DEFAULT_PROXY_PROBE_TIMEOUT_MS,
|
|
295
|
+
urls = PROXY_EGRESS_ECHO_URLS,
|
|
296
|
+
fetchImpl = undiciFetch,
|
|
297
|
+
createProxyAgent = (url) => new ProxyAgent(url),
|
|
298
|
+
} = {},
|
|
299
|
+
) {
|
|
300
|
+
let agent = null;
|
|
301
|
+
const attemptedUrls = [];
|
|
302
|
+
let lastError = null;
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
try {
|
|
306
|
+
agent = createProxyAgent(proxyUrl);
|
|
307
|
+
} catch {
|
|
308
|
+
return {
|
|
309
|
+
ok: false,
|
|
310
|
+
ip: null,
|
|
311
|
+
url: null,
|
|
312
|
+
attempts: 0,
|
|
313
|
+
attemptedUrls,
|
|
314
|
+
error: "proxy agent setup failed",
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
for (const url of urls) {
|
|
319
|
+
attemptedUrls.push(url);
|
|
320
|
+
try {
|
|
321
|
+
const response = await fetchImpl(url, {
|
|
322
|
+
dispatcher: agent,
|
|
323
|
+
redirect: "follow",
|
|
324
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
325
|
+
headers: {
|
|
326
|
+
Accept: "text/plain, application/json;q=0.9, */*;q=0.1",
|
|
327
|
+
"Cache-Control": "no-cache",
|
|
328
|
+
},
|
|
329
|
+
});
|
|
330
|
+
if (!response?.ok) {
|
|
331
|
+
lastError = `HTTP ${response?.status || 0}`;
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
const ip = parseProxyEgressIp(await response.text());
|
|
335
|
+
if (!ip) {
|
|
336
|
+
lastError = "exit-IP response was not recognized";
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
ok: true,
|
|
341
|
+
ip,
|
|
342
|
+
url,
|
|
343
|
+
attempts: attemptedUrls.length,
|
|
344
|
+
attemptedUrls,
|
|
345
|
+
error: null,
|
|
346
|
+
};
|
|
347
|
+
} catch (error) {
|
|
348
|
+
lastError = error?.name === "TimeoutError"
|
|
349
|
+
? `timed out after ${timeoutMs}ms`
|
|
350
|
+
: "request failed";
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return {
|
|
355
|
+
ok: false,
|
|
356
|
+
ip: null,
|
|
357
|
+
url: null,
|
|
358
|
+
attempts: attemptedUrls.length,
|
|
359
|
+
attemptedUrls,
|
|
360
|
+
error: lastError || "all exit-IP services failed",
|
|
361
|
+
};
|
|
362
|
+
} finally {
|
|
363
|
+
await closeProxyAgent(agent);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async function lookupProxyGeoProfile(
|
|
368
|
+
egressIp,
|
|
369
|
+
{ timeoutMs = DEFAULT_PROXY_GEO_TIMEOUT_MS, fetchImpl = undiciFetch } = {},
|
|
370
|
+
) {
|
|
371
|
+
try {
|
|
372
|
+
const response = await fetchImpl(`https://ipwho.is/${encodeURIComponent(egressIp)}`, {
|
|
373
|
+
redirect: "follow",
|
|
374
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
375
|
+
headers: { Accept: "application/json" },
|
|
376
|
+
});
|
|
377
|
+
if (!response?.ok) return null;
|
|
378
|
+
const data = await response.json();
|
|
379
|
+
if (data?.success === false) return null;
|
|
380
|
+
const countryCode = String(data?.country_code || "").trim().toUpperCase();
|
|
381
|
+
const timezone = String(data?.timezone?.id || "").trim();
|
|
382
|
+
const locale = PROXY_GEO_PROFILES[countryCode]?.locale
|
|
383
|
+
|| (countryCode ? `en-${countryCode}` : "");
|
|
384
|
+
return timezone && locale
|
|
385
|
+
? { countryCode: countryCode || null, timezone, locale, source: "ip-geo" }
|
|
386
|
+
: null;
|
|
387
|
+
} catch {
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export async function resolveProxyLaunchProfile(proxyUrl, options = {}) {
|
|
393
|
+
const probe = await probeProxyEgressBeforeLaunch(proxyUrl, options);
|
|
394
|
+
if (!probe.ok || !probe.ip) {
|
|
395
|
+
const error = new Error(
|
|
396
|
+
`Manual proxy exit IP could not be verified before browser launch (${probe.error || "no response"}); no phone number was purchased`,
|
|
397
|
+
);
|
|
398
|
+
error.code = "CLOAKBROWSER_PROXY_EGRESS_UNAVAILABLE";
|
|
399
|
+
throw error;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const regional = inferProxyRegionalProfile(proxyUrl)
|
|
403
|
+
|| await lookupProxyGeoProfile(probe.ip, options);
|
|
404
|
+
if (!regional?.timezone || !regional?.locale) {
|
|
405
|
+
const error = new Error(
|
|
406
|
+
"Manual proxy region could not be aligned with CloakBrowser; no phone number was purchased",
|
|
407
|
+
);
|
|
408
|
+
error.code = "CLOAKBROWSER_PROXY_GEOIP_UNAVAILABLE";
|
|
409
|
+
throw error;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return Object.freeze({
|
|
413
|
+
egressIp: probe.ip,
|
|
414
|
+
timezone: regional.timezone,
|
|
415
|
+
locale: regional.locale,
|
|
416
|
+
countryCode: regional.countryCode || null,
|
|
417
|
+
source: regional.source,
|
|
418
|
+
probeUrl: probe.url,
|
|
419
|
+
probeAttempts: probe.attempts,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
export function buildVerifiedProxyLaunchOptions(launchOpts, proxyProfile) {
|
|
424
|
+
const managedPrefixes = [
|
|
425
|
+
"--fingerprint-webrtc-ip=",
|
|
426
|
+
"--fingerprint-timezone=",
|
|
427
|
+
"--fingerprint-locale=",
|
|
428
|
+
"--lang=",
|
|
429
|
+
];
|
|
430
|
+
const args = (launchOpts?.args || []).filter(
|
|
431
|
+
(arg) => !managedPrefixes.some((prefix) => String(arg).startsWith(prefix)),
|
|
432
|
+
);
|
|
433
|
+
args.push(
|
|
434
|
+
`--fingerprint-webrtc-ip=${proxyProfile.egressIp}`,
|
|
435
|
+
`--fingerprint-timezone=${proxyProfile.timezone}`,
|
|
436
|
+
`--lang=${proxyProfile.locale}`,
|
|
437
|
+
`--fingerprint-locale=${proxyProfile.locale}`,
|
|
438
|
+
);
|
|
439
|
+
return {
|
|
440
|
+
...launchOpts,
|
|
441
|
+
args,
|
|
442
|
+
timezone: proxyProfile.timezone,
|
|
443
|
+
locale: proxyProfile.locale,
|
|
444
|
+
geoip: false,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
|
|
211
448
|
/**
|
|
212
449
|
* CloakBrowser — sole bulk-import engine (patched stealth Chromium).
|
|
213
450
|
* Prefer headed (headless=false); Turnstile / Google bot checks often fail headless.
|
|
@@ -292,38 +529,10 @@ async function launchCloakbrowser({
|
|
|
292
529
|
let effectiveLaunchOpts = launchOpts;
|
|
293
530
|
let proxyProfile = null;
|
|
294
531
|
if (proxyUrl && requireProxyGeoip) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
// Slow residential CONNECT handshakes regularly exceed CloakBrowser's 5s
|
|
301
|
-
// default. Resolve once with a bounded 12s budget, then reuse those flags.
|
|
302
|
-
const previousGeoipTimeout = process.env.CLOAKBROWSER_GEOIP_TIMEOUT_SECONDS;
|
|
303
|
-
if (!previousGeoipTimeout) process.env.CLOAKBROWSER_GEOIP_TIMEOUT_SECONDS = "12";
|
|
304
|
-
let resolved;
|
|
305
|
-
try {
|
|
306
|
-
resolved = await cloak.buildLaunchOptions(launchOpts);
|
|
307
|
-
} finally {
|
|
308
|
-
if (previousGeoipTimeout === undefined) {
|
|
309
|
-
delete process.env.CLOAKBROWSER_GEOIP_TIMEOUT_SECONDS;
|
|
310
|
-
} else {
|
|
311
|
-
process.env.CLOAKBROWSER_GEOIP_TIMEOUT_SECONDS = previousGeoipTimeout;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
proxyProfile = extractCloakProxyProfile(resolved?.args || []);
|
|
315
|
-
if (!proxyProfile.egressIp || !proxyProfile.timezone || !proxyProfile.locale) {
|
|
316
|
-
const error = new Error(
|
|
317
|
-
"Manual proxy exit GeoIP could not be verified; no phone number was purchased",
|
|
318
|
-
);
|
|
319
|
-
error.code = "CLOAKBROWSER_PROXY_GEOIP_UNAVAILABLE";
|
|
320
|
-
throw error;
|
|
321
|
-
}
|
|
322
|
-
effectiveLaunchOpts = {
|
|
323
|
-
...launchOpts,
|
|
324
|
-
args: resolved.args || launchOpts.args,
|
|
325
|
-
geoip: false,
|
|
326
|
-
};
|
|
532
|
+
// Resolve the exit ourselves through CN-accessible endpoints. CloakBrowser's
|
|
533
|
+
// foreign echo fallbacks can time out and mistake the gateway IP for the exit.
|
|
534
|
+
proxyProfile = await resolveProxyLaunchProfile(proxyUrl);
|
|
535
|
+
effectiveLaunchOpts = buildVerifiedProxyLaunchOptions(launchOpts, proxyProfile);
|
|
327
536
|
}
|
|
328
537
|
|
|
329
538
|
try {
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import { randomUUID } from "crypto";
|
|
21
|
-
import net from "node:net";
|
|
22
21
|
import {
|
|
23
22
|
KiroBulkImportManager,
|
|
24
23
|
buildLookupResponse,
|
|
@@ -44,6 +43,8 @@ import {
|
|
|
44
43
|
import {
|
|
45
44
|
forceCloseBrowser,
|
|
46
45
|
getCloakProxyProfile,
|
|
46
|
+
parseProxyEgressIp,
|
|
47
|
+
PROXY_EGRESS_ECHO_URLS,
|
|
47
48
|
} from "./bulkImportBrowserEngine.js";
|
|
48
49
|
|
|
49
50
|
const CODEBUDDY_CN_PROVIDER_ID = "codebuddy-cn";
|
|
@@ -89,11 +90,6 @@ const CODEBUDDY_CN_FIVESIM_SETTLE_TIMEOUT_MS = 12_000;
|
|
|
89
90
|
const CODEBUDDY_CN_EGRESS_PROBE_TIMEOUT_MS = 6_000;
|
|
90
91
|
const CODEBUDDY_CN_API_KEY_OUTCOME_UNKNOWN = "CN_API_KEY_OUTCOME_UNKNOWN";
|
|
91
92
|
const CODEBUDDY_CN_ACCOUNT_RESTRICTED = "CN_ACCOUNT_RESTRICTED";
|
|
92
|
-
const CODEBUDDY_CN_EGRESS_ECHO_URLS = [
|
|
93
|
-
"https://api.ipify.org",
|
|
94
|
-
"https://checkip.amazonaws.com",
|
|
95
|
-
"https://ifconfig.me/ip",
|
|
96
|
-
];
|
|
97
93
|
|
|
98
94
|
// Supported 5sim regions
|
|
99
95
|
const SUPPORTED_REGIONS = new Set(["hongkong", "china", "any"]);
|
|
@@ -142,15 +138,7 @@ function resolveCnJobConcurrency(value, { manualProxy = false } = {}) {
|
|
|
142
138
|
}
|
|
143
139
|
|
|
144
140
|
function parseEgressIp(value) {
|
|
145
|
-
|
|
146
|
-
if (net.isIP(raw)) return raw;
|
|
147
|
-
try {
|
|
148
|
-
const parsed = JSON.parse(raw);
|
|
149
|
-
const ip = String(parsed?.ip || parsed?.query || "").trim();
|
|
150
|
-
return net.isIP(ip) ? ip : null;
|
|
151
|
-
} catch {
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
141
|
+
return parseProxyEgressIp(value);
|
|
154
142
|
}
|
|
155
143
|
|
|
156
144
|
async function probeCodeBuddyProxyEgress(
|
|
@@ -167,7 +155,10 @@ async function probeCodeBuddyProxyEgress(
|
|
|
167
155
|
return { ok: false, ip: null, ips: [], samples: 0, error: "context request unavailable" };
|
|
168
156
|
}
|
|
169
157
|
|
|
170
|
-
const
|
|
158
|
+
const attemptedUrls = [];
|
|
159
|
+
let lastError = null;
|
|
160
|
+
for (const url of PROXY_EGRESS_ECHO_URLS) {
|
|
161
|
+
attemptedUrls.push(url);
|
|
171
162
|
let response = null;
|
|
172
163
|
try {
|
|
173
164
|
response = await requestContext.get(url, {
|
|
@@ -178,30 +169,44 @@ async function probeCodeBuddyProxyEgress(
|
|
|
178
169
|
"Cache-Control": "no-cache",
|
|
179
170
|
},
|
|
180
171
|
});
|
|
181
|
-
if (response.status() < 200 || response.status() >= 300)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
172
|
+
if (response.status() < 200 || response.status() >= 300) {
|
|
173
|
+
lastError = `HTTP ${response.status()}`;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const ip = parseEgressIp(await response.text().catch(() => ""));
|
|
177
|
+
if (!ip) {
|
|
178
|
+
lastError = "exit-IP response was not recognized";
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
ok: true,
|
|
183
|
+
ip,
|
|
184
|
+
ips: [ip],
|
|
185
|
+
samples: 1,
|
|
186
|
+
attempts: attemptedUrls.length,
|
|
187
|
+
attemptedUrls,
|
|
188
|
+
unstable: false,
|
|
189
|
+
error: null,
|
|
190
|
+
};
|
|
191
|
+
} catch (error) {
|
|
192
|
+
lastError = error?.name === "TimeoutError"
|
|
193
|
+
? `timed out after ${timeoutMs}ms`
|
|
194
|
+
: "request failed";
|
|
185
195
|
} finally {
|
|
186
196
|
if (typeof response?.dispose === "function") {
|
|
187
197
|
await Promise.resolve(response.dispose()).catch(() => null);
|
|
188
198
|
}
|
|
189
199
|
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const successful = results.filter(Boolean);
|
|
193
|
-
const ips = [...new Set(successful)];
|
|
200
|
+
}
|
|
194
201
|
return {
|
|
195
|
-
ok:
|
|
196
|
-
ip:
|
|
197
|
-
ips,
|
|
198
|
-
samples:
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
? `proxy returned ${ips.length} exit IPs in one probe`
|
|
204
|
-
: null,
|
|
202
|
+
ok: false,
|
|
203
|
+
ip: null,
|
|
204
|
+
ips: [],
|
|
205
|
+
samples: 0,
|
|
206
|
+
attempts: attemptedUrls.length,
|
|
207
|
+
attemptedUrls,
|
|
208
|
+
unstable: false,
|
|
209
|
+
error: lastError || "all exit-IP services failed",
|
|
205
210
|
};
|
|
206
211
|
}
|
|
207
212
|
|
package/src/sse/services/auth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getProviderConnections, validateApiKey, updateProviderConnection, getSettings, getQuotaSnapshot, getAllQuotaSnapshots, getProxyPools } from "@/lib/localDb";
|
|
2
2
|
import { resolveConnectionProxyConfig, pickProxyPoolId } from "@/lib/network/connectionProxy";
|
|
3
|
-
import { formatRetryAfter, checkFallbackError, isModelLockActive, buildModelLockUpdate, getEarliestModelLockUntil, isNonAccountError, extractProviderErrorCode, getQuotaResetAt, getQuotaExhaustedUntil } from "open-sse/services/accountFallback.js";
|
|
3
|
+
import { formatRetryAfter, checkFallbackError, isModelLockActive, isModelLockRecoveredByQuota, buildModelLockUpdate, getEarliestModelLockUntil, isNonAccountError, extractProviderErrorCode, getQuotaResetAt, getQuotaExhaustedUntil } from "open-sse/services/accountFallback.js";
|
|
4
4
|
import { MAX_RATE_LIMIT_COOLDOWN_MS } from "open-sse/config/errorConfig.js";
|
|
5
5
|
import { resolveProviderId, FREE_PROVIDERS } from "@/shared/constants/providers.js";
|
|
6
6
|
import * as log from "../utils/logger.js";
|
|
@@ -77,9 +77,29 @@ export async function getProviderCredentials(provider, excludeConnectionIds = nu
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
// Codex can return a precise usage-limit reset which creates a long-lived
|
|
81
|
+
// model lock. If a newer quota poll explicitly reports capacity again, let
|
|
82
|
+
// that account be probed once instead of serving a stale all-rate-limited
|
|
83
|
+
// response until the old reset timestamp. A new failure is newer than the
|
|
84
|
+
// snapshot, so it immediately restores the lock without a retry loop.
|
|
85
|
+
const recoveredModelLocks = new Set();
|
|
86
|
+
if (providerId === "codex" && model) {
|
|
87
|
+
const snapshots = await getAllQuotaSnapshots(providerId);
|
|
88
|
+
const byConnection = new Map(snapshots.map((snapshot) => [snapshot.connectionId, snapshot]));
|
|
89
|
+
for (const connection of connections) {
|
|
90
|
+
if (isModelLockRecoveredByQuota(connection, model, byConnection.get(connection.id))) {
|
|
91
|
+
recoveredModelLocks.add(connection.id);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const hasBlockingModelLock = (connection) => (
|
|
97
|
+
isModelLockActive(connection, model) && !recoveredModelLocks.has(connection.id)
|
|
98
|
+
);
|
|
99
|
+
|
|
80
100
|
const baseAvailableConnections = connections.filter(c => {
|
|
81
101
|
if (excludeSet.has(c.id)) return false;
|
|
82
|
-
if (
|
|
102
|
+
if (hasBlockingModelLock(c)) return false;
|
|
83
103
|
if (quotaExhausted.has(c.id)) return false;
|
|
84
104
|
return true;
|
|
85
105
|
});
|
|
@@ -98,7 +118,7 @@ export async function getProviderCredentials(provider, excludeConnectionIds = nu
|
|
|
98
118
|
log.warn("AUTH", `${provider} | pinned account excluded after failure: ${preferred.id?.slice(0, 8)}`);
|
|
99
119
|
return null;
|
|
100
120
|
}
|
|
101
|
-
if (
|
|
121
|
+
if (hasBlockingModelLock(preferred) || quotaExhausted.has(preferred.id)) {
|
|
102
122
|
const retryAfter = [
|
|
103
123
|
getEarliestModelLockUntil(preferred),
|
|
104
124
|
quotaExhausted.has(preferred.id)
|
|
@@ -119,17 +139,18 @@ export async function getProviderCredentials(provider, excludeConnectionIds = nu
|
|
|
119
139
|
log.debug("AUTH", `${provider} | available: ${availableConnections.length}/${connections.length}`);
|
|
120
140
|
connections.forEach(c => {
|
|
121
141
|
const excluded = excludeSet.has(c.id);
|
|
122
|
-
const locked =
|
|
142
|
+
const locked = hasBlockingModelLock(c);
|
|
143
|
+
const recovered = recoveredModelLocks.has(c.id);
|
|
123
144
|
const exhaustedUntil = quotaExhausted.get(c.id);
|
|
124
|
-
if (excluded || locked || exhaustedUntil) {
|
|
145
|
+
if (excluded || locked || exhaustedUntil || recovered) {
|
|
125
146
|
const lockUntil = getEarliestModelLockUntil(c);
|
|
126
|
-
log.debug("AUTH", ` \u2192 ${c.id?.slice(0, 8)} | ${excluded ? "excluded" : ""} ${locked ? `modelLocked(${model}) until ${lockUntil}` : ""} ${exhaustedUntil ? `quotaExhausted until ${new Date(exhaustedUntil).toISOString()}` : ""}`);
|
|
147
|
+
log.debug("AUTH", ` \u2192 ${c.id?.slice(0, 8)} | ${excluded ? "excluded" : ""} ${locked ? `modelLocked(${model}) until ${lockUntil}` : ""} ${recovered ? `staleLockRecovered(${model})` : ""} ${exhaustedUntil ? `quotaExhausted until ${new Date(exhaustedUntil).toISOString()}` : ""}`);
|
|
127
148
|
}
|
|
128
149
|
});
|
|
129
150
|
|
|
130
151
|
if (availableConnections.length === 0) {
|
|
131
152
|
// Find earliest lock expiry across all connections for retry timing
|
|
132
|
-
const lockedConns = connections.filter(c =>
|
|
153
|
+
const lockedConns = connections.filter(c => hasBlockingModelLock(c));
|
|
133
154
|
const expiries = [
|
|
134
155
|
...lockedConns.map(c => getEarliestModelLockUntil(c)).filter(Boolean),
|
|
135
156
|
...quotaExhausted.values().map(timestamp => new Date(timestamp).toISOString()),
|
|
File without changes
|
|
File without changes
|