Ctrl K
ComunidadGuías…

test/codex-rate-limits.test.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
var test = require("node:test");
var assert = require("node:assert/strict");
var kit = require("../lib/yoke/adapters/codex").contractTestKit;
var attachMessageProcessor = require("../lib/sdk-message-processor").attachMessageProcessor;

function snapshot(primary, secondary, limitId) {
  return kit.normalizeEvent({ method: "account/rateLimits/updated", params: {
    rateLimits: { primary: primary, secondary: secondary, limitId: limitId },
  } }, kit.createEventState())[0];
}

test("Codex keeps actual quota durations and never infers request rejection", function () {
  [10080, 300, 15, 90, null, undefined].forEach(function (duration) {
    var event = snapshot({ usedPercent: 100, windowDurationMins: duration, resetsAt: 1900000000 });
    assert.equal(event.yokeType, "rate_limit");
    assert.equal(event.rateLimitInfo.source, "account_snapshot");
    assert.equal(event.rateLimitInfo.status, undefined);
    assert.equal(event.rateLimitInfo.windows[0].windowDurationMins, duration || null);
    assert.equal(event.rateLimitInfo.windows[0].usedPercent, 100);
    assert.equal(event.rateLimitInfo.windows[0].resetsAt, 1900000000);
  });
});

test("Codex snapshots explicitly clear missing and disabled windows", function () {
  assert.deepEqual(snapshot(null, null).rateLimitInfo.windows, []);
  assert.deepEqual(snapshot({ windowDurationMins: 0, usedPercent: 100 }).rateLimitInfo.windows, []);
  var windows = snapshot({ windowDurationMins: 300 }, { windowDurationMins: 300 }).rateLimitInfo.windows;
  assert.deepEqual(windows.map(function (window) { return window.key; }), ["primary", "secondary"]);
  assert.equal(windows[0].usedPercent, null);
  assert.equal(windows[0].resetsAt, null);
});

function fixture() {
  var recorded = [];
  var rejected = [];
  var scheduled = [];
  var processor = attachMessageProcessor({
    sm: { sendAndRecord: function (session, msg) { recorded.push(msg); } },
    opts: {
      onRateLimitRejected: function (session, reset) { rejected.push(reset); },
      getAutoContinueSetting: function () { return true; },
      scheduleMessage: function (session, text, reset) { scheduled.push(reset); },
    },
  });
  return { processor: processor, recorded: recorded, rejected: rejected, scheduled: scheduled };
}

test("full snapshots are deduplicated per session and bucket without scheduling retries", function () {
  var f = fixture();
  var session = { localId: 12, vendor: "codex", ownerId: "owner" };
  var window = { usedPercent: 100, windowDurationMins: 10080, resetsAt: 1900000000 };
  f.processor.processSDKMessage(session, snapshot(window));
  f.processor.processSDKMessage(session, snapshot(window));
  assert.equal(f.recorded.length, 1);
  assert.equal(f.recorded[0].type, "rate_limit_usage");
  assert.equal(f.recorded[0].sessionId, 12);
  assert.equal(f.recorded[0].vendor, "codex");
  assert.equal(f.recorded[0].quotaWindows[0].resetsAt, 1900000000000);
  assert.equal(session.rateLimitResetsAt, undefined);
  assert.equal(session.rateLimitAutoContinuePending, undefined);
  assert.deepEqual(f.rejected, []);
  assert.deepEqual(f.scheduled, []);
  f.processor.processSDKMessage({ localId: 13, vendor: "codex" }, snapshot(window));
  f.processor.processSDKMessage(session, snapshot(window, null, "other"));
  assert.equal(f.recorded.length, 3);
  f.processor.processSDKMessage(session, snapshot(Object.assign({}, window, { usedPercent: 0 })));
  f.processor.processSDKMessage(session, snapshot(null, null));
  assert.equal(f.recorded.length, 5);
  assert.deepEqual(f.recorded[4].quotaWindows, []);
  f.processor.processSDKMessage(session, snapshot(window));
  assert.equal(f.recorded.length, 6, "same quota can recur after recovery");
});

test("real rejection events retain scheduling behavior", function () {
  var f = fixture();
  var session = { localId: 1, vendor: "claude" };
  f.processor.processSDKMessage(session, { yokeType: "rate_limit", rateLimitInfo: {
    status: "rejected", rateLimitType: "five_hour", resetsAt: 1900000000,
  } });
  assert.deepEqual(f.rejected, [1900000000000]);
  assert.deepEqual(f.scheduled, [1900000000000]);
  assert.ok(f.recorded.some(function (msg) { return msg.type === "rate_limit"; }));
});

test("reconnect restores latest quota buckets beyond paginated history with the current session id", function () {
  var listener;
  attachMessageProcessor({ sm: { addOnSessionViewed: function (fn) { listener = fn; } } });
  var base = { type: "rate_limit_usage", source: "account_snapshot", vendor: "codex", sessionId: 99, limitId: "codex" };
  var session = { localId: 12, vendor: "codex", history: [
    Object.assign({}, base, { quotaWindows: [{ usedPercent: 100 }] }),
    Object.assign({}, base, { quotaWindows: [] }),
    Object.assign({}, base, { limitId: "other", quotaWindows: [{ usedPercent: 20 }] }),
  ] };
  for (var i = 0; i < 600; i++) session.history.push({ type: "user_message", text: "later" });
  var sent = [];
  listener(session, {}, function (msg) { sent.push(msg); });
  assert.equal(sent.length, 2);
  assert.equal(sent[0].sessionId, 12);
  assert.equal(sent[1].sessionId, 12);
  assert.equal(sent[1].limitId, "codex");
  assert.deepEqual(sent[1].quotaWindows, [], "recovery wins over older exhausted snapshot");
  sent.length = 0;
  listener(Object.assign({}, session, { vendor: "claude" }), {}, function (msg) { sent.push(msg); });
  assert.deepEqual(sent, []);
});

test("Claude warnings retain explicit extra usage metadata without scheduling retries", function () {
  var f = fixture();
  f.processor.processSDKMessage({ localId: 20, vendor: "claude" }, { yokeType: "rate_limit", rateLimitInfo: {
    status: "allowed_warning", rateLimitType: "five_hour", overageEnabled: false,
    overageStatus: "rejected", overageResetsAt: 1900000000, overageDisabledReason: "out_of_credits"
  } });
  var warning = f.recorded.find(function (msg) { return msg.type === "rate_limit"; });
  assert.equal(warning.overageEnabled, false);
  assert.equal(warning.overageStatus, "rejected");
  assert.equal(warning.overageResetsAt, 1900000000000);
  assert.equal(warning.overageDisabledReason, "out_of_credits");
  assert.deepEqual(f.scheduled, []);
});