2026-05-12 15:05:56 +00:00
|
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
import {
|
|
|
|
|
runtimeConfigSnapshotFromAppServerConfig,
|
|
|
|
|
type AppServerConfigReadResponse,
|
|
|
|
|
type RuntimeConfigSnapshot,
|
|
|
|
|
} from "../../src/app-server/runtime-config";
|
2026-06-09 14:39:58 +00:00
|
|
|
import type { ModelMetadata } from "../../src/domain/catalog/metadata";
|
2026-05-12 15:05:56 +00:00
|
|
|
import {
|
|
|
|
|
compactModelLabel,
|
|
|
|
|
compactReasoningEffortLabel,
|
|
|
|
|
modelOverrideMessage,
|
2026-06-12 05:12:59 +00:00
|
|
|
reasoningEffortOverrideMessage,
|
|
|
|
|
} from "../../src/features/chat/runtime/settings-copy";
|
|
|
|
|
import {
|
2026-05-12 15:05:56 +00:00
|
|
|
parseModelOverride,
|
|
|
|
|
parseReasoningEffortOverride,
|
2026-06-12 05:12:59 +00:00
|
|
|
} from "../../src/features/chat/conversation/turns/runtime-setting-commands";
|
2026-05-12 15:05:56 +00:00
|
|
|
import {
|
2026-05-21 15:02:32 +00:00
|
|
|
autoReviewActive,
|
|
|
|
|
currentApprovalsReviewer,
|
2026-05-12 15:05:56 +00:00
|
|
|
currentModel,
|
|
|
|
|
currentReasoningEffort,
|
2026-05-17 09:50:00 +00:00
|
|
|
currentServiceTier,
|
2026-05-29 00:44:25 +00:00
|
|
|
fastModeActive,
|
|
|
|
|
fastServiceTierRequestValue,
|
2026-05-12 15:05:56 +00:00
|
|
|
fastModeLabel,
|
2026-06-10 02:34:27 +00:00
|
|
|
runtimeConfigOrDefault,
|
2026-05-12 15:05:56 +00:00
|
|
|
serviceTierLabel,
|
2026-06-11 15:03:23 +00:00
|
|
|
supportedReasoningEfforts,
|
2026-06-12 02:54:45 +00:00
|
|
|
} from "../../src/features/chat/runtime/effective";
|
|
|
|
|
import type { RuntimeSnapshot } from "../../src/features/chat/runtime/snapshot";
|
2026-06-12 05:12:59 +00:00
|
|
|
import { resetRuntimeSettingToConfig, setPendingRuntimeSetting } from "../../src/features/chat/runtime/pending-settings";
|
2026-06-11 15:03:23 +00:00
|
|
|
import {
|
|
|
|
|
pendingThreadSettingsUpdate,
|
|
|
|
|
requestedTurnCollaborationModeSettings,
|
|
|
|
|
serviceTierRequestForThreadStart,
|
2026-06-12 05:12:59 +00:00
|
|
|
} from "../../src/features/chat/runtime/thread-settings-update";
|
2026-06-12 04:20:19 +00:00
|
|
|
import { contextSummary, runtimeConfigSections, rateLimitSummary } from "../../src/features/chat/display/status/runtime";
|
2026-05-12 15:05:56 +00:00
|
|
|
|
|
|
|
|
describe("runtime settings", () => {
|
|
|
|
|
it("parses model overrides", () => {
|
|
|
|
|
expect(parseModelOverride("gpt-5.5")).toBe("gpt-5.5");
|
|
|
|
|
expect(parseModelOverride(" default ")).toBeNull();
|
|
|
|
|
expect(parseModelOverride("")).toBeUndefined();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("parses reasoning effort overrides", () => {
|
|
|
|
|
expect(parseReasoningEffortOverride("high")).toBe("high");
|
|
|
|
|
expect(parseReasoningEffortOverride("default")).toBeNull();
|
2026-06-11 10:09:28 +00:00
|
|
|
expect(parseReasoningEffortOverride("extreme")).toBe("extreme");
|
|
|
|
|
expect(parseReasoningEffortOverride("CaseSensitive")).toBe("CaseSensitive");
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("formats runtime override messages", () => {
|
|
|
|
|
expect(modelOverrideMessage("gpt-5.5")).toBe("Model set to gpt-5.5 for subsequent turns.");
|
|
|
|
|
expect(modelOverrideMessage(null)).toBe("Model reset to default for subsequent turns.");
|
2026-06-04 14:13:19 +00:00
|
|
|
expect(reasoningEffortOverrideMessage("low")).toBe("Reasoning effort set to low for subsequent turns.");
|
|
|
|
|
expect(reasoningEffortOverrideMessage(null)).toBe("Reasoning effort reset to default for subsequent turns.");
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("formats compact runtime labels", () => {
|
|
|
|
|
expect(compactModelLabel("gpt-5.5")).toBe("5.5");
|
|
|
|
|
expect(compactModelLabel("custom-model")).toBe("custom-model");
|
|
|
|
|
expect(compactModelLabel(null)).toBe("default");
|
|
|
|
|
expect(compactReasoningEffortLabel("minimal")).toBe("min");
|
|
|
|
|
expect(compactReasoningEffortLabel("high")).toBe("high");
|
|
|
|
|
expect(compactReasoningEffortLabel(null)).toBe("default");
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-22 01:42:56 +00:00
|
|
|
it("keeps runtime defaults, resets, and collaboration mode semantics distinct", () => {
|
2026-05-12 15:05:56 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-01 02:07:59 +00:00
|
|
|
requestedModel: resetRuntimeSettingToConfig(),
|
|
|
|
|
requestedReasoningEffort: resetRuntimeSettingToConfig(),
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBe("gpt-5.5");
|
|
|
|
|
expect(currentReasoningEffort(snapshot, snapshotConfig(snapshot))).toBe("high");
|
|
|
|
|
expect(requestedTurnCollaborationModeSettings(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
2026-05-12 15:05:56 +00:00
|
|
|
collaborationMode: {
|
|
|
|
|
mode: "default",
|
|
|
|
|
settings: { model: "gpt-5.5", reasoning_effort: "high" },
|
|
|
|
|
},
|
|
|
|
|
});
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(pendingThreadSettingsUpdate(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
|
|
|
update: { model: null, effort: null },
|
|
|
|
|
collaborationModeWarning: null,
|
|
|
|
|
});
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-22 01:42:56 +00:00
|
|
|
it("uses explicit runtime overrides as current values and settings payload values", () => {
|
2026-05-12 15:05:56 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-01 02:07:59 +00:00
|
|
|
requestedModel: setPendingRuntimeSetting("gpt-5.4"),
|
|
|
|
|
requestedReasoningEffort: setPendingRuntimeSetting("low"),
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBe("gpt-5.4");
|
|
|
|
|
expect(currentReasoningEffort(snapshot, snapshotConfig(snapshot))).toBe("low");
|
|
|
|
|
expect(pendingThreadSettingsUpdate(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
|
|
|
update: { model: "gpt-5.4", effort: "low" },
|
|
|
|
|
collaborationModeWarning: null,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("keeps model reset tied to config when active thread model differs", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
activeModel: "gpt-5-active",
|
|
|
|
|
requestedModel: resetRuntimeSettingToConfig(),
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
model_reasoning_effort: "high",
|
|
|
|
|
service_tier: "flex",
|
|
|
|
|
model_context_window: 100_000,
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBeNull();
|
|
|
|
|
expect(pendingThreadSettingsUpdate(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
|
|
|
update: { model: null },
|
|
|
|
|
collaborationModeWarning: null,
|
|
|
|
|
});
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-08 00:33:13 +00:00
|
|
|
it("builds the Plan collaboration mode payload from selected runtime settings", () => {
|
2026-06-11 15:03:23 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
selectedCollaborationMode: "plan",
|
|
|
|
|
requestedModel: setPendingRuntimeSetting("gpt-5.5"),
|
|
|
|
|
requestedReasoningEffort: setPendingRuntimeSetting("high"),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(requestedTurnCollaborationModeSettings(snapshot, snapshotConfig(snapshot))).toEqual({
|
2026-06-08 00:33:13 +00:00
|
|
|
collaborationMode: {
|
|
|
|
|
mode: "plan",
|
|
|
|
|
settings: {
|
|
|
|
|
model: "gpt-5.5",
|
|
|
|
|
reasoning_effort: "high",
|
|
|
|
|
developer_instructions: null,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
warning: null,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
it("uses the explicit config for collaboration mode thread settings", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
selectedCollaborationMode: "plan",
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
model: "snapshot-model",
|
|
|
|
|
model_reasoning_effort: "low",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
const explicitConfig = runtimeConfigFixture({
|
|
|
|
|
model: "explicit-model",
|
|
|
|
|
model_reasoning_effort: "high",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(requestedTurnCollaborationModeSettings(snapshot, explicitConfig)).toEqual({
|
|
|
|
|
collaborationMode: {
|
|
|
|
|
mode: "plan",
|
|
|
|
|
settings: {
|
|
|
|
|
model: "explicit-model",
|
|
|
|
|
reasoning_effort: "high",
|
|
|
|
|
developer_instructions: null,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
warning: null,
|
|
|
|
|
});
|
|
|
|
|
expect(pendingThreadSettingsUpdate(snapshot, explicitConfig)).toMatchObject({
|
|
|
|
|
update: {
|
|
|
|
|
collaborationMode: {
|
|
|
|
|
mode: "plan",
|
|
|
|
|
settings: {
|
|
|
|
|
model: "explicit-model",
|
|
|
|
|
reasoning_effort: "high",
|
|
|
|
|
developer_instructions: null,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
collaborationModeWarning: null,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-21 15:02:32 +00:00
|
|
|
it("resolves approval reviewer from requested, active, then effective config", () => {
|
2026-06-11 15:03:23 +00:00
|
|
|
const requested = runtimeSnapshot({
|
|
|
|
|
requestedApprovalsReviewer: setPendingRuntimeSetting("user"),
|
|
|
|
|
activeApprovalsReviewer: "auto_review",
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
|
|
|
|
});
|
|
|
|
|
const active = runtimeSnapshot({
|
|
|
|
|
activeApprovalsReviewer: "auto_review",
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
|
|
|
|
});
|
|
|
|
|
const configured = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(currentApprovalsReviewer(requested, snapshotConfig(requested))).toBe("user");
|
|
|
|
|
expect(currentApprovalsReviewer(active, snapshotConfig(active))).toBe("auto_review");
|
|
|
|
|
expect(currentApprovalsReviewer(configured, snapshotConfig(configured))).toBe("guardian_subagent");
|
2026-05-21 15:02:32 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-22 21:01:07 +00:00
|
|
|
it("uses the active reviewer before configured reviewer", () => {
|
2026-05-22 03:30:45 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
activeApprovalsReviewer: "user",
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "auto_review" }),
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentApprovalsReviewer(snapshot, snapshotConfig(snapshot))).toBe("user");
|
|
|
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("treats guardian subagent reviewer as active auto-review", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
activeApprovalsReviewer: "guardian_subagent",
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentApprovalsReviewer(snapshot, snapshotConfig(snapshot))).toBe("guardian_subagent");
|
|
|
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-22 21:01:07 +00:00
|
|
|
it("uses requested reviewer above active and configured reviewers", () => {
|
2026-05-22 03:30:45 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-01 02:07:59 +00:00
|
|
|
requestedApprovalsReviewer: setPendingRuntimeSetting("user"),
|
2026-05-22 03:30:45 +00:00
|
|
|
activeApprovalsReviewer: "user",
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "auto_review" }),
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentApprovalsReviewer(snapshot, snapshotConfig(snapshot))).toBe("user");
|
|
|
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-27 05:33:07 +00:00
|
|
|
it("uses effective approval reviewer values and reports selected profile metadata", () => {
|
2026-06-10 02:04:30 +00:00
|
|
|
const runtimeConfig = runtimeConfigFixture({ approvals_reviewer: "auto_review" }, [
|
2026-05-27 05:33:07 +00:00
|
|
|
configLayer({}, null),
|
|
|
|
|
configLayer({ approvals_reviewer: "auto_review" }, "auto"),
|
|
|
|
|
]);
|
2026-05-22 03:30:45 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig,
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-10 02:04:30 +00:00
|
|
|
expect(runtimeConfigOrDefault(runtimeConfig).profile).toBe("auto");
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentApprovalsReviewer(snapshot, snapshotConfig(snapshot))).toBe("auto_review");
|
|
|
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-27 05:33:07 +00:00
|
|
|
it("uses effective model, effort, and fast mode config values", () => {
|
2026-05-22 03:30:45 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture(
|
2026-05-27 05:33:07 +00:00
|
|
|
{
|
|
|
|
|
model: "gpt-profile",
|
|
|
|
|
model_reasoning_effort: "high",
|
|
|
|
|
service_tier: "fast",
|
2026-05-22 03:30:45 +00:00
|
|
|
},
|
2026-05-27 05:33:07 +00:00
|
|
|
[
|
|
|
|
|
configLayer({}, null),
|
|
|
|
|
configLayer({ model: "gpt-profile", model_reasoning_effort: "high", service_tier: "fast" }, "fast-profile"),
|
|
|
|
|
],
|
|
|
|
|
),
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBe("gpt-profile");
|
|
|
|
|
expect(currentReasoningEffort(snapshot, snapshotConfig(snapshot))).toBe("high");
|
|
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
|
|
|
expect(serviceTierLabel(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("on");
|
|
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-22 21:01:07 +00:00
|
|
|
it("uses active service tier before configured service tier", () => {
|
2026-05-22 03:30:45 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-05-28 09:16:54 +00:00
|
|
|
activeServiceTier: "flex",
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("flex");
|
|
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("off");
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-29 00:44:25 +00:00
|
|
|
it("treats the catalog Fast service tier id as fast mode while preserving the id", () => {
|
|
|
|
|
const model = modelFixture("gpt-5.5");
|
|
|
|
|
// This mirrors Codex app-server 0.134.0 model/list: Fast is named "Fast" but its id is "priority".
|
2026-06-09 02:34:15 +00:00
|
|
|
model.serviceTiers = [{ id: "priority", name: "Fast" }];
|
2026-05-29 00:44:25 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
activeModel: "gpt-5.5",
|
|
|
|
|
activeServiceTier: "priority",
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
|
2026-05-29 00:44:25 +00:00
|
|
|
availableModels: [model],
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("priority");
|
|
|
|
|
expect(serviceTierLabel(snapshot, snapshotConfig(snapshot))).toBe("priority");
|
|
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
|
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("on");
|
|
|
|
|
expect(fastServiceTierRequestValue(snapshot, snapshotConfig(snapshot))).toBe("priority");
|
2026-05-29 00:44:25 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("treats the Codex 0.134.0 reported default tier after clearing Fast as fast mode off", () => {
|
|
|
|
|
const model = modelFixture("gpt-5.5");
|
2026-06-09 02:34:15 +00:00
|
|
|
model.serviceTiers = [{ id: "priority", name: "Fast" }];
|
2026-05-29 00:44:25 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
activeModel: "gpt-5.5",
|
|
|
|
|
activeServiceTier: "default",
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
|
2026-05-29 00:44:25 +00:00
|
|
|
availableModels: [model],
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("default");
|
|
|
|
|
expect(serviceTierLabel(snapshot, snapshotConfig(snapshot))).toBe("default");
|
|
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
|
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("off");
|
2026-05-29 00:44:25 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-22 21:01:07 +00:00
|
|
|
it("uses requested service tier above active and configured service tiers", () => {
|
2026-05-22 03:30:45 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-01 02:07:59 +00:00
|
|
|
requestedServiceTier: setPendingRuntimeSetting("off"),
|
2026-05-28 09:16:54 +00:00
|
|
|
activeServiceTier: "flex",
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBeNull();
|
|
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("off");
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-22 01:42:56 +00:00
|
|
|
it("resolves requested approval reviewer without adding it to turn runtime settings", () => {
|
2026-06-01 02:07:59 +00:00
|
|
|
const snapshot = runtimeSnapshot({ requestedApprovalsReviewer: setPendingRuntimeSetting("auto_review") });
|
2026-05-21 15:02:32 +00:00
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
|
|
|
|
expect(currentApprovalsReviewer(snapshot, snapshotConfig(snapshot))).toBe("auto_review");
|
|
|
|
|
expect(requestedTurnCollaborationModeSettings(snapshot, snapshotConfig(snapshot))).not.toHaveProperty("approvalsReviewer");
|
2026-05-21 15:02:32 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-17 09:50:00 +00:00
|
|
|
it("treats active thread runtime as display state without persisting it into turn overrides", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
activeModel: "gpt-5-active",
|
|
|
|
|
activeServiceTier: "fast",
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({}),
|
2026-05-17 09:50:00 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBe("gpt-5-active");
|
|
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
|
|
|
expect(requestedTurnCollaborationModeSettings(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
2026-05-17 09:50:00 +00:00
|
|
|
collaborationMode: {
|
|
|
|
|
mode: "default",
|
|
|
|
|
settings: { model: "gpt-5-active" },
|
|
|
|
|
},
|
|
|
|
|
});
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(requestedTurnCollaborationModeSettings(snapshot, snapshotConfig(snapshot))).not.toHaveProperty("model");
|
|
|
|
|
expect(requestedTurnCollaborationModeSettings(snapshot, snapshotConfig(snapshot))).not.toHaveProperty("effort");
|
2026-05-17 09:50:00 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-22 01:23:10 +00:00
|
|
|
it("separates effective runtime, config defaults, and pending changes in status details", () => {
|
2026-06-10 02:04:30 +00:00
|
|
|
const sections = runtimeConfigSections(
|
2026-05-22 01:23:10 +00:00
|
|
|
runtimeSnapshot({
|
|
|
|
|
activeModel: "gpt-5-active",
|
|
|
|
|
activeReasoningEffort: "low",
|
|
|
|
|
activeCollaborationMode: "plan",
|
2026-06-01 02:07:59 +00:00
|
|
|
selectedCollaborationMode: "plan",
|
|
|
|
|
requestedModel: setPendingRuntimeSetting("gpt-5-pending"),
|
2026-05-22 01:23:10 +00:00
|
|
|
}),
|
|
|
|
|
"/vault",
|
|
|
|
|
);
|
|
|
|
|
const runtimeRows = Object.fromEntries(
|
|
|
|
|
sections.find((section) => section.title === "Runtime")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(runtimeRows).toMatchObject({
|
2026-05-27 05:48:26 +00:00
|
|
|
"effective model": "gpt-5-pending",
|
|
|
|
|
"configured model": "gpt-5.5",
|
|
|
|
|
"thread model": "gpt-5-active",
|
|
|
|
|
"requested model": "gpt-5-pending",
|
|
|
|
|
"effective effort": "low",
|
|
|
|
|
"configured effort": "high",
|
|
|
|
|
"thread effort": "low",
|
|
|
|
|
"requested effort": "(none)",
|
|
|
|
|
"effective mode": "Plan",
|
|
|
|
|
"requested mode": "(none)",
|
2026-05-28 09:16:54 +00:00
|
|
|
"configured service tier": "flex",
|
2026-05-27 05:48:26 +00:00
|
|
|
"thread service tier": "(not reported)",
|
|
|
|
|
"requested service tier": "(none)",
|
2026-05-22 01:23:10 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-10 02:04:30 +00:00
|
|
|
const resetSections = runtimeConfigSections(
|
2026-05-22 01:23:10 +00:00
|
|
|
runtimeSnapshot({
|
2026-06-01 02:07:59 +00:00
|
|
|
requestedReasoningEffort: resetRuntimeSettingToConfig(),
|
2026-05-22 01:23:10 +00:00
|
|
|
}),
|
|
|
|
|
"/vault",
|
|
|
|
|
);
|
|
|
|
|
const resetRuntimeRows = Object.fromEntries(
|
|
|
|
|
resetSections.find((section) => section.title === "Runtime")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
2026-05-27 05:48:26 +00:00
|
|
|
expect(resetRuntimeRows["requested effort"]).toBe("(reset to config)");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("labels unset config values as Codex defaults when no concrete value is reported", () => {
|
2026-06-10 02:04:30 +00:00
|
|
|
const sections = runtimeConfigSections(
|
2026-05-27 05:48:26 +00:00
|
|
|
runtimeSnapshot({
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({}),
|
2026-05-27 05:48:26 +00:00
|
|
|
}),
|
|
|
|
|
"/vault",
|
|
|
|
|
);
|
|
|
|
|
const scopeRows = Object.fromEntries(
|
|
|
|
|
sections.find((section) => section.title === "Scope")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
|
|
|
|
const runtimeRows = Object.fromEntries(
|
|
|
|
|
sections.find((section) => section.title === "Runtime")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
|
|
|
|
const policyRows = Object.fromEntries(
|
|
|
|
|
sections.find((section) => section.title === "Policy")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(scopeRows["model provider"]).toBe("(Codex default)");
|
|
|
|
|
expect(runtimeRows).toMatchObject({
|
|
|
|
|
"effective model": "(Codex default)",
|
|
|
|
|
"configured model": "(not reported)",
|
|
|
|
|
"thread model": "(not reported)",
|
|
|
|
|
"requested model": "(none)",
|
|
|
|
|
"configured service tier": "(Codex default)",
|
|
|
|
|
"thread service tier": "(not reported)",
|
|
|
|
|
"requested service tier": "(none)",
|
|
|
|
|
"fast mode": "Codex default",
|
|
|
|
|
});
|
|
|
|
|
expect(policyRows).toMatchObject({
|
2026-05-28 09:29:21 +00:00
|
|
|
"effective approval": "(Codex default)",
|
|
|
|
|
"configured approval": "(Codex default)",
|
|
|
|
|
"thread approval": "(not reported)",
|
|
|
|
|
"active permissions": "(not reported)",
|
2026-05-27 05:48:26 +00:00
|
|
|
"configured reviewer": "(Codex default)",
|
|
|
|
|
sandbox: "(Codex default)",
|
|
|
|
|
"web search": "(Codex default)",
|
|
|
|
|
});
|
2026-05-22 01:23:10 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 10:09:28 +00:00
|
|
|
it("uses catalog default reasoning efforts from model metadata", () => {
|
2026-06-09 02:34:15 +00:00
|
|
|
const model = { ...modelFixture("gpt-catalog-default"), isDefault: true, defaultReasoningEffort: "extreme" };
|
2026-06-10 02:04:30 +00:00
|
|
|
const sections = runtimeConfigSections(
|
2026-06-09 02:34:15 +00:00
|
|
|
runtimeSnapshot({
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({}),
|
2026-06-09 02:34:15 +00:00
|
|
|
availableModels: [model],
|
|
|
|
|
}),
|
|
|
|
|
"/vault",
|
|
|
|
|
);
|
|
|
|
|
const runtimeRows = Object.fromEntries(
|
|
|
|
|
sections.find((section) => section.title === "Runtime")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(runtimeRows["configured model"]).toBe("gpt-catalog-default");
|
2026-06-11 10:09:28 +00:00
|
|
|
expect(runtimeRows["configured effort"]).toBe("extreme");
|
2026-06-09 02:34:15 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
it("uses the explicit config when finding supported reasoning efforts", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
requestedModel: resetRuntimeSettingToConfig(),
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({ model: "snapshot-model" }),
|
|
|
|
|
availableModels: [
|
|
|
|
|
{ ...modelFixture("snapshot-model"), supportedReasoningEfforts: ["low"] },
|
|
|
|
|
{ ...modelFixture("explicit-model"), supportedReasoningEfforts: ["high"] },
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
const explicitConfig = runtimeConfigFixture({ model: "explicit-model" });
|
|
|
|
|
|
|
|
|
|
expect(supportedReasoningEfforts(snapshot, explicitConfig)).toEqual(["high"]);
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-27 05:33:07 +00:00
|
|
|
it("shows effective profile runtime and policy values in status details", () => {
|
|
|
|
|
const profileConfig = {
|
|
|
|
|
model: "gpt-profile",
|
|
|
|
|
model_provider: "profile-provider",
|
|
|
|
|
model_reasoning_effort: "high",
|
|
|
|
|
model_reasoning_summary: "detailed",
|
|
|
|
|
model_verbosity: "high",
|
|
|
|
|
approval_policy: "never",
|
|
|
|
|
approvals_reviewer: "auto_review",
|
|
|
|
|
web_search: "live",
|
|
|
|
|
service_tier: "fast",
|
|
|
|
|
};
|
2026-06-10 02:04:30 +00:00
|
|
|
const sections = runtimeConfigSections(
|
2026-05-22 03:30:45 +00:00
|
|
|
runtimeSnapshot({
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture(profileConfig, [configLayer({}, null), configLayer(profileConfig, "auto")]),
|
2026-05-22 03:30:45 +00:00
|
|
|
}),
|
|
|
|
|
"/vault",
|
|
|
|
|
);
|
|
|
|
|
const scopeRows = Object.fromEntries(
|
|
|
|
|
sections.find((section) => section.title === "Scope")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
|
|
|
|
const runtimeRows = Object.fromEntries(
|
|
|
|
|
sections.find((section) => section.title === "Runtime")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
|
|
|
|
const policyRows = Object.fromEntries(
|
|
|
|
|
sections.find((section) => section.title === "Policy")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
|
|
|
|
|
2026-05-27 05:33:07 +00:00
|
|
|
expect(scopeRows["profile"]).toBe("auto");
|
2026-05-22 03:30:45 +00:00
|
|
|
expect(scopeRows["model provider"]).toBe("profile-provider");
|
|
|
|
|
expect(runtimeRows).toMatchObject({
|
2026-05-27 05:48:26 +00:00
|
|
|
"effective model": "gpt-profile",
|
|
|
|
|
"configured model": "gpt-profile",
|
|
|
|
|
"thread model": "(not reported)",
|
|
|
|
|
"requested model": "(none)",
|
|
|
|
|
"effective effort": "high",
|
|
|
|
|
"configured effort": "high",
|
|
|
|
|
"thread effort": "(not reported)",
|
|
|
|
|
"requested effort": "(none)",
|
2026-05-22 03:30:45 +00:00
|
|
|
"reasoning summary": "detailed",
|
|
|
|
|
verbosity: "high",
|
2026-05-27 05:48:26 +00:00
|
|
|
"effective service tier": "fast",
|
|
|
|
|
"configured service tier": "fast",
|
|
|
|
|
"thread service tier": "(not reported)",
|
|
|
|
|
"requested service tier": "(none)",
|
2026-05-22 03:30:45 +00:00
|
|
|
"fast mode": "on",
|
|
|
|
|
});
|
2026-05-28 09:29:21 +00:00
|
|
|
expect(policyRows["effective approval"]).toBe("never");
|
|
|
|
|
expect(policyRows["configured approval"]).toBe("never");
|
|
|
|
|
expect(policyRows["thread approval"]).toBe("(not reported)");
|
|
|
|
|
expect(policyRows["active permissions"]).toBe("(not reported)");
|
2026-05-27 05:48:26 +00:00
|
|
|
expect(policyRows["effective reviewer"]).toBe("auto_review");
|
2026-05-22 03:30:45 +00:00
|
|
|
expect(policyRows["auto-review"]).toBe("on");
|
2026-05-27 05:48:26 +00:00
|
|
|
expect(policyRows["configured reviewer"]).toBe("auto_review");
|
|
|
|
|
expect(policyRows["thread reviewer"]).toBe("(not reported)");
|
|
|
|
|
expect(policyRows["requested reviewer"]).toBe("(none)");
|
2026-05-22 03:30:45 +00:00
|
|
|
expect(policyRows["web search"]).toBe("live");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("shows active and configured reviewer inputs in status details", () => {
|
2026-06-10 02:04:30 +00:00
|
|
|
const sections = runtimeConfigSections(
|
2026-05-22 03:30:45 +00:00
|
|
|
runtimeSnapshot({
|
|
|
|
|
activeApprovalsReviewer: "guardian_subagent",
|
2026-05-28 09:29:21 +00:00
|
|
|
activeApprovalPolicy: "never",
|
|
|
|
|
activePermissionProfile: { id: ":workspace", extends: ":default" },
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "auto_review" }),
|
2026-05-22 03:30:45 +00:00
|
|
|
}),
|
|
|
|
|
"/vault",
|
|
|
|
|
);
|
|
|
|
|
const policyRows = Object.fromEntries(
|
|
|
|
|
sections.find((section) => section.title === "Policy")?.rows.map((row) => [row.key, row.value]) ?? [],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(policyRows).toMatchObject({
|
2026-05-28 09:29:21 +00:00
|
|
|
"effective approval": "never",
|
|
|
|
|
"thread approval": "never",
|
|
|
|
|
"active permissions": ":workspace extends :default",
|
2026-05-27 05:48:26 +00:00
|
|
|
"effective reviewer": "guardian_subagent",
|
2026-05-22 03:30:45 +00:00
|
|
|
"auto-review": "on",
|
2026-05-27 05:48:26 +00:00
|
|
|
"configured reviewer": "auto_review",
|
|
|
|
|
"thread reviewer": "guardian_subagent",
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-12 15:05:56 +00:00
|
|
|
it("summarizes service tier and context meter state from one runtime snapshot", () => {
|
2026-06-01 02:07:59 +00:00
|
|
|
const snapshot = runtimeSnapshot({ requestedServiceTier: setPendingRuntimeSetting("fast"), activeThreadId: "thread" });
|
2026-05-12 15:05:56 +00:00
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(serviceTierLabel(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("on");
|
2026-05-12 15:05:56 +00:00
|
|
|
expect(contextSummary(snapshot)).toMatchObject({
|
|
|
|
|
label: "Context 0%",
|
2026-05-25 02:48:22 +00:00
|
|
|
title: "Context: 0 / 100,000 (0%). No turns in this thread yet.",
|
2026-05-12 15:05:56 +00:00
|
|
|
percent: 0,
|
|
|
|
|
level: "ok",
|
|
|
|
|
});
|
2026-05-25 02:48:22 +00:00
|
|
|
expect(
|
|
|
|
|
contextSummary(
|
|
|
|
|
runtimeSnapshot({
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
tokenUsage: {
|
|
|
|
|
last: { inputTokens: 1000, cachedInputTokens: 0, outputTokens: 200, reasoningOutputTokens: 50, totalTokens: 1250 },
|
|
|
|
|
total: { inputTokens: 2000, cachedInputTokens: 0, outputTokens: 500, reasoningOutputTokens: 100, totalTokens: 2600 },
|
|
|
|
|
modelContextWindow: 100_000,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
),
|
|
|
|
|
).toMatchObject({
|
|
|
|
|
title: "Context: 1,000 / 100,000 (1%). Last request: 1,000 input, 200 output, 50 reasoning. Total: 2,600 tokens.",
|
|
|
|
|
});
|
2026-05-12 15:05:56 +00:00
|
|
|
expect(
|
|
|
|
|
contextSummary(
|
|
|
|
|
runtimeSnapshot({
|
|
|
|
|
activeThreadId: "thread",
|
2026-05-26 00:54:45 +00:00
|
|
|
hasThreadTurns: true,
|
2026-05-12 15:05:56 +00:00
|
|
|
}),
|
|
|
|
|
),
|
|
|
|
|
).toMatchObject({
|
|
|
|
|
label: "Context unknown",
|
|
|
|
|
percent: null,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("serializes explicit fast off as a null service tier request", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
2026-06-01 02:07:59 +00:00
|
|
|
requestedServiceTier: setPendingRuntimeSetting("off"),
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(serviceTierLabel(snapshot, snapshotConfig(snapshot))).toBe("(Codex default)");
|
|
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("off");
|
|
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBeNull();
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 11:31:47 +00:00
|
|
|
it("serializes service tier reset for thread start as an explicit null request", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
|
|
|
|
requestedServiceTier: resetRuntimeSettingToConfig(),
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(serviceTierLabel(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("on");
|
|
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBeNull();
|
2026-06-11 11:31:47 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-29 00:44:25 +00:00
|
|
|
it("serializes requested fast mode using the catalog Fast service tier id", () => {
|
|
|
|
|
const model = modelFixture("gpt-5.5");
|
2026-06-09 02:34:15 +00:00
|
|
|
model.serviceTiers = [{ id: "priority", name: "Fast" }];
|
2026-05-29 00:44:25 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-01 02:07:59 +00:00
|
|
|
requestedServiceTier: setPendingRuntimeSetting("fast"),
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
|
2026-05-29 00:44:25 +00:00
|
|
|
availableModels: [model],
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("on");
|
|
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBe("priority");
|
2026-05-29 00:44:25 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-12 15:05:56 +00:00
|
|
|
it("omits service tier when neither config nor override selects one", () => {
|
2026-06-11 15:03:23 +00:00
|
|
|
const snapshot = runtimeSnapshot({ runtimeConfig: runtimeConfigFixture({}) });
|
|
|
|
|
|
|
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBeUndefined();
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-28 09:16:54 +00:00
|
|
|
it("passes through configured non-fast service tier ids", () => {
|
2026-06-10 02:04:30 +00:00
|
|
|
const snapshot = runtimeSnapshot({ runtimeConfig: runtimeConfigFixture({ service_tier: "flex" }) });
|
2026-05-28 09:16:54 +00:00
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(serviceTierLabel(snapshot, snapshotConfig(snapshot))).toBe("flex");
|
|
|
|
|
expect(fastModeLabel(snapshot, snapshotConfig(snapshot))).toBe("off");
|
|
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBe("flex");
|
2026-05-28 09:16:54 +00:00
|
|
|
});
|
|
|
|
|
|
2026-05-12 15:05:56 +00:00
|
|
|
it("summarizes Codex usage limits independently from context usage", () => {
|
|
|
|
|
expect(
|
|
|
|
|
rateLimitSummary(
|
|
|
|
|
runtimeSnapshot({
|
|
|
|
|
rateLimit: {
|
|
|
|
|
limitId: "codex",
|
|
|
|
|
limitName: "Codex",
|
|
|
|
|
primary: { usedPercent: 72.4, windowDurationMins: 300, resetsAt: 1_800_000_000 },
|
|
|
|
|
secondary: null,
|
2026-06-04 02:54:53 +00:00
|
|
|
individualLimit: null,
|
2026-05-12 15:05:56 +00:00
|
|
|
rateLimitReachedType: null,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
1_799_991_600_000,
|
|
|
|
|
),
|
|
|
|
|
).toMatchObject({
|
2026-06-04 03:15:31 +00:00
|
|
|
rows: [{ label: "5h", value: "72%", resetLabel: "reset in 2h 20m", percent: 72, meterDivisions: 5 }],
|
2026-05-12 15:05:56 +00:00
|
|
|
level: "warn",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(
|
|
|
|
|
rateLimitSummary(
|
|
|
|
|
runtimeSnapshot({
|
|
|
|
|
rateLimit: {
|
|
|
|
|
limitId: "codex",
|
|
|
|
|
limitName: null,
|
|
|
|
|
primary: { usedPercent: 95, windowDurationMins: null, resetsAt: null },
|
|
|
|
|
secondary: null,
|
2026-06-04 02:54:53 +00:00
|
|
|
individualLimit: null,
|
2026-05-12 15:05:56 +00:00
|
|
|
rateLimitReachedType: "rate_limit_reached",
|
|
|
|
|
},
|
|
|
|
|
}),
|
2026-06-12 01:28:07 +00:00
|
|
|
0,
|
2026-05-12 15:05:56 +00:00
|
|
|
),
|
|
|
|
|
).toMatchObject({
|
|
|
|
|
rows: [{ percent: 95, resetLabel: null }],
|
|
|
|
|
level: "danger",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(
|
|
|
|
|
rateLimitSummary(
|
|
|
|
|
runtimeSnapshot({
|
|
|
|
|
rateLimit: {
|
|
|
|
|
limitId: "codex",
|
|
|
|
|
limitName: "Codex",
|
|
|
|
|
primary: { usedPercent: 15, windowDurationMins: 300, resetsAt: null },
|
|
|
|
|
secondary: { usedPercent: 38, windowDurationMins: 10_080, resetsAt: null },
|
2026-06-04 02:54:53 +00:00
|
|
|
individualLimit: null,
|
2026-05-12 15:05:56 +00:00
|
|
|
rateLimitReachedType: null,
|
|
|
|
|
},
|
|
|
|
|
}),
|
2026-06-12 01:28:07 +00:00
|
|
|
0,
|
2026-05-12 15:05:56 +00:00
|
|
|
),
|
|
|
|
|
).toMatchObject({
|
|
|
|
|
rows: [
|
2026-06-04 03:15:31 +00:00
|
|
|
{ label: "5h", value: "15%", meterDivisions: 5 },
|
|
|
|
|
{ label: "1w", value: "38%", meterDivisions: 7 },
|
2026-05-12 15:05:56 +00:00
|
|
|
],
|
|
|
|
|
level: "ok",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(
|
|
|
|
|
rateLimitSummary(
|
|
|
|
|
runtimeSnapshot({
|
|
|
|
|
rateLimit: {
|
|
|
|
|
limitId: "codex",
|
|
|
|
|
limitName: "Codex",
|
|
|
|
|
primary: { usedPercent: 10, windowDurationMins: 300, resetsAt: 1_800_000_000 },
|
|
|
|
|
secondary: null,
|
2026-06-04 02:54:53 +00:00
|
|
|
individualLimit: null,
|
2026-05-12 15:05:56 +00:00
|
|
|
rateLimitReachedType: null,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
1_800_000_001_000,
|
|
|
|
|
),
|
|
|
|
|
).toMatchObject({
|
|
|
|
|
rows: [{ resetLabel: "reset due" }],
|
|
|
|
|
});
|
2026-06-04 02:54:53 +00:00
|
|
|
|
|
|
|
|
expect(
|
|
|
|
|
rateLimitSummary(
|
|
|
|
|
runtimeSnapshot({
|
|
|
|
|
rateLimit: {
|
|
|
|
|
limitId: "codex",
|
|
|
|
|
limitName: "Codex",
|
|
|
|
|
primary: null,
|
|
|
|
|
secondary: null,
|
|
|
|
|
individualLimit: { limit: "$100", used: "$72", remainingPercent: 28, resetsAt: 1_800_000_000 },
|
|
|
|
|
rateLimitReachedType: null,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
1_799_991_600_000,
|
|
|
|
|
),
|
|
|
|
|
).toMatchObject({
|
2026-06-04 03:15:31 +00:00
|
|
|
rows: [{ label: "monthly", value: "$72 / $100", resetLabel: "reset in 2h 20m", percent: 72, meterDivisions: null }],
|
2026-06-04 02:54:53 +00:00
|
|
|
level: "warn",
|
|
|
|
|
});
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function runtimeSnapshot(overrides: Partial<RuntimeSnapshot> = {}): RuntimeSnapshot {
|
|
|
|
|
return {
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({
|
2026-05-22 23:37:26 +00:00
|
|
|
model: "gpt-5.5",
|
|
|
|
|
model_reasoning_effort: "high",
|
2026-05-28 09:16:54 +00:00
|
|
|
service_tier: "flex",
|
2026-05-22 23:37:26 +00:00
|
|
|
model_context_window: 100_000,
|
|
|
|
|
}),
|
2026-05-12 15:05:56 +00:00
|
|
|
activeThreadId: null,
|
|
|
|
|
activeModel: null,
|
2026-05-22 00:57:01 +00:00
|
|
|
activeReasoningEffort: null,
|
|
|
|
|
activeCollaborationMode: "default",
|
2026-05-12 15:05:56 +00:00
|
|
|
activeServiceTier: null,
|
2026-05-28 09:29:21 +00:00
|
|
|
activeApprovalPolicy: null,
|
2026-05-21 15:02:32 +00:00
|
|
|
activeApprovalsReviewer: null,
|
2026-05-28 09:29:21 +00:00
|
|
|
activePermissionProfile: null,
|
2026-06-01 02:07:59 +00:00
|
|
|
requestedModel: { kind: "unchanged" },
|
|
|
|
|
requestedReasoningEffort: { kind: "unchanged" },
|
|
|
|
|
requestedApprovalsReviewer: { kind: "unchanged" },
|
|
|
|
|
selectedCollaborationMode: "default",
|
|
|
|
|
requestedServiceTier: { kind: "unchanged" },
|
2026-05-12 15:05:56 +00:00
|
|
|
tokenUsage: null,
|
|
|
|
|
rateLimit: null,
|
2026-05-26 00:54:45 +00:00
|
|
|
hasThreadTurns: false,
|
2026-05-12 15:05:56 +00:00
|
|
|
availableModels: [],
|
|
|
|
|
...overrides,
|
|
|
|
|
};
|
|
|
|
|
}
|
2026-05-22 23:37:26 +00:00
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
function snapshotConfig(snapshot: RuntimeSnapshot): RuntimeConfigSnapshot {
|
|
|
|
|
return runtimeConfigOrDefault(snapshot.runtimeConfig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function runtimeConfigFixture(
|
|
|
|
|
config: Record<string, unknown>,
|
|
|
|
|
layers: AppServerConfigReadResponse["layers"] = null,
|
|
|
|
|
): RuntimeConfigSnapshot {
|
2026-06-10 02:04:30 +00:00
|
|
|
return runtimeConfigSnapshotFromAppServerConfig({
|
2026-06-11 15:03:23 +00:00
|
|
|
config: config as AppServerConfigReadResponse["config"],
|
2026-05-22 23:37:26 +00:00
|
|
|
origins: {},
|
|
|
|
|
layers,
|
2026-06-10 02:04:30 +00:00
|
|
|
});
|
2026-05-22 23:37:26 +00:00
|
|
|
}
|
2026-05-27 05:33:07 +00:00
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
function configLayer(config: Record<string, unknown>, profile: string | null): NonNullable<AppServerConfigReadResponse["layers"]>[number] {
|
2026-05-27 05:33:07 +00:00
|
|
|
return {
|
|
|
|
|
name: { type: "user", file: "/home/me/.codex/config.toml", profile },
|
|
|
|
|
version: "1",
|
2026-06-11 15:03:23 +00:00
|
|
|
config: config as NonNullable<AppServerConfigReadResponse["layers"]>[number]["config"],
|
2026-05-27 05:33:07 +00:00
|
|
|
disabledReason: null,
|
|
|
|
|
};
|
|
|
|
|
}
|
2026-05-28 13:15:15 +00:00
|
|
|
|
2026-06-09 14:39:58 +00:00
|
|
|
function modelFixture(model: string): ModelMetadata {
|
2026-05-28 13:15:15 +00:00
|
|
|
return {
|
|
|
|
|
id: model,
|
|
|
|
|
model,
|
|
|
|
|
displayName: model,
|
|
|
|
|
description: "",
|
|
|
|
|
hidden: false,
|
|
|
|
|
supportedReasoningEfforts: [],
|
|
|
|
|
defaultReasoningEffort: "medium",
|
|
|
|
|
inputModalities: [],
|
|
|
|
|
additionalSpeedTiers: [],
|
|
|
|
|
serviceTiers: [],
|
|
|
|
|
defaultServiceTier: null,
|
|
|
|
|
isDefault: false,
|
|
|
|
|
};
|
|
|
|
|
}
|