talon-agent 3.18.0 → 3.19.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "talon-agent",
3
- "version": "3.18.0",
3
+ "version": "3.19.0",
4
4
  "description": "Multi-frontend AI agent with full tool access, streaming, cron jobs, and plugin system",
5
5
  "author": "Dylan Neve",
6
6
  "license": "MIT",
@@ -95,6 +95,10 @@ export function parseCodexUsage(body: unknown): PlanUsage | undefined {
95
95
  primary_window?: RawWindow | null;
96
96
  secondary_window?: RawWindow | null;
97
97
  };
98
+ rate_limit_reset_credits?: {
99
+ available_count?: number;
100
+ applicable_available_count?: number;
101
+ } | null;
98
102
  } | null;
99
103
  const limit = data?.rate_limit;
100
104
  if (!limit) return undefined;
@@ -108,6 +112,10 @@ export function parseCodexUsage(body: unknown): PlanUsage | undefined {
108
112
  return {
109
113
  ...(data?.plan_type ? { plan: data.plan_type } : {}),
110
114
  windows,
115
+ ...(typeof data?.rate_limit_reset_credits?.available_count === "number" &&
116
+ data.rate_limit_reset_credits.available_count > 0
117
+ ? { resetsAvailable: data.rate_limit_reset_credits.available_count }
118
+ : {}),
111
119
  fetchedAt: Date.now(),
112
120
  };
113
121
  }
@@ -245,6 +245,8 @@ export interface PlanUsage {
245
245
  /** Subscription tier (`max`, `pro`, …) when known. */
246
246
  plan?: string;
247
247
  windows: PlanWindow[];
248
+ /** How many one-shot rate-limit resets are still banked, when the plan has them. */
249
+ resetsAvailable?: number;
248
250
  /** Epoch ms of the read, so renderers can flag figures as aged. */
249
251
  fetchedAt: number;
250
252
  }
@@ -293,6 +293,12 @@ export function renderUsageMessage(entries: BackendUsageEntry[]): string {
293
293
  const age = entry.plan.ageLabel ? ` *(${entry.plan.ageLabel})*` : "";
294
294
  const plan = entry.plan.plan ? ` · ${entry.plan.plan}` : "";
295
295
  lines.push("", `**${name}**${plan}${age}`);
296
+ if (entry.plan.resetsAvailable) {
297
+ const n = entry.plan.resetsAvailable;
298
+ lines.push(
299
+ ` • You have **${n}** usage limit reset${n === 1 ? "" : "s"} available`,
300
+ );
301
+ }
296
302
  for (const w of entry.plan.windows) {
297
303
  const reset = w.resetLabel ? ` reset ${w.resetLabel}` : "";
298
304
  lines.push(
@@ -303,7 +303,9 @@ export interface PlanWindowDisplay {
303
303
  export interface PlanDisplay {
304
304
  plan: string | undefined;
305
305
  windows: PlanWindowDisplay[];
306
- /** Set only once the figures have aged, e.g. "12m ago". */
306
+ /** Set only when the account still has one-shot rate-limit resets left. */
307
+ resetsAvailable: number | undefined;
308
+ /** Set only when the figures have aged, e.g. "12m ago". */
307
309
  ageLabel: string | undefined;
308
310
  }
309
311
 
@@ -330,6 +332,7 @@ export function buildPlanDisplay(
330
332
  const age = Date.now() - usage.fetchedAt;
331
333
  return {
332
334
  plan: usage.plan,
335
+ resetsAvailable: usage.resetsAvailable,
333
336
  ageLabel:
334
337
  age > PLAN_STALE_AFTER_MS
335
338
  ? formatRelativeAge(usage.fetchedAt)
@@ -222,6 +222,12 @@ export function renderUsageMessage(entries: BackendUsageEntry[]): string {
222
222
  const age = entry.plan.ageLabel ? ` <i>(${entry.plan.ageLabel})</i>` : "";
223
223
  const plan = entry.plan.plan ? ` · ${escapeHtml(entry.plan.plan)}` : "";
224
224
  lines.push("", `<b>${name}</b>${plan}${age}`);
225
+ if (entry.plan.resetsAvailable) {
226
+ const n = entry.plan.resetsAvailable;
227
+ lines.push(
228
+ ` • You have <b>${n}</b> usage limit reset${n === 1 ? "" : "s"} available`,
229
+ );
230
+ }
225
231
  for (const w of entry.plan.windows) {
226
232
  const reset = w.resetLabel ? ` reset ${w.resetLabel}` : "";
227
233
  lines.push(