sidekick-shared 0.21.4 → 0.21.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.
- package/dist/codexQuota.js +24 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10 -8
- package/dist/parsers/codexParser.d.ts +1 -0
- package/dist/parsers/codexParser.js +15 -2
- package/dist/quotaSnapshots.js +10 -0
- package/dist/schemas/assistantTurn.d.ts +2 -2
- package/dist/schemas/sessionEvent.d.ts +1 -1
- package/dist/types/codex.d.ts +9 -0
- package/dist/types/codex.js +12 -0
- package/package.json +1 -1
package/dist/codexQuota.js
CHANGED
|
@@ -44,6 +44,7 @@ const codexProfiles_1 = require("./codexProfiles");
|
|
|
44
44
|
const quotaSnapshots_1 = require("./quotaSnapshots");
|
|
45
45
|
const quota_1 = require("./quota");
|
|
46
46
|
const codex_1 = require("./providers/codex");
|
|
47
|
+
const codex_2 = require("./types/codex");
|
|
47
48
|
const DEFAULT_TAIL_BYTES = 2 * 1024 * 1024;
|
|
48
49
|
const DEFAULT_MAX_SESSION_FILES = 50;
|
|
49
50
|
const CHATGPT_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage';
|
|
@@ -54,11 +55,19 @@ function timestampMs(value, fallbackMs = 0) {
|
|
|
54
55
|
return Number.isFinite(ms) ? ms : fallbackMs;
|
|
55
56
|
}
|
|
56
57
|
// Codex can report slightly different percentages for the same reset window
|
|
57
|
-
// across recent sessions. Prefer
|
|
58
|
-
//
|
|
58
|
+
// across recent sessions. Prefer the aggregate plan family ("codex") over
|
|
59
|
+
// model/feature-specific families (which can read 0% while the plan is busy),
|
|
60
|
+
// then newer reset windows, then the highest observed same-window utilization so
|
|
61
|
+
// local fallbacks do not under-report quota usage.
|
|
59
62
|
function isPreferredQuotaHit(candidate, current) {
|
|
60
63
|
if (!current)
|
|
61
64
|
return true;
|
|
65
|
+
// Family rank first: an aggregate hit always outranks a model-specific one, so a
|
|
66
|
+
// freshly-used per-model family (e.g. codex_bengalfox at 0%) can never mask the plan quota.
|
|
67
|
+
const candidateAggregate = (0, codex_2.isAggregateCodexLimit)(candidate.quota.limitId);
|
|
68
|
+
const currentAggregate = (0, codex_2.isAggregateCodexLimit)(current.quota.limitId);
|
|
69
|
+
if (candidateAggregate !== currentAggregate)
|
|
70
|
+
return candidateAggregate;
|
|
62
71
|
const candidatePrimaryReset = timestampMs(candidate.quota.fiveHour.resetsAt);
|
|
63
72
|
const currentPrimaryReset = timestampMs(current.quota.fiveHour.resetsAt);
|
|
64
73
|
if (candidatePrimaryReset !== currentPrimaryReset)
|
|
@@ -464,7 +473,11 @@ function readLatestQuotaFromRollout(sessionPath, maxTailBytes, source) {
|
|
|
464
473
|
const firstNewline = text.indexOf('\n');
|
|
465
474
|
text = firstNewline >= 0 ? text.slice(firstNewline + 1) : '';
|
|
466
475
|
}
|
|
476
|
+
// Scan from the end for the latest aggregate ("codex") rate-limit sample, which
|
|
477
|
+
// is what the plan quota represents. Keep the latest sample of any family as a
|
|
478
|
+
// fallback so a model-only session still surfaces something.
|
|
467
479
|
const lines = text.split('\n');
|
|
480
|
+
let fallback = null;
|
|
468
481
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
469
482
|
const line = lines[i].trim();
|
|
470
483
|
if (!line || !line.includes('rate_limits'))
|
|
@@ -474,13 +487,20 @@ function readLatestQuotaFromRollout(sessionPath, maxTailBytes, source) {
|
|
|
474
487
|
if (parsed.type !== 'event_msg' || parsed.payload?.type !== 'token_count')
|
|
475
488
|
continue;
|
|
476
489
|
const quota = quotaFromCodexRateLimits(parsed.payload.rate_limits, source, parsed.timestamp ?? new Date(stat.mtime).toISOString());
|
|
477
|
-
if (quota)
|
|
478
|
-
|
|
490
|
+
if (!quota)
|
|
491
|
+
continue;
|
|
492
|
+
const hit = { quota, filePath: sessionPath, mtimeMs: stat.mtime.getTime() };
|
|
493
|
+
if ((0, codex_2.isAggregateCodexLimit)(quota.limitId))
|
|
494
|
+
return hit;
|
|
495
|
+
if (!fallback)
|
|
496
|
+
fallback = hit;
|
|
479
497
|
}
|
|
480
498
|
catch {
|
|
481
499
|
// Ignore malformed or partial lines.
|
|
482
500
|
}
|
|
483
501
|
}
|
|
502
|
+
if (fallback)
|
|
503
|
+
return fallback;
|
|
484
504
|
}
|
|
485
505
|
catch {
|
|
486
506
|
return null;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
export type { SessionEvent, ClaudeSessionEvent, MessageUsage, SessionMessage, TokenUsage, ToolCall, ToolAnalytics, TimelineEvent, PendingToolCall, TaskStatus as SessionTaskStatus, TrackedTask, TaskState, SubagentStats, PendingUserRequest, ResponseLatency, LatencyStats, PlanStep, PlanState, SessionStats, CompactionEvent, TruncationEvent, ContextAttribution, TurnAttribution, ContextSizePoint, PermissionMode, PermissionModeChange, } from './types/sessionEvent';
|
|
5
5
|
export type { OpenCodeSession, OpenCodeMessage, OpenCodePart, OpenCodeTextPart, OpenCodeReasoningPart, OpenCodeToolInvocationPart, OpenCodeCompactionPart, OpenCodeDbToolPart, OpenCodeStepStartPart, OpenCodeStepFinishPart, OpenCodePatchPart, OpenCodeSubtaskPart, OpenCodeAgentPart, OpenCodeFilePart, OpenCodeRetryPart, OpenCodeSnapshotPart, OpenCodeProject, DbProject as OpenCodeDbProject, DbSession as OpenCodeDbSession, DbMessage as OpenCodeDbMessage, DbPart as OpenCodeDbPart, } from './types/opencode';
|
|
6
6
|
export type { CodexRolloutLine, CodexSessionMeta, CodexResponseItem, CodexMessageItem, CodexContentPart, CodexReasoningItem, CodexFunctionCallItem, CodexFunctionCallOutputItem, CodexLocalShellCallItem, CodexWebSearchCallItem, CodexCustomToolCallItem, CodexCustomToolCallOutputItem, CodexCompacted, CodexTurnContext, CodexEventMsg, CodexEvent, CodexTurnStartedEvent, CodexTurnCompleteEvent, CodexTaskStartedEvent, CodexTaskCompleteEvent, CodexTurnAbortedEvent, CodexTokenCountEvent, CodexTokenUsage, CodexRateLimits, CodexAgentMessageEvent, CodexAgentReasoningEvent, CodexUserMessageEvent, CodexExecCommandBeginEvent, CodexExecCommandEndEvent, CodexMcpToolCallBeginEvent, CodexMcpToolCallEndEvent, CodexErrorEvent, CodexContextCompactedEvent, CodexPatchAppliedEvent, CodexBackgroundEvent, CodexGenericEvent, CodexDbThread, CodexReasoningSummary, } from './types/codex';
|
|
7
|
+
export { isAggregateCodexLimit } from './types/codex';
|
|
7
8
|
export type { PersistedTask, TaskPersistenceStore, TaskStatus } from './types/taskPersistence';
|
|
8
9
|
export { TASK_PERSISTENCE_SCHEMA_VERSION, normalizeTaskStatus } from './types/taskPersistence';
|
|
9
10
|
export type { DecisionEntry, DecisionLogStore, DecisionSource } from './types/decisionLog';
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
* Public API for sidekick-shared.
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
10
|
-
exports.
|
|
11
|
-
exports.scopePeakHoursToSessionProvider = exports.isClaudeCodeSessionProvider = exports.fetchPeakHoursStatus = exports.createPeakHoursNotApplicableState = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = exports.accountEntrySchema = exports.accountLoginStatusSchema = exports.beginAccountLoginResultSchema = exports.accountManagerResultSchema = exports.accountProviderIdSchema = exports.activeAccountStatusSchema = exports.activeProviderAccountStatusSchema = exports.quotaHistoryDailyBucketSchema = exports.quotaHistorySampleSchema = exports.quotaHistoryRuntimeProviderSchema = exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaStateSchema = exports.quotaWindowSchema = exports.extractSessionEvents = exports.permissionModeSchema = exports.sessionEventSchema = void 0;
|
|
6
|
+
exports.getClaudeSessionDirectory = exports.encodeClaudeWorkspacePath = exports.detectSessionActivity = exports.extractTaskInfo = exports.scanSubagentDir = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.CodexRolloutParser = exports.parseDbPartData = exports.parseDbMessageData = exports.convertOpenCodeMessage = exports.detectPlanModeFromText = exports.normalizeToolInput = exports.normalizeToolName = exports.TRUNCATION_PATTERNS = exports.JsonlParser = exports.CodexProvider = exports.getOpenCodeDataDir = exports.OpenCodeProvider = exports.ClaudeCodeProvider = exports.getAllDetectedProviders = exports.detectProvider = exports.readClaudeCodePlanFiles = exports.getPlanAnalytics = exports.writePlans = exports.getLatestPlan = exports.readPlans = exports.readLatestHandoff = exports.readHistory = exports.readNotes = exports.readDecisions = exports.readTasks = exports.getProjectSlugRaw = exports.getProjectSlug = exports.encodeWorkspacePath = exports.getGlobalDataPath = exports.getProjectDataPath = exports.getConfigDir = exports.MAX_PLANS_PER_PROJECT = exports.PLAN_SCHEMA_VERSION = exports.createEmptyTokenTotals = exports.HISTORICAL_DATA_SCHEMA_VERSION = exports.STALENESS_THRESHOLDS = exports.IMPORTANCE_DECAY_FACTORS = exports.KNOWLEDGE_NOTE_SCHEMA_VERSION = exports.DECISION_LOG_SCHEMA_VERSION = exports.normalizeTaskStatus = exports.TASK_PERSISTENCE_SCHEMA_VERSION = exports.isAggregateCodexLimit = void 0;
|
|
7
|
+
exports.formatSessionJson = exports.formatSessionMarkdown = exports.formatSessionText = exports.classifyNoise = exports.shouldMergeWithPrevious = exports.classifyFollowEvent = exports.classifyMessage = exports.getSoftNoiseReason = exports.isHardNoiseFollowEvent = exports.isHardNoise = exports.formatToolSummary = exports.formatTokenCount = exports.formatDurationMs = exports.createJsonlTail = exports.toFollowEvents = exports.createWatcher = exports.parseChangelog = exports.extractProposedPlanShared = exports.parsePlanMarkdownShared = exports.PlanExtractor = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.readSessionContextSnapshot = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.composeContext = exports.FilterEngine = exports.searchSessions = exports.CodexDatabase = exports.OpenCodeDatabase = exports.discoverDebugLogs = exports.collapseDuplicates = exports.filterByLevel = exports.parseDebugLog = exports.scanSubagentTraces = exports.findAllSessionsWithWorktrees = exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionsInDirectory = exports.findAllClaudeSessions = exports.findActiveClaudeSession = exports.discoverSessionDirectory = void 0;
|
|
8
|
+
exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = exports.getAccountsDir = exports.resolveClaudeLoginCommand = exports.listAllAccounts = exports.switchAccount = exports.spawnAccountLogin = exports.finalizeAccountLogin = exports.getAccountLoginStatus = exports.beginAccountLogin = exports.isMultiAccountEnabled = exports.resolveActiveClaudeAccount = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.reconcileClaudeAuthState = exports.applyActiveClaudeToLiveHome = exports.resolveActiveClaudeHome = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.ensureDefaultAccounts = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscriptFromEvents = exports.parseTranscript = exports.generateHtmlReport = exports.PatternExtractor = exports.HeatmapTracker = exports.FrequencyTracker = exports.getSnapshotPath = exports.isSnapshotValid = exports.deleteSnapshot = exports.loadSnapshot = exports.saveSnapshot = exports.parseTodoDependencies = exports.EventAggregator = exports.getRandomPhrase = exports.PHRASE_CATEGORIES = exports.ALL_PHRASES = exports.HIGHLIGHT_CSS = exports.clearHighlightCache = exports.highlightEvent = void 0;
|
|
9
|
+
exports.readLatestCodexQuotaFromRollouts = exports.quotaFromCodexRateLimits = exports.fetchCodexQuotaFromApi = exports.getWorkspaceIdFromPath = exports.pruneQuotaHistory = exports.readQuotaHistoryDailyBuckets = exports.readQuotaHistoryRange = exports.appendQuotaHistorySample = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.withQuotaProjections = exports.projectQuotaWindow = exports.fetchQuota = exports.SEVEN_DAY_WINDOW_MS = exports.FIVE_HOUR_WINDOW_MS = exports.AutoSwitchController = exports.decideAutoSwitch = exports.DEFAULT_AUTO_SWITCH_CONFIG = exports.removeLauncher = exports.writeLauncher = exports.isShellHookInstalled = exports.uninstallShellHook = exports.installShellHook = exports.setTerminalActiveProfile = exports.removeCodexAccount = exports.switchToCodexAccount = exports.finalizeCodexAccount = exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.resolveActiveCodexAccount = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.readClaudeProfileIdentity = exports.isClaudeProfileAuthenticated = exports.claudeKeychainService = exports.claudeKeychainSuffix = exports.getClaudeProfileHome = exports.getClaudeProfilesDir = exports.getActiveAccountStatus = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = void 0;
|
|
10
|
+
exports.messageUsageSchema = exports.gatherAssetsForCwd = exports.codexSessions = exports.readCodexAssets = exports.claudeSessions = exports.readClaudeAssets = exports.extractCommands = exports.extractFilePaths = exports.extractUrls = exports.extractToolCalls = exports.extractToolCall = exports.extractTokenUsage = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = exports.MultiProviderQuotaService = exports.resolveZaiQuota = exports.readZaiCredentials = exports.quotaStateFromZaiQuotaLimitPayload = exports.fetchZaiQuotaFromApi = exports.ZaiQuotaWatcher = exports.ZAI_TIER_BUDGETS = exports.ZAI_PROVIDER_IDS = exports.ZAI_PROMPT_INVOCATIONS = exports.turnTokenWeight = exports.rowsToZaiTurnsAndErrors = exports.resolveZaiTier = exports.parseZaiQuotaError = exports.makeUnavailableZaiQuotaState = exports.isZaiProviderId = exports.inferZaiQuotaState = exports.extractNextFlushTime = exports.accumulateZaiUsage = exports.CodexQuotaWatcher = exports.resolveCodexQuotaFromLocalSources = exports.resolveCodexQuota = void 0;
|
|
11
|
+
exports.scopePeakHoursToSessionProvider = exports.isClaudeCodeSessionProvider = exports.fetchPeakHoursStatus = exports.createPeakHoursNotApplicableState = exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = exports.accountEntrySchema = exports.accountLoginStatusSchema = exports.beginAccountLoginResultSchema = exports.accountManagerResultSchema = exports.accountProviderIdSchema = exports.activeAccountStatusSchema = exports.activeProviderAccountStatusSchema = exports.quotaHistoryDailyBucketSchema = exports.quotaHistorySampleSchema = exports.quotaHistoryRuntimeProviderSchema = exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaStateSchema = exports.quotaWindowSchema = exports.extractSessionEvents = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = void 0;
|
|
12
|
+
var codex_1 = require("./types/codex");
|
|
13
|
+
Object.defineProperty(exports, "isAggregateCodexLimit", { enumerable: true, get: function () { return codex_1.isAggregateCodexLimit; } });
|
|
12
14
|
var taskPersistence_1 = require("./types/taskPersistence");
|
|
13
15
|
Object.defineProperty(exports, "TASK_PERSISTENCE_SCHEMA_VERSION", { enumerable: true, get: function () { return taskPersistence_1.TASK_PERSISTENCE_SCHEMA_VERSION; } });
|
|
14
16
|
Object.defineProperty(exports, "normalizeTaskStatus", { enumerable: true, get: function () { return taskPersistence_1.normalizeTaskStatus; } });
|
|
@@ -57,8 +59,8 @@ Object.defineProperty(exports, "ClaudeCodeProvider", { enumerable: true, get: fu
|
|
|
57
59
|
var openCode_1 = require("./providers/openCode");
|
|
58
60
|
Object.defineProperty(exports, "OpenCodeProvider", { enumerable: true, get: function () { return openCode_1.OpenCodeProvider; } });
|
|
59
61
|
Object.defineProperty(exports, "getOpenCodeDataDir", { enumerable: true, get: function () { return openCode_1.getOpenCodeDataDir; } });
|
|
60
|
-
var
|
|
61
|
-
Object.defineProperty(exports, "CodexProvider", { enumerable: true, get: function () { return
|
|
62
|
+
var codex_2 = require("./providers/codex");
|
|
63
|
+
Object.defineProperty(exports, "CodexProvider", { enumerable: true, get: function () { return codex_2.CodexProvider; } });
|
|
62
64
|
// Parsers — JSONL
|
|
63
65
|
var jsonl_1 = require("./parsers/jsonl");
|
|
64
66
|
Object.defineProperty(exports, "JsonlParser", { enumerable: true, get: function () { return jsonl_1.JsonlParser; } });
|
|
@@ -16,6 +16,7 @@ exports.CodexRolloutParser = void 0;
|
|
|
16
16
|
exports.normalizeCodexToolName = normalizeCodexToolName;
|
|
17
17
|
exports.normalizeCodexToolInput = normalizeCodexToolInput;
|
|
18
18
|
exports.extractPatchFilePaths = extractPatchFilePaths;
|
|
19
|
+
const codex_1 = require("../types/codex");
|
|
19
20
|
const openCodeParser_1 = require("./openCodeParser");
|
|
20
21
|
function normalizeRateLimits(rateLimits) {
|
|
21
22
|
if (!rateLimits?.primary && !rateLimits?.secondary)
|
|
@@ -126,6 +127,7 @@ class CodexRolloutParser {
|
|
|
126
127
|
lastTokenUsage = null;
|
|
127
128
|
modelContextWindow = null;
|
|
128
129
|
lastRateLimits = null;
|
|
130
|
+
hasAggregateRateLimits = false;
|
|
129
131
|
inPlanMode = false;
|
|
130
132
|
emittedToolUseIds = new Set();
|
|
131
133
|
patchExpandedToolUseIds = new Map();
|
|
@@ -177,6 +179,7 @@ class CodexRolloutParser {
|
|
|
177
179
|
this.lastTokenUsage = null;
|
|
178
180
|
this.modelContextWindow = null;
|
|
179
181
|
this.lastRateLimits = null;
|
|
182
|
+
this.hasAggregateRateLimits = false;
|
|
180
183
|
this.inPlanMode = false;
|
|
181
184
|
this.emittedToolUseIds.clear();
|
|
182
185
|
this.patchExpandedToolUseIds.clear();
|
|
@@ -493,9 +496,19 @@ class CodexRolloutParser {
|
|
|
493
496
|
if (e.info?.model_context_window) {
|
|
494
497
|
this.modelContextWindow = e.info.model_context_window;
|
|
495
498
|
}
|
|
496
|
-
// Store rate_limits if provided (subscription quota data)
|
|
499
|
+
// Store rate_limits if provided (subscription quota data). Codex interleaves
|
|
500
|
+
// multiple families (aggregate "codex" plus per-model ones like codex_bengalfox);
|
|
501
|
+
// keep the latest aggregate sample so a trailing model-specific event at 0% does
|
|
502
|
+
// not mask the plan quota. Fall back to a non-aggregate sample only until an
|
|
503
|
+
// aggregate one has been seen.
|
|
497
504
|
if (e.rate_limits) {
|
|
498
|
-
|
|
505
|
+
if ((0, codex_1.isAggregateCodexLimit)(e.rate_limits.limit_id)) {
|
|
506
|
+
this.lastRateLimits = e.rate_limits;
|
|
507
|
+
this.hasAggregateRateLimits = true;
|
|
508
|
+
}
|
|
509
|
+
else if (!this.hasAggregateRateLimits) {
|
|
510
|
+
this.lastRateLimits = e.rate_limits;
|
|
511
|
+
}
|
|
499
512
|
}
|
|
500
513
|
// Usage data is nested under info.last_token_usage (info can be null)
|
|
501
514
|
const usage = e.info?.last_token_usage || e.info?.total_token_usage;
|
package/dist/quotaSnapshots.js
CHANGED
|
@@ -39,6 +39,7 @@ const crypto = __importStar(require("crypto"));
|
|
|
39
39
|
const fs = __importStar(require("fs"));
|
|
40
40
|
const path = __importStar(require("path"));
|
|
41
41
|
const paths_1 = require("./paths");
|
|
42
|
+
const codex_1 = require("./types/codex");
|
|
42
43
|
function getQuotaSnapshotPath() {
|
|
43
44
|
return path.join((0, paths_1.getConfigDir)(), 'quota-snapshots.json');
|
|
44
45
|
}
|
|
@@ -94,6 +95,15 @@ function windowResetMs(value) {
|
|
|
94
95
|
// Preserve the best-known same-window snapshot while still allowing lower
|
|
95
96
|
// utilization after Codex advances to a newer reset window.
|
|
96
97
|
function shouldKeepExistingSnapshot(existing, next) {
|
|
98
|
+
// Family rank first (Codex): the aggregate plan-quota family ("codex") must never be
|
|
99
|
+
// replaced or blocked by a model/feature-specific family (e.g. codex_bengalfox), whose
|
|
100
|
+
// later-resetting 0% window would otherwise win the reset-window comparison below. This
|
|
101
|
+
// is a no-op for providers whose limitId is consistent across samples (Claude: absent;
|
|
102
|
+
// z.ai: zai-*), where both sides share the same aggregate-ness.
|
|
103
|
+
const existingAggregate = (0, codex_1.isAggregateCodexLimit)(existing.limitId);
|
|
104
|
+
const nextAggregate = (0, codex_1.isAggregateCodexLimit)(next.limitId);
|
|
105
|
+
if (existingAggregate !== nextAggregate)
|
|
106
|
+
return existingAggregate;
|
|
97
107
|
const existingPrimaryReset = windowResetMs(existing.fiveHour.resetsAt);
|
|
98
108
|
const nextPrimaryReset = windowResetMs(next.fiveHour.resetsAt);
|
|
99
109
|
if (existingPrimaryReset !== nextPrimaryReset)
|
|
@@ -8,9 +8,9 @@ import { z } from 'zod';
|
|
|
8
8
|
export declare const assistantTurnEventTypeSchema: z.ZodEnum<{
|
|
9
9
|
status: "status";
|
|
10
10
|
error: "error";
|
|
11
|
+
text: "text";
|
|
11
12
|
tool_use: "tool_use";
|
|
12
13
|
tool_result: "tool_result";
|
|
13
|
-
text: "text";
|
|
14
14
|
progress: "progress";
|
|
15
15
|
thinking: "thinking";
|
|
16
16
|
delta: "delta";
|
|
@@ -19,9 +19,9 @@ export declare const assistantTurnEventSchema: z.ZodObject<{
|
|
|
19
19
|
eventType: z.ZodEnum<{
|
|
20
20
|
status: "status";
|
|
21
21
|
error: "error";
|
|
22
|
+
text: "text";
|
|
22
23
|
tool_use: "tool_use";
|
|
23
24
|
tool_result: "tool_result";
|
|
24
|
-
text: "text";
|
|
25
25
|
progress: "progress";
|
|
26
26
|
thinking: "thinking";
|
|
27
27
|
delta: "delta";
|
|
@@ -41,10 +41,10 @@ export declare const sessionEventSchema: z.ZodObject<{
|
|
|
41
41
|
type: z.ZodEnum<{
|
|
42
42
|
user: "user";
|
|
43
43
|
assistant: "assistant";
|
|
44
|
+
system: "system";
|
|
44
45
|
tool_use: "tool_use";
|
|
45
46
|
tool_result: "tool_result";
|
|
46
47
|
summary: "summary";
|
|
47
|
-
system: "system";
|
|
48
48
|
}>;
|
|
49
49
|
message: z.ZodObject<{
|
|
50
50
|
role: z.ZodString;
|
package/dist/types/codex.d.ts
CHANGED
|
@@ -192,6 +192,15 @@ export interface CodexRateLimits {
|
|
|
192
192
|
plan_type?: string;
|
|
193
193
|
rate_limit_reached_type?: string;
|
|
194
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Codex reports several rate-limit families per session, keyed by `limit_id`.
|
|
197
|
+
* The aggregate plan quota — what the usage API surfaces — is `limit_id: "codex"`
|
|
198
|
+
* (or absent on older payloads). Model/feature-specific families (e.g.
|
|
199
|
+
* `codex_bengalfox`, `premium`) report their own windows and can read 0% while the
|
|
200
|
+
* plan is heavily used, so they must never mask the aggregate in the standard
|
|
201
|
+
* quota view. Returns true only for the aggregate family.
|
|
202
|
+
*/
|
|
203
|
+
export declare function isAggregateCodexLimit(limitId?: string | null): boolean;
|
|
195
204
|
export interface CodexTokenUsage {
|
|
196
205
|
input_tokens: number;
|
|
197
206
|
cached_input_tokens?: number;
|
package/dist/types/codex.js
CHANGED
|
@@ -12,3 +12,15 @@
|
|
|
12
12
|
* @module types/codex
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.isAggregateCodexLimit = isAggregateCodexLimit;
|
|
16
|
+
/**
|
|
17
|
+
* Codex reports several rate-limit families per session, keyed by `limit_id`.
|
|
18
|
+
* The aggregate plan quota — what the usage API surfaces — is `limit_id: "codex"`
|
|
19
|
+
* (or absent on older payloads). Model/feature-specific families (e.g.
|
|
20
|
+
* `codex_bengalfox`, `premium`) report their own windows and can read 0% while the
|
|
21
|
+
* plan is heavily used, so they must never mask the aggregate in the standard
|
|
22
|
+
* quota view. Returns true only for the aggregate family.
|
|
23
|
+
*/
|
|
24
|
+
function isAggregateCodexLimit(limitId) {
|
|
25
|
+
return !limitId || limitId === 'codex';
|
|
26
|
+
}
|
package/package.json
CHANGED