Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2082,6 +2082,18 @@ are rejected before changing settings. `standard` clears an explicit tier;
omitting speed leaves the session's current tier intact.
Codexometer ships no enabled profile and does not infer which model is cheaper.

When one or more steps are configured, Codexometer adds a **Thresholds** view
after **Resets** within **Quota**, in both the terminal and experimental web interface. It keeps
the complete policy visible in trigger order, including model, reasoning level,
speed and `ask`/`auto` behavior, and marks the active and next steps against the
longest Codex quota window. The tab is omitted entirely on ordinary launches;
saved Thresholds navigation falls back to Bars when no policy is
configured. Approvals remain attached to their individual sessions in
**Sessions** rather than being actioned from the policy overview.
`ACTIVE` identifies the selected policy, not confirmation that every session has
applied it; `PASSED` means a higher threshold now takes precedence. Scroll long
policies with the mouse wheel, arrow keys or Page Up/Down in the terminal.

The optional final mode defaults to **`ask`**, preserving per-session approval
for existing command lines. **`auto`** authorizes applying the profile at launch:
when the threshold is reached, each eligible loaded session is updated for its
Expand Down
54 changes: 54 additions & 0 deletions internal/codex/quota_profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,64 @@ import (
"context"
"errors"
"fmt"
"slices"
"sync"
"time"
)

type QuotaStepStage string

const (
QuotaStepConfigured QuotaStepStage = "CONFIGURED"
QuotaStepPassed QuotaStepStage = "PASSED"
QuotaStepActive QuotaStepStage = "ACTIVE"
QuotaStepNext QuotaStepStage = "NEXT"
QuotaStepArmed QuotaStepStage = "ARMED"
)

type QuotaStepStatus struct {
Step QuotaStep
Stage QuotaStepStage
Remaining int
}

// QuotaStepStatuses returns a stable, trigger-ordered policy projection for
// any presentation. The used percentage is nil until the policy window can be
// identified authoritatively.
func QuotaStepStatuses(s Snapshot, steps []QuotaStep) ([]QuotaStepStatus, *int) {
ordered := append([]QuotaStep(nil), steps...)
slices.SortStableFunc(ordered, func(a, b QuotaStep) int { return a.Threshold - b.Threshold })
used, active := -1, -1
if meter, _, ok := QuotaPolicyWindow(s); ok {
used = meter.Window.UsedPercent
for index, step := range ordered {
if step.Threshold <= used {
active = index
}
}
}
statuses := make([]QuotaStepStatus, 0, len(ordered))
for index, step := range ordered {
status := QuotaStepStatus{Step: step, Stage: QuotaStepArmed}
switch {
case used < 0:
status.Stage = QuotaStepConfigured
case index < active:
status.Stage = QuotaStepPassed
case index == active:
status.Stage = QuotaStepActive
case index == active+1:
status.Stage = QuotaStepNext
status.Remaining = max(step.Threshold-used, 0)
}
statuses = append(statuses, status)
}
if used < 0 {
return statuses, nil
}
return statuses, &used
}

// QuotaProfiles owns the policy lifecycle independently of either presentation.
// Its lock also serializes inventory and writes from browser tabs or UI commands.
type QuotaProfiles struct {
Expand Down
24 changes: 24 additions & 0 deletions internal/codex/quota_profiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,30 @@ func TestQuotaProfileCaptureAndSelection(t *testing.T) {
}
}

func TestQuotaStepStatusesAreSortedAndClassified(t *testing.T) {
s := DemoSnapshot()
s.AccountFingerprint = "account"
s.RateLimits.Secondary.UsedPercent = 65
statuses, used := QuotaStepStatuses(s, []QuotaStep{{Threshold: 90}, {Threshold: 25}, {Threshold: 80}, {Threshold: 50}})
want := []QuotaStepStage{QuotaStepPassed, QuotaStepActive, QuotaStepNext, QuotaStepArmed}
if used == nil || *used != 65 || len(statuses) != len(want) {
t.Fatalf("status summary = %#v, used=%v", statuses, used)
}
for index, stage := range want {
if statuses[index].Stage != stage {
t.Fatalf("status %d = %#v, want %s", index, statuses[index], stage)
}
}
if statuses[2].Remaining != 15 {
t.Fatalf("next remaining = %d", statuses[2].Remaining)
}

configured, used := QuotaStepStatuses(Snapshot{}, []QuotaStep{{Threshold: 80}})
if used != nil || configured[0].Stage != QuotaStepConfigured {
t.Fatalf("unobserved status = %#v, used=%v", configured, used)
}
}

func TestQuotaProfilesStaleAttemptConsumed(t *testing.T) {
c := &policyTestClient{}
p := NewQuotaProfiles(c)
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/da.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "TÆRSKLER",
"MODEL STEP POLICY": "POLITIK FOR MODELTRIN",
"QUOTA WINDOW UNAVAILABLE": "KVOTEVINDUE IKKE TILGÆNGELIGT",
"QUOTA WINDOW // %d%% USED": "KVOTEVINDUE // %d%% BRUGT",
"TRIGGER": "UDLØSER",
"ACTION": "HANDLING",
"STATE": "STATUS",
"ASK": "SPØRG",
"AUTO": "AUTO",
"ARMED": "KLAR",
"CONFIGURED": "KONFIGURERET",
"PASSED": "PASSERET",
"NEXT // %d PP": "NÆSTE // %d PP",
"WHY THIS CHANGE": "HVORFOR DENNE ÆNDRING",
"CURRENT PROFILE": "AKTUEL PROFIL",
"PROPOSED PROFILE": "FORESLÅET PROFIL",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/de.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "SCHWELLENWERTE",
"MODEL STEP POLICY": "MODELLSTUFENREGEL",
"QUOTA WINDOW UNAVAILABLE": "KONTINGENTFENSTER NICHT VERFÜGBAR",
"QUOTA WINDOW // %d%% USED": "KONTINGENTFENSTER // %d%% VERBRAUCHT",
"TRIGGER": "AUSLÖSER",
"ACTION": "AKTION",
"STATE": "STATUS",
"ASK": "FRAGEN",
"AUTO": "AUTO",
"ARMED": "BEREIT",
"CONFIGURED": "KONFIGURIERT",
"PASSED": "ÜBERSCHRITTEN",
"NEXT // %d PP": "NÄCHSTE // %d PP",
"WHY THIS CHANGE": "WARUM DIESE ÄNDERUNG",
"CURRENT PROFILE": "AKTUELLES PROFIL",
"PROPOSED PROFILE": "VORGESCHLAGENES PROFIL",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/en-GB.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "THRESHOLDS",
"MODEL STEP POLICY": "MODEL STEP POLICY",
"QUOTA WINDOW UNAVAILABLE": "QUOTA WINDOW UNAVAILABLE",
"QUOTA WINDOW // %d%% USED": "QUOTA WINDOW // %d%% USED",
"TRIGGER": "TRIGGER",
"ACTION": "ACTION",
"STATE": "STATE",
"ASK": "ASK",
"AUTO": "AUTO",
"ARMED": "ARMED",
"CONFIGURED": "CONFIGURED",
"PASSED": "PASSED",
"NEXT // %d PP": "NEXT // %d PP",
"WHY THIS CHANGE": "WHY THIS CHANGE",
"CURRENT PROFILE": "CURRENT PROFILE",
"PROPOSED PROFILE": "PROPOSED PROFILE",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/es.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "UMBRALES",
"MODEL STEP POLICY": "POLÍTICA DE CAMBIO DE MODELO",
"QUOTA WINDOW UNAVAILABLE": "VENTANA DE CUOTA NO DISPONIBLE",
"QUOTA WINDOW // %d%% USED": "VENTANA DE CUOTA // %d%% USADO",
"TRIGGER": "ACTIVACIÓN",
"ACTION": "ACCIÓN",
"STATE": "ESTADO",
"ASK": "PREGUNTAR",
"AUTO": "AUTO",
"ARMED": "PREPARADO",
"CONFIGURED": "CONFIGURADO",
"PASSED": "SUPERADO",
"NEXT // %d PP": "SIGUIENTE // %d PP",
"WHY THIS CHANGE": "MOTIVO DEL CAMBIO",
"CURRENT PROFILE": "PERFIL ACTUAL",
"PROPOSED PROFILE": "PERFIL PROPUESTO",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/et.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "LÄVENDID",
"MODEL STEP POLICY": "MUDELIASTMETE REEGEL",
"QUOTA WINDOW UNAVAILABLE": "KVOODIAKEN POLE SAADAVAL",
"QUOTA WINDOW // %d%% USED": "KVOODIAKEN // %d%% KASUTATUD",
"TRIGGER": "KÄIVITI",
"ACTION": "TOIMING",
"STATE": "OLEK",
"ASK": "KÜSI",
"AUTO": "AUTO",
"ARMED": "VALMIS",
"CONFIGURED": "SEADISTATUD",
"PASSED": "ÜLETATUD",
"NEXT // %d PP": "JÄRGMINE // %d PP",
"WHY THIS CHANGE": "MUUDATUSE PÕHJUS",
"CURRENT PROFILE": "PRAEGUNE PROFIIL",
"PROPOSED PROFILE": "SOOVITATUD PROFIIL",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/fi.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "KYNNYSARVOT",
"MODEL STEP POLICY": "MALLIPORRAIDEN KÄYTÄNTÖ",
"QUOTA WINDOW UNAVAILABLE": "KIINTIÖIKKUNA EI SAATAVILLA",
"QUOTA WINDOW // %d%% USED": "KIINTIÖIKKUNA // %d%% KÄYTETTY",
"TRIGGER": "LAUKAISIN",
"ACTION": "TOIMINTO",
"STATE": "TILA",
"ASK": "KYSY",
"AUTO": "AUTO",
"ARMED": "VALMIINA",
"CONFIGURED": "MÄÄRITETTY",
"PASSED": "OHITETTU",
"NEXT // %d PP": "SEURAAVA // %d PP",
"WHY THIS CHANGE": "MUUTOKSEN SYY",
"CURRENT PROFILE": "NYKYINEN PROFIILI",
"PROPOSED PROFILE": "EHDOTETTU PROFIILI",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/fr.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "SEUILS",
"MODEL STEP POLICY": "POLITIQUE DE PALIERS DE MODÈLE",
"QUOTA WINDOW UNAVAILABLE": "FENÊTRE DE QUOTA INDISPONIBLE",
"QUOTA WINDOW // %d%% USED": "FENÊTRE DE QUOTA // %d%% UTILISÉ",
"TRIGGER": "DÉCLENCHEUR",
"ACTION": "ACTION",
"STATE": "ÉTAT",
"ASK": "DEMANDER",
"AUTO": "AUTO",
"ARMED": "PRÊT",
"CONFIGURED": "CONFIGURÉ",
"PASSED": "DÉPASSÉ",
"NEXT // %d PP": "SUIVANT // %d PP",
"WHY THIS CHANGE": "POURQUOI CE CHANGEMENT",
"CURRENT PROFILE": "PROFIL ACTUEL",
"PROPOSED PROFILE": "PROFIL PROPOSÉ",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/it.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "SOGLIE",
"MODEL STEP POLICY": "CRITERI DI CAMBIO MODELLO",
"QUOTA WINDOW UNAVAILABLE": "FINESTRA QUOTA NON DISPONIBILE",
"QUOTA WINDOW // %d%% USED": "FINESTRA QUOTA // %d%% USATO",
"TRIGGER": "ATTIVAZIONE",
"ACTION": "AZIONE",
"STATE": "STATO",
"ASK": "CHIEDI",
"AUTO": "AUTO",
"ARMED": "PRONTO",
"CONFIGURED": "CONFIGURATO",
"PASSED": "SUPERATO",
"NEXT // %d PP": "PROSSIMO // %d PP",
"WHY THIS CHANGE": "PERCHÉ QUESTO CAMBIAMENTO",
"CURRENT PROFILE": "PROFILO ATTUALE",
"PROPOSED PROFILE": "PROFILO PROPOSTO",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/ja.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "しきい値",
"MODEL STEP POLICY": "モデル切替ポリシー",
"QUOTA WINDOW UNAVAILABLE": "クォータ期間を取得できません",
"QUOTA WINDOW // %d%% USED": "クォータ期間 // %d%% 使用",
"TRIGGER": "トリガー",
"ACTION": "動作",
"STATE": "状態",
"ASK": "確認",
"AUTO": "自動",
"ARMED": "待機",
"CONFIGURED": "設定済み",
"PASSED": "通過済み",
"NEXT // %d PP": "次 // %d PP",
"WHY THIS CHANGE": "変更の理由",
"CURRENT PROFILE": "現在のプロファイル",
"PROPOSED PROFILE": "提案するプロファイル",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/nb.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "TERSKLER",
"MODEL STEP POLICY": "REGLER FOR MODELLTRINN",
"QUOTA WINDOW UNAVAILABLE": "KVOTEVINDU IKKE TILGJENGELIG",
"QUOTA WINDOW // %d%% USED": "KVOTEVINDU // %d%% BRUKT",
"TRIGGER": "UTLØSER",
"ACTION": "HANDLING",
"STATE": "STATUS",
"ASK": "SPØR",
"AUTO": "AUTO",
"ARMED": "KLAR",
"CONFIGURED": "KONFIGURERT",
"PASSED": "PASSERT",
"NEXT // %d PP": "NESTE // %d PP",
"WHY THIS CHANGE": "HVORFOR DENNE ENDRINGEN",
"CURRENT PROFILE": "GJELDENDE PROFIL",
"PROPOSED PROFILE": "FORESLÅTT PROFIL",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/nl.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "DREMPELS",
"MODEL STEP POLICY": "BELEID VOOR MODELSTAPPEN",
"QUOTA WINDOW UNAVAILABLE": "QUOTAVENSTER NIET BESCHIKBAAR",
"QUOTA WINDOW // %d%% USED": "QUOTAVENSTER // %d%% GEBRUIKT",
"TRIGGER": "DREMPEL",
"ACTION": "ACTIE",
"STATE": "STATUS",
"ASK": "VRAGEN",
"AUTO": "AUTO",
"ARMED": "GEREED",
"CONFIGURED": "INGESTELD",
"PASSED": "GEPASSEERD",
"NEXT // %d PP": "VOLGENDE // %d PP",
"WHY THIS CHANGE": "WAAROM DEZE WIJZIGING",
"CURRENT PROFILE": "HUIDIG PROFIEL",
"PROPOSED PROFILE": "VOORGESTELD PROFIEL",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/pt-BR.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "LIMITES",
"MODEL STEP POLICY": "POLÍTICA DE ETAPAS DO MODELO",
"QUOTA WINDOW UNAVAILABLE": "JANELA DE COTA INDISPONÍVEL",
"QUOTA WINDOW // %d%% USED": "JANELA DE COTA // %d%% USADA",
"TRIGGER": "ACIONAMENTO",
"ACTION": "AÇÃO",
"STATE": "ESTADO",
"ASK": "PERGUNTAR",
"AUTO": "AUTO",
"ARMED": "PRONTO",
"CONFIGURED": "CONFIGURADO",
"PASSED": "ULTRAPASSADO",
"NEXT // %d PP": "PRÓXIMO // %d PP",
"WHY THIS CHANGE": "MOTIVO DA ALTERAÇÃO",
"CURRENT PROFILE": "PERFIL ATUAL",
"PROPOSED PROFILE": "PERFIL PROPOSTO",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/pt-PT.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "LIMITES",
"MODEL STEP POLICY": "POLÍTICA DE ETAPAS DO MODELO",
"QUOTA WINDOW UNAVAILABLE": "JANELA DE QUOTA INDISPONÍVEL",
"QUOTA WINDOW // %d%% USED": "JANELA DE QUOTA // %d%% UTILIZADA",
"TRIGGER": "ACIONAMENTO",
"ACTION": "AÇÃO",
"STATE": "ESTADO",
"ASK": "PERGUNTAR",
"AUTO": "AUTO",
"ARMED": "PRONTO",
"CONFIGURED": "CONFIGURADO",
"PASSED": "ULTRAPASSADO",
"NEXT // %d PP": "PRÓXIMO // %d PP",
"WHY THIS CHANGE": "MOTIVO DA ALTERAÇÃO",
"CURRENT PROFILE": "PERFIL ATUAL",
"PROPOSED PROFILE": "PERFIL PROPOSTO",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/ru.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "ПОРОГИ",
"MODEL STEP POLICY": "ПОЛИТИКА СМЕНЫ МОДЕЛИ",
"QUOTA WINDOW UNAVAILABLE": "ОКНО КВОТЫ НЕДОСТУПНО",
"QUOTA WINDOW // %d%% USED": "ОКНО КВОТЫ // %d%% ИСПОЛЬЗОВАНО",
"TRIGGER": "ПОРОГ",
"ACTION": "ДЕЙСТВИЕ",
"STATE": "СОСТОЯНИЕ",
"ASK": "СПРОСИТЬ",
"AUTO": "АВТО",
"ARMED": "ГОТОВО",
"CONFIGURED": "НАСТРОЕНО",
"PASSED": "ПРОЙДЕНО",
"NEXT // %d PP": "СЛЕДУЮЩИЙ // %d ПП",
"WHY THIS CHANGE": "ПРИЧИНА ИЗМЕНЕНИЯ",
"CURRENT PROFILE": "ТЕКУЩИЙ ПРОФИЛЬ",
"PROPOSED PROFILE": "ПРЕДЛАГАЕМЫЙ ПРОФИЛЬ",
Expand Down
13 changes: 13 additions & 0 deletions internal/i18n/locales/sv.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
{
"THRESHOLDS": "TRÖSKLAR",
"MODEL STEP POLICY": "POLICY FÖR MODELLSTEG",
"QUOTA WINDOW UNAVAILABLE": "KVOTFÖNSTER INTE TILLGÄNGLIGT",
"QUOTA WINDOW // %d%% USED": "KVOTFÖNSTER // %d%% ANVÄNT",
"TRIGGER": "UTLÖSARE",
"ACTION": "ÅTGÄRD",
"STATE": "STATUS",
"ASK": "FRÅGA",
"AUTO": "AUTO",
"ARMED": "REDO",
"CONFIGURED": "KONFIGURERAD",
"PASSED": "PASSERAD",
"NEXT // %d PP": "NÄSTA // %d PP",
"WHY THIS CHANGE": "VARFÖR DENNA ÄNDRING",
"CURRENT PROFILE": "AKTUELL PROFIL",
"PROPOSED PROFILE": "FÖRESLAGEN PROFIL",
Expand Down
Loading
Loading