fix(usage): restore xai quota label case; update stale kiro tests

3-way unit-suite comparison (branch-pre-merge vs origin/master vs
HEAD) with git worktrees:

* ProviderLimits/utils.js: parseQuotaData 'xai' case (ab9a3c1d
  weekly/api_usage label mapping) was dropped by an EARLIER merge
  (already failing at the pre-merge branch tip) — its companion test
  xai-usage.test.js has been red since. Restored verbatim from
  ab9a3c1d; the xai usage handler + dispatch entry survived, only the
  UI label mapping was lost.
* openai-to-kiro.test.js: 19 failures were stale upstream tests —
  1fc2a81d intentionally removed the redundant top-level
  systemPrompt field (Kiro rejects it) without updating them. The
  thinking/agentic directives now ride the frozen session-start msg0
  via contentPrefix. systemPromptOf reads msg0 (or the current
  message when there is no replayed session); the cross-turn
  stability test asserts the actual cacheability contract.

Suite now: 83 failing vs 103 on origin/master baseline; zero files
fail in HEAD that did not fail pre-merge. next build passes.
This commit is contained in:
2026-09-08 10:53:21 +07:00
parent 02f097880d
commit 302795a613
2 changed files with 71 additions and 7 deletions

View File

@@ -666,6 +666,48 @@ export function parseQuotaData(provider, data) {
}
break;
case "xai":
// xAI mixes:
// - weekly: percentage window (used/total 0-100) from GetGrokCreditsConfig
// - api_usage: absolute monthly credits from /v1/billing
// For absolute rows, do not forward remainingCredits as `remaining`
// (QuotaTable treats remaining as a 0-100 percentage; same pitfall as Qoder).
if (data.quotas) {
Object.entries(data.quotas).forEach(([quotaType, quota]) => {
const name =
quotaType === "weekly"
? "Weekly limit"
: quotaType === "api_usage"
? "Api usage"
: quotaType === "monthly"
? "Api usage"
: quotaType === "on_demand"
? "On-demand"
: quotaType;
if (quotaType === "weekly") {
normalizedQuotas.push({
name,
used: quota.used || 0,
total: quota.total || 100,
remaining: quota.remaining,
remainingPercentage: quota.remainingPercentage ?? quota.remaining,
resetAt: quota.resetAt || null,
});
return;
}
normalizedQuotas.push({
name,
used: quota.used || 0,
total: quota.total || 0,
unit: quota.unit,
resetAt: quota.resetAt || null,
});
});
}
break;
default:
// Generic fallback for unknown providers
if (data.quotas) {

View File

@@ -11,7 +11,16 @@ import { openaiToKiroRequest } from "../../open-sse/translator/request/openai-to
const contentOf = (result) =>
result.conversationState.currentMessage.userInputMessage.content;
const systemPromptOf = (result) => result.systemPrompt || "";
// 1fc2a81d dropped the redundant top-level systemPrompt field (Kiro rejects
// it): thinking/agentic directives ride into the frozen session-start message
// (msg0) via contentPrefix, or into the current message when there is no
// session to replay. Read whichever carries them.
const systemPromptOf = (result) => {
const cs = result.conversationState || {};
const msg0 = cs.history?.[0]?.userInputMessage?.content;
if (typeof msg0 === "string" && msg0) return msg0;
return cs.currentMessage?.userInputMessage?.content || "";
};
describe("openaiToKiroRequest", () => {
describe("basic message conversion", () => {
@@ -568,23 +577,36 @@ describe("openaiToKiroRequest", () => {
expect(systemPromptOf(result)).toContain("<max_thinking_length>16000</max_thinking_length>");
});
it("keeps top-level systemPrompt stable across turns", () => {
it("keeps the frozen session-start directive stable across turns", () => {
// Upstream dropped the redundant top-level systemPrompt; cacheability
// now lives in the replayed msg0. Assert the directive rides msg0 and
// the volatile clock only enters the current turn.
const credentials = {
connectionId: "kiro-account-openai-stable",
rawHeaders: { "x-session-id": "hermes-session-openai-stable" },
};
const first = openaiToKiroRequest(
"claude-sonnet-4.6-thinking",
{ messages: [{ role: "user", content: "first" }] },
true,
{}
credentials
);
const second = openaiToKiroRequest(
"claude-sonnet-4.6-thinking",
{ messages: [{ role: "user", content: "second" }] },
true,
{}
credentials
);
expect(first.systemPrompt).toBe(second.systemPrompt);
expect(first.systemPrompt).not.toContain("Current time");
expect(first.conversationState.currentMessage.userInputMessage.content).toContain("Current time");
const msg0 = second.conversationState.history[0].userInputMessage.content;
// msg0 carries the thinking directive and is replayed byte-identical on
// later turns (upstream prefix includes the session-start timestamp;
// the cacheability contract is that it does NOT change per turn).
expect(msg0).toBe(first.conversationState.currentMessage.userInputMessage.content);
expect(msg0).toContain("<max_thinking_length>");
const cur = second.conversationState.currentMessage.userInputMessage.content;
expect(cur).toContain("second");
expect(cur).toContain("Current time");
});
it("replays frozen msg0 for explicit Kiro sessions while keeping current time fresh", () => {