clauderipple 0.8.9 → 0.9.0
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 +62 -0
- package/README.es.md +0 -4
- package/README.ja.md +0 -4
- package/README.ko.md +5 -1
- package/README.md +5 -1
- package/README.pt-BR.md +0 -4
- package/README.zh-CN.md +0 -4
- package/dist/app/dist/main.js +23 -3
- package/dist/app/package.json +1 -1
- package/dist/cli/src/codex.js +3 -1
- package/dist/cli/src/index.js +1 -1
- package/dist/cli/src/settings.js +5 -2
- package/dist/cli/src/tray.js +41 -5
- package/dist/mod/.claude-plugin/plugin.json +9 -1
- package/dist/mod/hooks/cache.ts +60 -0
- package/dist/mod/hooks/compact.ts +40 -0
- package/dist/mod/hooks/handoff.ts +43 -0
- package/dist/mod/hooks/i18n.ts +2716 -0
- package/dist/mod/hooks/judge.ts +226 -0
- package/dist/mod/hooks/ladder.js +179 -0
- package/dist/mod/hooks/ladder.ts +174 -0
- package/dist/mod/hooks/modes.ts +93 -0
- package/dist/mod/hooks/register.tsx +1458 -256
- package/dist/mod/hooks/session.ts +62 -0
- package/dist/mod/hooks/settings.js +342 -0
- package/dist/mod/hooks/settings.ts +321 -0
- package/dist/mod/hooks/stats.ts +59 -0
- package/dist/mod/hooks/ui/agents.tsx +138 -0
- package/dist/mod/hooks/ui/alerts.tsx +370 -0
- package/dist/mod/hooks/ui/art.ts +628 -0
- package/dist/mod/hooks/ui/band.tsx +836 -0
- package/dist/mod/hooks/ui/kit.tsx +258 -0
- package/dist/mod/hooks/ui/log.tsx +109 -0
- package/dist/mod/hooks/ui/parts.tsx +217 -0
- package/dist/mod/hooks/ui/ripple.ts +614 -0
- package/dist/mod/hooks/ui/settings.tsx +376 -0
- package/dist/mod/hooks/ui/setup.tsx +148 -0
- package/dist/mod/hooks/ui/theme.ts +217 -0
- package/dist/mod/hooks/ui/view.ts +371 -0
- package/dist/mod/hooks/worker.ts +1 -1
- package/dist/mod/hooks/workers.ts +217 -0
- package/dist/mod/tests/register.test.tsx +1730 -0
- package/dist/mod/tests/ui.test.tsx +853 -0
- package/dist/mod/tsconfig.json +2 -1
- package/dist/mod/types/index.d.ts +320 -1
- package/dist/router/src/admin.js +195 -53
- package/dist/router/src/agents.js +24 -5
- package/dist/router/src/bootstrap.js +4 -2
- package/dist/router/src/compat.js +10 -2
- package/dist/router/src/config.js +3 -0
- package/dist/router/src/health.js +33 -0
- package/dist/router/src/index.js +1 -0
- package/dist/router/src/ingress/models.js +4 -1
- package/dist/router/src/mod-settings.js +119 -0
- package/dist/router/src/model-policy.js +6 -0
- package/dist/router/src/model-scores.js +159 -0
- package/dist/router/src/picker.js +7 -0
- package/dist/router/src/providers/anthropic-account-pool.js +10 -4
- package/dist/router/src/providers/anthropic-accounts.js +26 -1
- package/dist/router/src/providers/chatgpt/catalog.js +45 -14
- package/dist/router/src/providers/chatgpt/index.js +9 -3
- package/dist/router/src/providers/chatgpt/translate.js +9 -5
- package/dist/router/src/providers/google/index.js +6 -2
- package/dist/router/src/providers/openai/index.js +4 -1
- package/dist/router/src/providers/openai/translate.js +1 -1
- package/dist/router/src/proxy.js +14 -3
- package/dist/router/src/version.js +1 -1
- package/dist/ui/app.js +932 -209
- package/dist/ui/favicon-32.png +0 -0
- package/dist/ui/favicon.svg +12 -0
- package/dist/ui/i18n.js +923 -237
- package/dist/ui/index.html +159 -87
- package/dist/ui/style.css +789 -408
- package/docs/ARCHITECTURE.md +134 -2
- package/package.json +7 -3
package/dist/router/src/proxy.js
CHANGED
|
@@ -18,7 +18,7 @@ import https from "node:https";
|
|
|
18
18
|
import net from "node:net";
|
|
19
19
|
import tls from "node:tls";
|
|
20
20
|
import zlib from "node:zlib";
|
|
21
|
-
import { UpstreamHealth } from "./health.js";
|
|
21
|
+
import { ProviderHealth, providerExhaustion, UpstreamHealth } from "./health.js";
|
|
22
22
|
import { BOOTSTRAP_PATH, injectBootstrap } from "./bootstrap.js";
|
|
23
23
|
import { THREAD_UNSUPPORTED, effortOf, resolve, rewriteBody, stripThreadFields, threadDecision, unroutableReason } from "./routing.js";
|
|
24
24
|
import { defaultAgentDir, withAgentAliases } from "./agents.js";
|
|
@@ -32,7 +32,7 @@ import { OpenAiCompatibleAdapter } from "./providers/openai/index.js";
|
|
|
32
32
|
import { GoogleAdapter } from "./providers/google/index.js";
|
|
33
33
|
import { conversationKey } from "./providers/chatgpt/translate.js";
|
|
34
34
|
import { providerFor, searchProviderFor, terminateHosts } from "./config.js";
|
|
35
|
-
import { injectPickerModels, isBootstrapPath } from "./picker.js";
|
|
35
|
+
import { chatPickerModels, injectPickerModels, isBootstrapPath } from "./picker.js";
|
|
36
36
|
import { effortLevelsForModel } from "./admin.js";
|
|
37
37
|
import { ResponseUsageTap } from "./requestlog.js";
|
|
38
38
|
import { credentialHeaderValues, redactErrorText, redactHeaders } from "./redact.js";
|
|
@@ -198,6 +198,7 @@ export class Proxy {
|
|
|
198
198
|
* its quarantine again on the first request.
|
|
199
199
|
*/
|
|
200
200
|
pool = new CredentialPool();
|
|
201
|
+
providerHealth = new ProviderHealth();
|
|
201
202
|
/** Latest rate-limit snapshot reported by any chatgpt provider (for the admin GUI). */
|
|
202
203
|
get chatgptRateLimits() {
|
|
203
204
|
const out = {};
|
|
@@ -784,6 +785,8 @@ export class Proxy {
|
|
|
784
785
|
// The adapter reports each account's outcome to the shared pool itself, so a slot pointing
|
|
785
786
|
// here fails over once every account is out (chooseTarget asks the adapter).
|
|
786
787
|
const o = await this.chatgpt(route.provider, provider).handle(req, res, path, json, route.model, effortOf(json));
|
|
788
|
+
if (!path.startsWith("/v1/messages/count_tokens"))
|
|
789
|
+
this.providerHealth.observe(route.provider, o.status, o.exhaustion);
|
|
787
790
|
finish(String(o.status), o.bytes, o.note, o.status >= 400, { ...(o.usage ? { usage: o.usage } : {}), ...(o.stopReason ? { stopReason: o.stopReason } : {}) });
|
|
788
791
|
}
|
|
789
792
|
catch (e) {
|
|
@@ -813,6 +816,8 @@ export class Proxy {
|
|
|
813
816
|
try {
|
|
814
817
|
const o = await this.openai(route.provider, provider).handle(req, res, path, json, route.model, routeEffort);
|
|
815
818
|
this.recordOutcome(route.provider, o.status);
|
|
819
|
+
if (!path.startsWith("/v1/messages/count_tokens"))
|
|
820
|
+
this.providerHealth.observe(route.provider, o.status, o.exhaustion);
|
|
816
821
|
finish(String(o.status), o.bytes, o.note, o.status >= 400, { ...(o.usage ? { usage: o.usage } : {}), ...(o.stopReason ? { stopReason: o.stopReason } : {}) });
|
|
817
822
|
}
|
|
818
823
|
catch (e) {
|
|
@@ -845,6 +850,8 @@ export class Proxy {
|
|
|
845
850
|
try {
|
|
846
851
|
const o = await this.google(route.provider, provider).handle(req, res, path, json, route.model, routeEffort);
|
|
847
852
|
this.recordOutcome(route.provider, o.status);
|
|
853
|
+
if (!path.startsWith("/v1/messages/count_tokens"))
|
|
854
|
+
this.providerHealth.observe(route.provider, o.status, o.exhaustion);
|
|
848
855
|
finish(String(o.status), o.bytes, o.note, o.status >= 400, { ...(o.usage ? { usage: o.usage } : {}), ...(o.stopReason ? { stopReason: o.stopReason } : {}) });
|
|
849
856
|
}
|
|
850
857
|
catch (e) {
|
|
@@ -1274,7 +1281,7 @@ export class Proxy {
|
|
|
1274
1281
|
else if (status === 200 && isPickerBootstrap) {
|
|
1275
1282
|
try {
|
|
1276
1283
|
const j = JSON.parse(out.toString("utf8"));
|
|
1277
|
-
const r = injectPickerModels(j, cfg
|
|
1284
|
+
const r = injectPickerModels(j, chatPickerModels(cfg), cfg.cli.autoCompactWindow, (model) => effortLevelsForModel(cfg, model));
|
|
1278
1285
|
if (r.surfaces.length > 0) {
|
|
1279
1286
|
this.lastPickerInjection = { at: new Date().toISOString(), ...r };
|
|
1280
1287
|
out = Buffer.from(JSON.stringify(j));
|
|
@@ -1337,6 +1344,10 @@ export class Proxy {
|
|
|
1337
1344
|
observedUsage = observed.usage;
|
|
1338
1345
|
observedStopReason = observed.stopReason;
|
|
1339
1346
|
res.end();
|
|
1347
|
+
const errorBody = status >= 400 ? decodeBodyToText(Buffer.concat(errorHead), upRes.headers["content-encoding"]) : "";
|
|
1348
|
+
if (route && path.startsWith("/v1/messages") && !path.startsWith("/v1/messages/count_tokens")) {
|
|
1349
|
+
this.providerHealth.observe(route.provider, status, providerExhaustion(status, errorBody, retryAfterMs(upRes.headers)));
|
|
1350
|
+
}
|
|
1340
1351
|
const note = status >= 400 ? `upstream ${status}: ${errorSnippet(Buffer.concat(errorHead), upRes.headers["content-encoding"], [...errorSecrets], upRes.headers["content-type"])}` : undefined;
|
|
1341
1352
|
// Anthropic forgets a conversation's server-side thread after a few idle minutes, and the CLI
|
|
1342
1353
|
// answers the 404 by replaying the whole conversation, which hits the prompt cache. From CLI
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
// from the manifests. Until 0.1.1 the router and the CLI each carried their own literal, and both
|
|
6
6
|
// still said "0.1.0" in the 0.1.1 release: after an update nobody could tell which router was
|
|
7
7
|
// running, and the tray app had nothing to compare (2026-09-15, reported from a Windows install).
|
|
8
|
-
export const VERSION = "0.
|
|
8
|
+
export const VERSION = "0.9.0";
|