axstack 0.52.0 → 0.52.1
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "axstack",
|
|
3
|
-
"version": "0.52.
|
|
3
|
+
"version": "0.52.1",
|
|
4
4
|
"description": "Axstack installer and setup CLI: installs owned chat skills and role data, configures supported harness settings, and checks T3 Code capabilities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -51,7 +51,7 @@ remaining quota in every applicable window. Null or absent reset timing is valid
|
|
|
51
51
|
Claude session/weekly/scoped Opus and Codex windows. The adapter omits the missing
|
|
52
52
|
reset; it never invents a timestamp. Unknown reset timing alone does **not** mean
|
|
53
53
|
unused or not started: the reported used percentage still governs remaining quota,
|
|
54
|
-
same-account eligibility and
|
|
54
|
+
same-account eligibility and the primary-pool reserve, including exhaustion at 100% used.
|
|
55
55
|
For pressure, an untimed window earns zero elapsed-window credit, a conservative
|
|
56
56
|
lower bound, while its full reported usage is subtracted. `untimedWindows` reports
|
|
57
57
|
these windows (including relevant Opus scope); n/a session windows are separate.
|
|
@@ -65,11 +65,18 @@ A weekly-exhausted account contributes 100% session usage. Different resets stay
|
|
|
65
65
|
per account; T3 lists refill events scaled by member count, rather than inventing
|
|
66
66
|
one pool reset. An n/a session contributes neither a zero nor 100% observation;
|
|
67
67
|
only accounts with an applicable session enter its mean, and an all-n/a session
|
|
68
|
-
is reported as null with status n/a.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
is reported as null with status n/a. For each primary pool, remaining capacity is
|
|
69
|
+
its minimum applicable session/weekly unrounded pooled percentage; n/a is omitted.
|
|
70
|
+
Sol xhigh is eligible **only when both Opus and Astra pools have <30% remaining**.
|
|
71
|
+
Exactly 30% on either pool excludes Sol, even if it is the current default.
|
|
72
|
+
When both are low, choose Sol if its Codex accounts and catalog are eligible.
|
|
73
|
+
Otherwise choose eligible Opus medium/Astra medium, preferring a non-low primary
|
|
74
|
+
over a low primary before pacing or fairness. If only low primaries remain
|
|
75
|
+
available, use those; exhausted accounts never gain capacity. Scoped Opus limits
|
|
76
|
+
still constrain eligibility; an unavailable primary is not evidence of <30%.
|
|
77
|
+
Unknown telemetry or catalogs hold. There is no separate Astra reserve cutoff.
|
|
78
|
+
Percentages do not establish absolute tokens or relative subscription sizes.
|
|
79
|
+
Duplicate identities hold instead of adding capacity from overlapping sources.
|
|
73
80
|
|
|
74
81
|
Pressure is the worse session/weekly mean of elapsed-window percentage minus
|
|
75
82
|
used percentage, higher meaning more underused capacity. As in T3's pace display,
|
|
@@ -105,11 +112,11 @@ that period, not an immutable record of its original model; hard-deleted/pruned
|
|
|
105
112
|
records and manual model changes limit fidelity. The source/coverage is reported.
|
|
106
113
|
A supplied project-only list remains caller-scoped, not global history.
|
|
107
114
|
|
|
108
|
-
When history is unavailable, similarly pressured eligible
|
|
109
|
-
six-hour UTC slots in Opus/Astra
|
|
115
|
+
When history is unavailable, similarly pressured eligible primaries receive fixed
|
|
116
|
+
six-hour UTC slots in Opus/Astra order. Sol is selected only in the both-low case. The target is stable within a slot;
|
|
110
117
|
pressure hysteresis still protects a current default outside a fair tie. This
|
|
111
118
|
prevents indefinite starvation without timer state, a new database, per-tick
|
|
112
|
-
rotation, or any claim of equal chat counts.
|
|
119
|
+
rotation, or any claim of equal chat counts. Reserve eligibility always wins over fairness and hysteresis.
|
|
113
120
|
|
|
114
121
|
## Run or enable
|
|
115
122
|
|
|
@@ -97,9 +97,15 @@ export function decide(settings, snapshots, catalogs, now, history = null) {
|
|
|
97
97
|
}
|
|
98
98
|
const choices = candidates(settings, catalogs, now);
|
|
99
99
|
result.pools = Object.fromEntries(['claudeAgent', 'codex'].map((d) => [d, pool(all, d, now)]));
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
const low = (driver) => Math.min(...[result.pools[driver].sessionRemaining,
|
|
101
|
+
result.pools[driver].weeklyRemaining].filter((v) => v !== null)) < 30;
|
|
102
|
+
const available = choices.filter((c) => result.pools[c.driver].eligibleAccounts > 0);
|
|
103
|
+
const sol = available.filter((c) => c.selection.model === 'gpt-6.1-sol');
|
|
104
|
+
const primaries = available.filter((c) => c.selection.model !== 'gpt-6.1-sol');
|
|
105
|
+
const nonLow = primaries.filter((c) => !low(c.driver));
|
|
106
|
+
// Apply the reserve before pacing, fairness and hysteresis can retain a forbidden default.
|
|
107
|
+
const eligible = low('claudeAgent') && low('codex') && sol.length ? sol
|
|
108
|
+
: nonLow.length ? nonLow : primaries;
|
|
103
109
|
if (!eligible.length) throw Error('both pools exhausted; no account has both windows available');
|
|
104
110
|
const best = Math.max(...eligible.map((c) => result.pools[c.driver].score));
|
|
105
111
|
const tied = eligible.filter((c) => best - result.pools[c.driver].score <= 5);
|
|
@@ -118,8 +124,8 @@ export function decide(settings, snapshots, catalogs, now, history = null) {
|
|
|
118
124
|
}
|
|
119
125
|
if (!chosen && current && best - result.pools[current.driver].score < 10) {
|
|
120
126
|
// Fixed UTC slots prevent starvation without persistent timer state or per-tick rotation.
|
|
121
|
-
const rotation = Math.floor(now / (6 * 3600000)) %
|
|
122
|
-
const target = [...
|
|
127
|
+
const rotation = Math.floor(now / (6 * 3600000)) % eligible.length;
|
|
128
|
+
const target = [...eligible.slice(rotation), ...eligible.slice(0, rotation)].find((c) => tied.includes(c));
|
|
123
129
|
chosen = !counts && tied.includes(current) ? target : current;
|
|
124
130
|
}
|
|
125
131
|
if (!chosen) {
|