2026-05-12 15:05:56 +00:00
|
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
|
|
2026-06-24 05:44:16 +00:00
|
|
|
import { type ConfigReadResult, runtimeConfigSnapshotFromAppServerConfig } from "../../src/app-server/protocol/runtime-config";
|
2026-06-09 14:39:58 +00:00
|
|
|
import type { ModelMetadata } from "../../src/domain/catalog/metadata";
|
2026-06-26 12:36:35 +00:00
|
|
|
import { type RuntimeConfigSnapshot, runtimeConfigOrDefault } from "../../src/domain/runtime/config";
|
2026-07-01 11:14:57 +00:00
|
|
|
import {
|
|
|
|
|
resetRuntimeIntentToConfig,
|
|
|
|
|
setCollaborationModeIntent,
|
|
|
|
|
setRuntimeIntentValue,
|
|
|
|
|
unchangedCollaborationModeIntent,
|
2026-07-06 05:24:07 +00:00
|
|
|
unchangedRuntimeIntent,
|
2026-07-01 11:14:57 +00:00
|
|
|
} from "../../src/features/chat/domain/runtime/intent";
|
2026-06-11 15:03:23 +00:00
|
|
|
import {
|
2026-06-24 05:44:16 +00:00
|
|
|
compactReasoningEffortLabel,
|
|
|
|
|
modelOverrideMessage,
|
|
|
|
|
reasoningEffortOverrideMessage,
|
|
|
|
|
} from "../../src/features/chat/domain/runtime/labels";
|
|
|
|
|
import { resolveRuntimeControls } from "../../src/features/chat/domain/runtime/resolution";
|
|
|
|
|
import type { RuntimeSnapshot } from "../../src/features/chat/domain/runtime/snapshot";
|
2026-06-27 08:11:25 +00:00
|
|
|
import {
|
|
|
|
|
pendingRuntimeSettingsPatch,
|
2026-07-02 04:43:19 +00:00
|
|
|
permissionProfileRequestForThreadStart,
|
2026-06-27 08:11:25 +00:00
|
|
|
serviceTierRequestForThreadStart,
|
|
|
|
|
} from "../../src/features/chat/domain/runtime/thread-settings-patch";
|
2026-07-09 17:07:34 +00:00
|
|
|
import { contextSummary, rateLimitSummary, statusDetails } from "../../src/features/chat/presentation/runtime/status";
|
2026-05-12 15:05:56 +00:00
|
|
|
|
2026-06-14 20:57:32 +00:00
|
|
|
describe("runtime settings", () => {
|
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(compactReasoningEffortLabel("minimal")).toBe("min");
|
|
|
|
|
expect(compactReasoningEffortLabel("high")).toBe("high");
|
|
|
|
|
expect(compactReasoningEffortLabel(null)).toBe("default");
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-01 03:01:36 +00:00
|
|
|
it("keeps startup permission defaults in the runtime config snapshot", () => {
|
|
|
|
|
expect(
|
|
|
|
|
runtimeConfigFixture({
|
|
|
|
|
default_permissions: ":workspace",
|
|
|
|
|
approval_policy: "on-request",
|
|
|
|
|
approvals_reviewer: "auto_review",
|
|
|
|
|
}),
|
|
|
|
|
).toMatchObject({
|
|
|
|
|
approvalsReviewer: "auto_review",
|
|
|
|
|
startupPermissions: {
|
|
|
|
|
activePermissionProfile: { id: ":workspace", extends: null },
|
|
|
|
|
approvalPolicy: "on-request",
|
|
|
|
|
sandboxPolicy: null,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("deep-clones granular startup approval policy in runtime config snapshots", () => {
|
|
|
|
|
const config = runtimeConfigFixture({
|
|
|
|
|
approval_policy: {
|
|
|
|
|
granular: {
|
|
|
|
|
sandbox_approval: true,
|
|
|
|
|
rules: false,
|
|
|
|
|
skill_approval: true,
|
|
|
|
|
request_permissions: false,
|
|
|
|
|
mcp_elicitations: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const cloned = runtimeConfigOrDefault(config);
|
|
|
|
|
const originalPolicy = config.startupPermissions.approvalPolicy;
|
|
|
|
|
const clonedPolicy = cloned.startupPermissions.approvalPolicy;
|
|
|
|
|
|
|
|
|
|
expect(clonedPolicy).toEqual(originalPolicy);
|
|
|
|
|
if (!originalPolicy || typeof originalPolicy === "string" || !clonedPolicy || typeof clonedPolicy === "string") {
|
|
|
|
|
throw new Error("expected granular approval policy");
|
|
|
|
|
}
|
|
|
|
|
expect(clonedPolicy).not.toBe(originalPolicy);
|
|
|
|
|
expect(clonedPolicy.granular).not.toBe(originalPolicy.granular);
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-02 04:43:19 +00:00
|
|
|
it("keeps default permissions separate from legacy sandbox fields", () => {
|
|
|
|
|
expect(
|
|
|
|
|
runtimeConfigFixture({
|
|
|
|
|
default_permissions: "DevProfile",
|
|
|
|
|
approval_policy: "on-request",
|
|
|
|
|
sandbox_mode: "workspace-write",
|
|
|
|
|
sandbox_workspace_write: {
|
|
|
|
|
writable_roots: ["/vault"],
|
|
|
|
|
network_access: false,
|
|
|
|
|
exclude_tmpdir_env_var: false,
|
|
|
|
|
exclude_slash_tmp: false,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
).toMatchObject({
|
|
|
|
|
startupPermissions: {
|
|
|
|
|
activePermissionProfile: { id: "DevProfile", extends: null },
|
|
|
|
|
approvalPolicy: "on-request",
|
|
|
|
|
sandboxPolicy: null,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("uses legacy sandbox config when default permissions are not reported", () => {
|
2026-07-01 03:01:36 +00:00
|
|
|
expect(
|
|
|
|
|
runtimeConfigFixture({
|
|
|
|
|
approval_policy: "on-request",
|
|
|
|
|
sandbox_mode: "workspace-write",
|
|
|
|
|
sandbox_workspace_write: {
|
|
|
|
|
writable_roots: ["/vault"],
|
|
|
|
|
network_access: false,
|
|
|
|
|
exclude_tmpdir_env_var: false,
|
|
|
|
|
exclude_slash_tmp: false,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
).toMatchObject({
|
|
|
|
|
startupPermissions: {
|
|
|
|
|
activePermissionProfile: null,
|
|
|
|
|
approvalPolicy: "on-request",
|
|
|
|
|
sandboxPolicy: {
|
|
|
|
|
type: "workspaceWrite",
|
|
|
|
|
writableRoots: ["/vault"],
|
|
|
|
|
networkAccess: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-01 10:13:45 +00:00
|
|
|
it("falls back to startup permissions until active thread permissions are reported", () => {
|
2026-07-01 03:01:36 +00:00
|
|
|
const configured = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
default_permissions: ":workspace",
|
|
|
|
|
approval_policy: "on-request",
|
|
|
|
|
}),
|
|
|
|
|
});
|
2026-07-01 10:13:45 +00:00
|
|
|
expect(resolveRuntimeControls(configured, snapshotConfig(configured))).toMatchObject({
|
|
|
|
|
permissionProfile: { effective: ":workspace", source: "config" },
|
|
|
|
|
sandboxPolicy: { effective: null, source: "none" },
|
|
|
|
|
approvalPolicy: { effective: "on-request", source: "config" },
|
2026-07-01 03:01:36 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const activeUnreported = runtimeSnapshot({
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
default_permissions: ":workspace",
|
|
|
|
|
approval_policy: "on-request",
|
|
|
|
|
}),
|
|
|
|
|
});
|
2026-07-01 10:13:45 +00:00
|
|
|
expect(resolveRuntimeControls(activeUnreported, snapshotConfig(activeUnreported))).toMatchObject({
|
|
|
|
|
permissionProfile: { configured: ":workspace", active: null, effective: ":workspace", source: "config" },
|
|
|
|
|
sandboxPolicy: { configured: null, active: null, effective: null, source: "none" },
|
|
|
|
|
approvalPolicy: { configured: "on-request", active: null, effective: "on-request", source: "config" },
|
2026-07-01 03:01:36 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const activeReported = runtimeSnapshot({
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
active: {
|
2026-07-01 10:13:45 +00:00
|
|
|
approvalPolicyKnown: true,
|
|
|
|
|
sandboxPolicyKnown: true,
|
|
|
|
|
permissionProfileKnown: true,
|
2026-07-01 03:01:36 +00:00
|
|
|
approvalPolicy: "never",
|
|
|
|
|
sandboxPolicy: { type: "readOnly", networkAccess: false },
|
|
|
|
|
activePermissionProfile: { id: ":read-only", extends: null },
|
|
|
|
|
approvalsReviewer: "user",
|
|
|
|
|
},
|
2026-07-01 07:30:04 +00:00
|
|
|
pending: { approvalsReviewer: setRuntimeIntentValue("auto_review") },
|
2026-07-01 03:01:36 +00:00
|
|
|
});
|
2026-07-01 07:30:04 +00:00
|
|
|
expect(resolveRuntimeControls(activeReported, snapshotConfig(activeReported))).toMatchObject({
|
|
|
|
|
approvalsReviewer: { effective: "auto_review", source: "pending" },
|
2026-07-01 10:13:45 +00:00
|
|
|
permissionProfile: { effective: ":read-only", source: "active-thread" },
|
|
|
|
|
sandboxPolicy: { effective: { type: "readOnly", networkAccess: false }, source: "active-thread" },
|
|
|
|
|
approvalPolicy: { effective: "never", source: "active-thread" },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const approvalOnlyReported = runtimeSnapshot({
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
default_permissions: ":workspace",
|
|
|
|
|
approval_policy: "on-request",
|
|
|
|
|
}),
|
|
|
|
|
active: {
|
|
|
|
|
approvalPolicyKnown: true,
|
|
|
|
|
approvalPolicy: "never",
|
2026-07-01 03:01:36 +00:00
|
|
|
},
|
|
|
|
|
});
|
2026-07-01 10:13:45 +00:00
|
|
|
expect(resolveRuntimeControls(approvalOnlyReported, snapshotConfig(approvalOnlyReported))).toMatchObject({
|
|
|
|
|
permissionProfile: { effective: ":workspace", source: "config" },
|
|
|
|
|
sandboxPolicy: { effective: null, source: "none" },
|
|
|
|
|
approvalPolicy: { effective: "never", source: "active-thread" },
|
|
|
|
|
});
|
2026-07-01 03:01:36 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("keeps permission display scope separate from pending permission source", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
active: {
|
2026-07-01 10:13:45 +00:00
|
|
|
approvalPolicyKnown: true,
|
|
|
|
|
sandboxPolicyKnown: true,
|
|
|
|
|
permissionProfileKnown: true,
|
2026-07-01 03:01:36 +00:00
|
|
|
approvalPolicy: "on-request",
|
|
|
|
|
sandboxPolicy: { type: "readOnly", networkAccess: false },
|
|
|
|
|
activePermissionProfile: null,
|
|
|
|
|
},
|
|
|
|
|
pending: {
|
2026-07-01 07:30:04 +00:00
|
|
|
approvalPolicy: setRuntimeIntentValue("never"),
|
|
|
|
|
permissionProfile: setRuntimeIntentValue(":workspace"),
|
2026-07-01 03:01:36 +00:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-01 10:13:45 +00:00
|
|
|
expect(resolveRuntimeControls(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
|
|
|
permissionProfile: { effective: ":workspace", source: "pending" },
|
|
|
|
|
sandboxPolicy: { effective: null, source: "pending" },
|
|
|
|
|
approvalPolicy: { effective: "never", source: "pending" },
|
2026-07-01 03:01:36 +00:00
|
|
|
});
|
|
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
|
|
|
update: {
|
|
|
|
|
approvalPolicy: "never",
|
|
|
|
|
permissions: ":workspace",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("resolves permission profile reset intent back to legacy sandbox config", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
sandbox_mode: "workspace-write",
|
|
|
|
|
sandbox_workspace_write: {
|
|
|
|
|
writable_roots: ["/vault"],
|
|
|
|
|
network_access: false,
|
|
|
|
|
exclude_tmpdir_env_var: false,
|
|
|
|
|
exclude_slash_tmp: false,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
active: {
|
2026-07-01 10:13:45 +00:00
|
|
|
sandboxPolicyKnown: true,
|
|
|
|
|
permissionProfileKnown: true,
|
2026-07-01 03:01:36 +00:00
|
|
|
activePermissionProfile: { id: ":workspace", extends: null },
|
|
|
|
|
sandboxPolicy: null,
|
|
|
|
|
},
|
2026-07-01 07:30:04 +00:00
|
|
|
pending: { permissionProfile: resetRuntimeIntentToConfig() },
|
2026-07-01 03:01:36 +00:00
|
|
|
});
|
|
|
|
|
|
2026-07-01 10:13:45 +00:00
|
|
|
expect(resolveRuntimeControls(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
|
|
|
permissionProfile: { effective: null, source: "config" },
|
|
|
|
|
sandboxPolicy: {
|
|
|
|
|
effective: {
|
2026-07-01 03:01:36 +00:00
|
|
|
type: "workspaceWrite",
|
|
|
|
|
writableRoots: ["/vault"],
|
|
|
|
|
networkAccess: false,
|
|
|
|
|
},
|
2026-07-01 10:13:45 +00:00
|
|
|
source: "config",
|
2026-07-01 03:01:36 +00:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
|
|
|
update: { permissions: null },
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-02 04:43:19 +00:00
|
|
|
it("selects config permission profiles for empty-panel thread starts", () => {
|
|
|
|
|
const configured = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
default_permissions: ":workspace",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(permissionProfileRequestForThreadStart(configured, snapshotConfig(configured))).toBe(":workspace");
|
|
|
|
|
|
|
|
|
|
const pending = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
default_permissions: ":workspace",
|
|
|
|
|
}),
|
|
|
|
|
pending: { permissionProfile: setRuntimeIntentValue(":read-only") },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(permissionProfileRequestForThreadStart(pending, snapshotConfig(pending))).toBe(":read-only");
|
|
|
|
|
|
|
|
|
|
const legacySandbox = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
sandbox_mode: "workspace-write",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(permissionProfileRequestForThreadStart(legacySandbox, snapshotConfig(legacySandbox))).toBeUndefined();
|
|
|
|
|
});
|
|
|
|
|
|
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-23 22:19:42 +00:00
|
|
|
pending: {
|
|
|
|
|
model: resetRuntimeIntentToConfig(),
|
|
|
|
|
reasoningEffort: resetRuntimeIntentToConfig(),
|
|
|
|
|
},
|
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");
|
2026-06-12 11:08:08 +00:00
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
2026-06-11 15:03:23 +00:00
|
|
|
update: { model: null, effort: null },
|
|
|
|
|
collaborationModeWarning: null,
|
|
|
|
|
});
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-21 08:55:23 +00:00
|
|
|
it("projects explicit runtime intents into current values and settings payload values", () => {
|
2026-05-12 15:05:56 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
pending: {
|
|
|
|
|
model: setRuntimeIntentValue("gpt-5.4"),
|
|
|
|
|
reasoningEffort: setRuntimeIntentValue("low"),
|
|
|
|
|
},
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
2026-06-23 22:19:42 +00:00
|
|
|
const resolution = resolveRuntimeControls(snapshot, snapshotConfig(snapshot));
|
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");
|
2026-06-23 22:19:42 +00:00
|
|
|
expect(resolution.model).toMatchObject({ effective: "gpt-5.4", source: "pending" });
|
|
|
|
|
expect(resolution.reasoningEffort).toMatchObject({ effective: "low", source: "pending" });
|
2026-06-12 11:08:08 +00:00
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
2026-06-11 15:03:23 +00:00
|
|
|
update: { model: "gpt-5.4", effort: "low" },
|
|
|
|
|
collaborationModeWarning: null,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-12 11:08:08 +00:00
|
|
|
it("treats unreported thread collaboration mode as default without losing the unknown state", () => {
|
2026-07-01 10:13:45 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
active: { collaborationMode: null },
|
|
|
|
|
});
|
2026-06-12 11:08:08 +00:00
|
|
|
|
2026-06-23 22:19:42 +00:00
|
|
|
expect(snapshot.active.collaborationMode).toBeNull();
|
2026-06-12 11:08:08 +00:00
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toEqual({
|
|
|
|
|
update: {},
|
|
|
|
|
collaborationModeWarning: null,
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-01 10:13:45 +00:00
|
|
|
expect(snapshot.pending.collaborationMode).toEqual({ kind: "unchanged" });
|
2026-06-12 11:08:08 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
it("keeps model reset tied to config when active thread model differs", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
active: { model: "gpt-5-active" },
|
|
|
|
|
pending: { model: resetRuntimeIntentToConfig() },
|
2026-06-11 15:03:23 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
model_reasoning_effort: "high",
|
|
|
|
|
service_tier: "flex",
|
|
|
|
|
model_context_window: 100_000,
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBeNull();
|
2026-06-12 11:08:08 +00:00
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
2026-06-11 15:03:23 +00:00
|
|
|
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({
|
2026-06-23 22:19:42 +00:00
|
|
|
pending: {
|
2026-07-01 11:14:57 +00:00
|
|
|
collaborationMode: setCollaborationModeIntent("plan"),
|
2026-06-23 22:19:42 +00:00
|
|
|
model: setRuntimeIntentValue("gpt-5.5"),
|
|
|
|
|
reasoningEffort: setRuntimeIntentValue("high"),
|
|
|
|
|
},
|
2026-06-11 15:03:23 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-14 20:57:32 +00:00
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
|
|
|
update: {
|
|
|
|
|
collaborationMode: {
|
|
|
|
|
mode: "plan",
|
|
|
|
|
settings: {
|
|
|
|
|
model: "gpt-5.5",
|
|
|
|
|
reasoningEffort: "high",
|
|
|
|
|
developerInstructions: null,
|
|
|
|
|
},
|
2026-06-08 00:33:13 +00:00
|
|
|
},
|
|
|
|
|
},
|
2026-06-14 20:57:32 +00:00
|
|
|
collaborationModeWarning: null,
|
2026-06-08 00:33:13 +00:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
it("uses the explicit config for collaboration mode thread settings", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
2026-07-01 11:14:57 +00:00
|
|
|
pending: { collaborationMode: setCollaborationModeIntent("plan") },
|
2026-06-11 15:03:23 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
model: "snapshot-model",
|
|
|
|
|
model_reasoning_effort: "low",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
const explicitConfig = runtimeConfigFixture({
|
|
|
|
|
model: "explicit-model",
|
|
|
|
|
model_reasoning_effort: "high",
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-12 11:08:08 +00:00
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, explicitConfig)).toMatchObject({
|
2026-06-11 15:03:23 +00:00
|
|
|
update: {
|
|
|
|
|
collaborationMode: {
|
|
|
|
|
mode: "plan",
|
|
|
|
|
settings: {
|
|
|
|
|
model: "explicit-model",
|
2026-06-12 11:08:08 +00:00
|
|
|
reasoningEffort: "high",
|
|
|
|
|
developerInstructions: null,
|
2026-06-11 15:03:23 +00:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
collaborationModeWarning: null,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-21 08:55:23 +00:00
|
|
|
it("keeps collaboration mode settings separate from reviewer and direct runtime intents", () => {
|
2026-06-14 20:57:32 +00:00
|
|
|
const reviewerSnapshot = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
pending: {
|
2026-07-01 11:14:57 +00:00
|
|
|
collaborationMode: setCollaborationModeIntent("plan"),
|
2026-07-01 07:30:04 +00:00
|
|
|
approvalsReviewer: setRuntimeIntentValue("auto_review"),
|
2026-06-23 22:19:42 +00:00
|
|
|
},
|
2026-06-14 20:57:32 +00:00
|
|
|
});
|
|
|
|
|
const activeRuntimeSnapshot = runtimeSnapshot({
|
2026-07-01 11:14:57 +00:00
|
|
|
pending: { collaborationMode: setCollaborationModeIntent("plan") },
|
2026-06-23 22:19:42 +00:00
|
|
|
active: { model: "gpt-5-active", serviceTier: "fast" },
|
2026-06-14 20:57:32 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(pendingRuntimeSettingsPatch(reviewerSnapshot, snapshotConfig(reviewerSnapshot))).toMatchObject({
|
|
|
|
|
update: {
|
|
|
|
|
approvalsReviewer: "auto_review",
|
|
|
|
|
collaborationMode: {
|
|
|
|
|
mode: "plan",
|
|
|
|
|
settings: { model: "gpt-5.5", reasoningEffort: "high" },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
expect(
|
|
|
|
|
pendingRuntimeSettingsPatch(reviewerSnapshot, snapshotConfig(reviewerSnapshot)).update.collaborationMode?.settings,
|
|
|
|
|
).not.toHaveProperty("approvalsReviewer");
|
|
|
|
|
expect(pendingRuntimeSettingsPatch(activeRuntimeSnapshot, snapshotConfig(activeRuntimeSnapshot))).toMatchObject({
|
|
|
|
|
update: {
|
|
|
|
|
collaborationMode: {
|
|
|
|
|
mode: "plan",
|
|
|
|
|
settings: { model: "gpt-5-active" },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
expect(pendingRuntimeSettingsPatch(activeRuntimeSnapshot, snapshotConfig(activeRuntimeSnapshot)).update).not.toHaveProperty("model");
|
|
|
|
|
expect(pendingRuntimeSettingsPatch(activeRuntimeSnapshot, snapshotConfig(activeRuntimeSnapshot)).update).not.toHaveProperty("effort");
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-15 22:39:07 +00:00
|
|
|
it("resolves auto-review mode from requested, active, then effective config", () => {
|
2026-06-11 15:03:23 +00:00
|
|
|
const requested = runtimeSnapshot({
|
2026-07-01 07:30:04 +00:00
|
|
|
pending: { approvalsReviewer: setRuntimeIntentValue("user") },
|
2026-06-23 22:19:42 +00:00
|
|
|
active: { approvalsReviewer: "auto_review" },
|
2026-06-11 15:03:23 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
|
|
|
|
});
|
|
|
|
|
const active = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
active: { approvalsReviewer: "user" },
|
2026-06-11 15:03:23 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
|
|
|
|
});
|
|
|
|
|
const configured = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-15 22:39:07 +00:00
|
|
|
expect(autoReviewActive(requested, snapshotConfig(requested))).toBe(false);
|
|
|
|
|
expect(autoReviewActive(active, snapshotConfig(active))).toBe(false);
|
|
|
|
|
expect(autoReviewActive(configured, snapshotConfig(configured))).toBe(true);
|
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({
|
2026-06-23 22:19:42 +00:00
|
|
|
active: { approvalsReviewer: "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(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({
|
2026-06-23 22:19:42 +00:00
|
|
|
active: { approvalsReviewer: "guardian_subagent" },
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
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-07-01 07:30:04 +00:00
|
|
|
pending: { approvalsReviewer: setRuntimeIntentValue("user") },
|
2026-06-23 22:19:42 +00:00
|
|
|
active: { approvalsReviewer: "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(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(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");
|
2026-06-15 06:29:09 +00:00
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
2026-06-11 15:03:23 +00:00
|
|
|
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-06-23 22:19:42 +00:00
|
|
|
activeThreadId: "thread",
|
|
|
|
|
active: { serviceTier: "flex" },
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
2026-06-23 22:19:42 +00:00
|
|
|
const resolution = resolveRuntimeControls(snapshot, snapshotConfig(snapshot));
|
2026-05-22 03:30:45 +00:00
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("flex");
|
2026-06-15 06:29:09 +00:00
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
2026-06-23 22:19:42 +00:00
|
|
|
expect(resolution.serviceTier).toMatchObject({ effective: "flex", source: "active-thread" });
|
|
|
|
|
expect(resolution.fastMode).toMatchObject({ active: false, source: "active-thread", effectiveServiceTier: "flex" });
|
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", () => {
|
2026-06-15 19:35:42 +00:00
|
|
|
const model = {
|
|
|
|
|
...modelFixture("gpt-5.5"),
|
|
|
|
|
serviceTiers: [{ id: "priority", name: "Fast" }],
|
|
|
|
|
};
|
2026-06-23 22:19:42 +00:00
|
|
|
// app-server may advertise Fast with an id such as "priority";
|
|
|
|
|
// last verified against codex app-server 0.142.0.
|
2026-05-29 00:44:25 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
activeThreadId: "thread",
|
|
|
|
|
active: { model: "gpt-5.5", serviceTier: "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(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
2026-06-12 11:08:08 +00:00
|
|
|
expect(fastRuntimeServiceTierRequestValue(snapshot, snapshotConfig(snapshot))).toBe("priority");
|
2026-05-29 00:44:25 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-23 22:19:42 +00:00
|
|
|
it("treats the app-server reported default tier after clearing Fast as fast mode off", () => {
|
2026-06-15 19:35:42 +00:00
|
|
|
const model = {
|
|
|
|
|
...modelFixture("gpt-5.5"),
|
|
|
|
|
serviceTiers: [{ id: "priority", name: "Fast" }],
|
|
|
|
|
};
|
2026-05-29 00:44:25 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
activeThreadId: "thread",
|
|
|
|
|
active: { model: "gpt-5.5", serviceTier: "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(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
2026-05-29 00:44:25 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-21 08:48:54 +00:00
|
|
|
it("uses requested Fast mode above active and configured service tiers", () => {
|
2026-05-22 03:30:45 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
active: { serviceTier: "flex" },
|
|
|
|
|
pending: { fastMode: setRuntimeIntentValue("disabled") },
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
|
|
|
|
});
|
|
|
|
|
const resolution = resolveRuntimeControls(snapshot, snapshotConfig(snapshot));
|
|
|
|
|
|
|
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBeNull();
|
|
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
|
|
|
|
expect(resolution.serviceTier).toMatchObject({ effective: null, source: "pending" });
|
|
|
|
|
expect(resolution.fastMode).toMatchObject({ active: false, source: "pending", effectiveServiceTier: null });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("keeps a cleared active thread service tier above configured Fast mode", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
active: { serviceTier: null },
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
2026-05-22 03:30:45 +00:00
|
|
|
});
|
2026-06-23 22:19:42 +00:00
|
|
|
const resolution = resolveRuntimeControls(snapshot, snapshotConfig(snapshot));
|
2026-05-22 03:30:45 +00:00
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBeNull();
|
2026-06-15 06:29:09 +00:00
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
2026-06-23 22:19:42 +00:00
|
|
|
expect(resolution.serviceTier).toMatchObject({ effective: null, source: "active-thread" });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("resolves all runtime controls through pending, active, and config layers", () => {
|
|
|
|
|
const configured = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({
|
|
|
|
|
model: "gpt-config",
|
|
|
|
|
model_reasoning_effort: "medium",
|
2026-07-01 10:13:45 +00:00
|
|
|
default_permissions: ":workspace",
|
|
|
|
|
approval_policy: "on-request",
|
|
|
|
|
sandbox_mode: "workspace-write",
|
|
|
|
|
sandbox_workspace_write: {
|
|
|
|
|
writable_roots: ["/vault"],
|
|
|
|
|
network_access: false,
|
|
|
|
|
exclude_tmpdir_env_var: false,
|
|
|
|
|
exclude_slash_tmp: false,
|
|
|
|
|
},
|
2026-06-23 22:19:42 +00:00
|
|
|
approvals_reviewer: "auto_review",
|
|
|
|
|
service_tier: "fast",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
const active = runtimeSnapshot({
|
|
|
|
|
...configured,
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
active: {
|
2026-07-01 10:13:45 +00:00
|
|
|
approvalPolicyKnown: true,
|
|
|
|
|
sandboxPolicyKnown: true,
|
|
|
|
|
permissionProfileKnown: true,
|
2026-06-23 22:19:42 +00:00
|
|
|
model: "gpt-active",
|
|
|
|
|
reasoningEffort: "high",
|
2026-07-01 10:13:45 +00:00
|
|
|
activePermissionProfile: { id: ":read-only", extends: null },
|
|
|
|
|
sandboxPolicy: { type: "readOnly", networkAccess: false },
|
|
|
|
|
approvalPolicy: "never",
|
2026-06-23 22:19:42 +00:00
|
|
|
approvalsReviewer: "user",
|
|
|
|
|
serviceTier: "flex",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
const pending = runtimeSnapshot({
|
|
|
|
|
...active,
|
|
|
|
|
pending: {
|
|
|
|
|
...active.pending,
|
|
|
|
|
model: setRuntimeIntentValue("gpt-pending"),
|
|
|
|
|
reasoningEffort: setRuntimeIntentValue("low"),
|
2026-07-01 10:13:45 +00:00
|
|
|
permissionProfile: setRuntimeIntentValue(":workspace"),
|
2026-07-08 02:38:43 +00:00
|
|
|
approvalPolicy: setRuntimeIntentValue("on-request"),
|
2026-07-01 07:30:04 +00:00
|
|
|
approvalsReviewer: setRuntimeIntentValue("guardian_subagent"),
|
2026-06-23 22:19:42 +00:00
|
|
|
fastMode: setRuntimeIntentValue("enabled"),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(resolveRuntimeControls(configured, snapshotConfig(configured))).toMatchObject({
|
|
|
|
|
model: { effective: "gpt-config", source: "config" },
|
|
|
|
|
reasoningEffort: { effective: "medium", source: "config" },
|
2026-07-02 04:43:19 +00:00
|
|
|
permissionProfile: { effective: ":workspace", source: "config" },
|
|
|
|
|
sandboxPolicy: { effective: null, source: "none" },
|
2026-07-01 10:13:45 +00:00
|
|
|
approvalPolicy: { effective: "on-request", source: "config" },
|
2026-07-01 07:30:04 +00:00
|
|
|
approvalsReviewer: { effective: "auto_review", source: "config" },
|
2026-06-23 22:19:42 +00:00
|
|
|
serviceTier: { effective: "fast", source: "config" },
|
|
|
|
|
});
|
|
|
|
|
expect(resolveRuntimeControls(active, snapshotConfig(active))).toMatchObject({
|
|
|
|
|
model: { effective: "gpt-active", source: "active-thread" },
|
|
|
|
|
reasoningEffort: { effective: "high", source: "active-thread" },
|
2026-07-01 10:13:45 +00:00
|
|
|
permissionProfile: { effective: ":read-only", source: "active-thread" },
|
|
|
|
|
sandboxPolicy: { effective: { type: "readOnly", networkAccess: false }, source: "active-thread" },
|
|
|
|
|
approvalPolicy: { effective: "never", source: "active-thread" },
|
2026-07-01 07:30:04 +00:00
|
|
|
approvalsReviewer: { effective: "user", source: "active-thread" },
|
2026-06-23 22:19:42 +00:00
|
|
|
serviceTier: { effective: "flex", source: "active-thread" },
|
|
|
|
|
});
|
|
|
|
|
expect(resolveRuntimeControls(pending, snapshotConfig(pending))).toMatchObject({
|
2026-07-01 10:13:45 +00:00
|
|
|
model: { confirmed: "gpt-active", confirmedSource: "active-thread", effective: "gpt-pending", source: "pending" },
|
|
|
|
|
reasoningEffort: { confirmed: "high", confirmedSource: "active-thread", effective: "low", source: "pending" },
|
|
|
|
|
permissionProfile: { confirmed: ":read-only", confirmedSource: "active-thread", effective: ":workspace", source: "pending" },
|
|
|
|
|
sandboxPolicy: {
|
|
|
|
|
confirmed: { type: "readOnly", networkAccess: false },
|
|
|
|
|
confirmedSource: "active-thread",
|
|
|
|
|
effective: null,
|
|
|
|
|
source: "pending",
|
|
|
|
|
},
|
2026-07-08 02:38:43 +00:00
|
|
|
approvalPolicy: { confirmed: "never", confirmedSource: "active-thread", effective: "on-request", source: "pending" },
|
2026-07-01 10:13:45 +00:00
|
|
|
approvalsReviewer: { confirmed: "user", confirmedSource: "active-thread", effective: "guardian_subagent", source: "pending" },
|
|
|
|
|
serviceTier: { confirmed: "flex", confirmedSource: "active-thread", effective: "fast", source: "pending" },
|
|
|
|
|
fastMode: {
|
|
|
|
|
active: true,
|
|
|
|
|
confirmedActive: false,
|
|
|
|
|
source: "pending",
|
|
|
|
|
confirmedSource: "active-thread",
|
|
|
|
|
serviceTierRequestValue: "fast",
|
|
|
|
|
},
|
2026-06-23 22:19:42 +00:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-06 05:24:07 +00:00
|
|
|
it("model-checks runtime value precedence for configured, active, and pending model layers", () => {
|
|
|
|
|
for (const configured of [null, "gpt-config"] as const) {
|
|
|
|
|
for (const active of [null, "gpt-active"] as const) {
|
|
|
|
|
for (const pending of modelPendingIntentCases()) {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture(configured ? { model: configured } : {}),
|
|
|
|
|
active: { model: active },
|
|
|
|
|
pending: { model: pending.intent },
|
|
|
|
|
});
|
|
|
|
|
const model = resolveRuntimeControls(snapshot, snapshotConfig(snapshot)).model;
|
|
|
|
|
const expectedConfirmed = active ?? configured;
|
|
|
|
|
const expectedConfirmedSource = active ? "active-thread" : configured ? "config" : "none";
|
|
|
|
|
|
|
|
|
|
expect(model, runtimeLayerCase(configured, active, pending.name)).toMatchObject({
|
|
|
|
|
configured,
|
|
|
|
|
active,
|
|
|
|
|
pending: pending.intent,
|
|
|
|
|
confirmed: expectedConfirmed,
|
|
|
|
|
confirmedSource: expectedConfirmedSource,
|
|
|
|
|
effective: pending.name === "set" ? "gpt-pending" : pending.name === "resetToConfig" ? configured : expectedConfirmed,
|
|
|
|
|
source: pending.name === "set" ? "pending" : pending.name === "resetToConfig" ? "config" : expectedConfirmedSource,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-23 22:19:42 +00:00
|
|
|
it("reports collaboration mode dirtiness and missing model blockers from the resolved runtime", () => {
|
|
|
|
|
const blocked = runtimeSnapshot({
|
2026-07-01 11:14:57 +00:00
|
|
|
pending: { collaborationMode: setCollaborationModeIntent("plan") },
|
2026-06-23 22:19:42 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({}),
|
|
|
|
|
});
|
|
|
|
|
const ready = runtimeSnapshot({
|
|
|
|
|
pending: {
|
2026-07-01 11:14:57 +00:00
|
|
|
collaborationMode: setCollaborationModeIntent("plan"),
|
2026-06-23 22:19:42 +00:00
|
|
|
model: setRuntimeIntentValue("gpt-5.5"),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(resolveRuntimeControls(blocked, snapshotConfig(blocked)).collaborationMode).toMatchObject({
|
2026-07-01 11:14:57 +00:00
|
|
|
pending: setCollaborationModeIntent("plan"),
|
2026-07-01 10:13:45 +00:00
|
|
|
confirmed: "default",
|
|
|
|
|
effective: "plan",
|
2026-06-23 22:19:42 +00:00
|
|
|
dirty: true,
|
|
|
|
|
blockedReason: "missing-model",
|
|
|
|
|
});
|
|
|
|
|
expect(resolveRuntimeControls(ready, snapshotConfig(ready)).collaborationMode).toMatchObject({
|
2026-07-01 11:14:57 +00:00
|
|
|
pending: setCollaborationModeIntent("plan"),
|
2026-07-01 10:13:45 +00:00
|
|
|
confirmed: "default",
|
|
|
|
|
effective: "plan",
|
2026-06-23 22:19:42 +00:00
|
|
|
dirty: true,
|
|
|
|
|
blockedReason: null,
|
|
|
|
|
});
|
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-07-01 07:30:04 +00:00
|
|
|
const snapshot = runtimeSnapshot({ pending: { approvalsReviewer: setRuntimeIntentValue("auto_review") } });
|
2026-07-01 10:13:45 +00:00
|
|
|
const resolution = resolveRuntimeControls(snapshot, snapshotConfig(snapshot));
|
2026-05-21 15:02:32 +00:00
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
2026-07-01 10:13:45 +00:00
|
|
|
expect(resolution.autoReview).toMatchObject({ active: true, confirmedActive: false, source: "pending", confirmedSource: "none" });
|
2026-06-14 20:57:32 +00:00
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
|
|
|
update: { approvalsReviewer: "auto_review" },
|
|
|
|
|
});
|
2026-05-21 15:02:32 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-21 08:55:23 +00:00
|
|
|
it("treats active thread runtime as display state without persisting it into runtime intent patches", () => {
|
2026-05-17 09:50:00 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
activeThreadId: "thread",
|
|
|
|
|
active: { model: "gpt-5-active", serviceTier: "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");
|
2026-06-14 20:57:32 +00:00
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot)).update).not.toHaveProperty("model");
|
|
|
|
|
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot)).update).not.toHaveProperty("effort");
|
2026-05-17 09:50:00 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-11 15:03:23 +00:00
|
|
|
it("uses the explicit config when finding supported reasoning efforts", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
pending: { model: resetRuntimeIntentToConfig() },
|
2026-06-11 15:03:23 +00:00
|
|
|
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-12 15:05:56 +00:00
|
|
|
it("summarizes service tier and context meter state from one runtime snapshot", () => {
|
2026-06-23 22:19:42 +00:00
|
|
|
const snapshot = runtimeSnapshot({ pending: { fastMode: setRuntimeIntentValue("enabled") }, activeThreadId: "thread" });
|
2026-05-12 15:05:56 +00:00
|
|
|
|
2026-06-15 06:29:09 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
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({
|
2026-07-08 22:30:00 +00:00
|
|
|
title: "Context: 1,000 / 100,000 (1%). Latest usage: 1,000 input, 200 output, 50 reasoning. Total: 2,600 tokens.",
|
2026-05-25 02:48:22 +00:00
|
|
|
});
|
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,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-06-21 08:48:54 +00:00
|
|
|
it("serializes disabled Fast mode as a null service tier request", () => {
|
2026-05-12 15:05:56 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-10 02:04:30 +00:00
|
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
2026-06-23 22:19:42 +00:00
|
|
|
pending: { fastMode: setRuntimeIntentValue("disabled") },
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-15 06:29:09 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBeNull();
|
|
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBeNull();
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-23 22:19:42 +00:00
|
|
|
it("serializes service tier reset for thread start as the configured tier instead of null", () => {
|
2026-06-11 11:31:47 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
2026-06-23 22:19:42 +00:00
|
|
|
pending: { fastMode: resetRuntimeIntentToConfig() },
|
2026-06-11 11:31:47 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-15 06:29:09 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
2026-06-23 22:19:42 +00:00
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("omits service tier reset for thread start when config has no service tier", () => {
|
|
|
|
|
const snapshot = runtimeSnapshot({
|
|
|
|
|
runtimeConfig: runtimeConfigFixture({}),
|
|
|
|
|
pending: { fastMode: resetRuntimeIntentToConfig() },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBeNull();
|
|
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
|
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBeUndefined();
|
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", () => {
|
2026-06-15 19:35:42 +00:00
|
|
|
const model = {
|
|
|
|
|
...modelFixture("gpt-5.5"),
|
|
|
|
|
serviceTiers: [{ id: "priority", name: "Fast" }],
|
|
|
|
|
};
|
2026-05-29 00:44:25 +00:00
|
|
|
const snapshot = runtimeSnapshot({
|
2026-06-23 22:19:42 +00:00
|
|
|
pending: { fastMode: setRuntimeIntentValue("enabled") },
|
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-23 22:19:42 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
2026-06-15 06:29:09 +00:00
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
2026-06-23 22:19:42 +00:00
|
|
|
expect(resolveRuntimeControls(snapshot, snapshotConfig(snapshot)).fastMode).toMatchObject({
|
|
|
|
|
active: true,
|
|
|
|
|
effectiveServiceTier: "fast",
|
|
|
|
|
serviceTierRequestValue: "priority",
|
|
|
|
|
});
|
2026-06-11 15:03:23 +00:00
|
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBe("priority");
|
2026-05-29 00:44:25 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-21 08:55:23 +00:00
|
|
|
it("omits service tier when neither config nor pending intent 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-15 06:29:09 +00:00
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("flex");
|
|
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
2026-06-11 15:03:23 +00:00
|
|
|
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
|
|
|
});
|
2026-07-09 17:07:34 +00:00
|
|
|
|
|
|
|
|
it("formats runtime status details as flat rows", () => {
|
|
|
|
|
expect(
|
|
|
|
|
statusDetails({
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
snapshot: runtimeSnapshot({
|
|
|
|
|
activeThreadId: "thread",
|
|
|
|
|
rateLimit: {
|
|
|
|
|
limitId: "codex",
|
|
|
|
|
limitName: "Codex",
|
|
|
|
|
primary: { usedPercent: 15, windowDurationMins: 300, resetsAt: null },
|
|
|
|
|
secondary: { usedPercent: 38, windowDurationMins: 10_080, resetsAt: null },
|
|
|
|
|
individualLimit: null,
|
|
|
|
|
rateLimitReachedType: null,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
nowMs: 0,
|
|
|
|
|
}),
|
|
|
|
|
).toEqual([
|
|
|
|
|
{ label: "Thread", value: "thread" },
|
|
|
|
|
{ label: "Context", value: "0 / 100,000 (0%). No turns in this thread yet." },
|
|
|
|
|
{ label: "Usage Limits", value: "5h 15%, 1w 38%" },
|
|
|
|
|
]);
|
|
|
|
|
});
|
2026-05-12 15:05:56 +00:00
|
|
|
});
|
|
|
|
|
|
2026-06-23 22:19:42 +00:00
|
|
|
interface RuntimeSnapshotPatch extends Partial<Omit<RuntimeSnapshot, "active" | "pending">> {
|
|
|
|
|
active?: Partial<RuntimeSnapshot["active"]>;
|
2026-07-01 07:30:04 +00:00
|
|
|
pending?: Partial<RuntimeSnapshot["pending"]>;
|
2026-06-23 22:19:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function runtimeSnapshot(overrides: RuntimeSnapshotPatch = {}): RuntimeSnapshot {
|
|
|
|
|
const { active, pending, ...snapshotOverrides } = overrides;
|
|
|
|
|
const snapshot: RuntimeSnapshot = {
|
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,
|
2026-06-23 22:19:42 +00:00
|
|
|
active: {
|
2026-07-01 10:13:45 +00:00
|
|
|
approvalPolicyKnown: false,
|
|
|
|
|
sandboxPolicyKnown: false,
|
|
|
|
|
permissionProfileKnown: false,
|
2026-06-23 22:19:42 +00:00
|
|
|
serviceTierKnown: false,
|
|
|
|
|
model: null,
|
|
|
|
|
reasoningEffort: null,
|
|
|
|
|
collaborationMode: null,
|
|
|
|
|
serviceTier: null,
|
|
|
|
|
approvalsReviewer: null,
|
2026-07-01 03:01:36 +00:00
|
|
|
approvalPolicy: null,
|
|
|
|
|
sandboxPolicy: null,
|
|
|
|
|
activePermissionProfile: null,
|
2026-06-23 22:19:42 +00:00
|
|
|
},
|
|
|
|
|
pending: {
|
|
|
|
|
model: { kind: "unchanged" },
|
|
|
|
|
reasoningEffort: { kind: "unchanged" },
|
2026-07-01 07:30:04 +00:00
|
|
|
permissionProfile: { kind: "unchanged" },
|
|
|
|
|
approvalPolicy: { kind: "unchanged" },
|
|
|
|
|
approvalsReviewer: { kind: "unchanged" },
|
2026-07-01 11:14:57 +00:00
|
|
|
collaborationMode: unchangedCollaborationModeIntent(),
|
2026-06-23 22:19:42 +00:00
|
|
|
fastMode: { 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: [],
|
2026-06-23 22:19:42 +00:00
|
|
|
};
|
|
|
|
|
return {
|
|
|
|
|
...snapshot,
|
|
|
|
|
...snapshotOverrides,
|
|
|
|
|
active: {
|
|
|
|
|
...snapshot.active,
|
|
|
|
|
...(active && "serviceTier" in active ? { serviceTierKnown: true } : {}),
|
|
|
|
|
...active,
|
|
|
|
|
},
|
|
|
|
|
pending: {
|
|
|
|
|
...snapshot.pending,
|
|
|
|
|
...pending,
|
|
|
|
|
},
|
2026-05-12 15:05:56 +00:00
|
|
|
};
|
|
|
|
|
}
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-26 12:36:35 +00:00
|
|
|
function runtimeControls(snapshot: RuntimeSnapshot, config: RuntimeConfigSnapshot = snapshotConfig(snapshot)) {
|
|
|
|
|
return resolveRuntimeControls(snapshot, config);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function currentModel(snapshot: RuntimeSnapshot, config?: RuntimeConfigSnapshot): string | null {
|
|
|
|
|
return runtimeControls(snapshot, config).model.effective;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function currentReasoningEffort(snapshot: RuntimeSnapshot, config?: RuntimeConfigSnapshot): string | null {
|
|
|
|
|
return runtimeControls(snapshot, config).reasoningEffort.effective;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function currentServiceTier(snapshot: RuntimeSnapshot, config?: RuntimeConfigSnapshot): string | null {
|
|
|
|
|
return runtimeControls(snapshot, config).serviceTier.effective;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function autoReviewActive(snapshot: RuntimeSnapshot, config?: RuntimeConfigSnapshot): boolean {
|
|
|
|
|
return runtimeControls(snapshot, config).autoReview.active;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fastModeActive(snapshot: RuntimeSnapshot, config?: RuntimeConfigSnapshot): boolean {
|
|
|
|
|
return runtimeControls(snapshot, config).fastMode.active;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fastRuntimeServiceTierRequestValue(snapshot: RuntimeSnapshot, config?: RuntimeConfigSnapshot): string {
|
|
|
|
|
return runtimeControls(snapshot, config).fastMode.serviceTierRequestValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function supportedReasoningEfforts(snapshot: RuntimeSnapshot, config?: RuntimeConfigSnapshot): readonly string[] {
|
|
|
|
|
return runtimeControls(snapshot, config).supportedReasoningEfforts;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-06 05:24:07 +00:00
|
|
|
function modelPendingIntentCases() {
|
|
|
|
|
return [
|
|
|
|
|
{ name: "unchanged", intent: unchangedRuntimeIntent<string>() },
|
|
|
|
|
{ name: "set", intent: setRuntimeIntentValue("gpt-pending") },
|
|
|
|
|
{ name: "resetToConfig", intent: resetRuntimeIntentToConfig<string>() },
|
|
|
|
|
] as const;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function runtimeLayerCase(configured: string | null, active: string | null, pending: string): string {
|
|
|
|
|
return `configured=${configured ?? "none"} active=${active ?? "none"} pending=${pending}`;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-12 08:29:04 +00:00
|
|
|
function runtimeConfigFixture(config: Record<string, unknown>, layers: ConfigReadResult["layers"] = null): RuntimeConfigSnapshot {
|
2026-06-10 02:04:30 +00:00
|
|
|
return runtimeConfigSnapshotFromAppServerConfig({
|
2026-06-12 06:00:35 +00:00
|
|
|
config: config as ConfigReadResult["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-12 06:00:35 +00:00
|
|
|
function configLayer(config: Record<string, unknown>, profile: string | null): NonNullable<ConfigReadResult["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-12 06:00:35 +00:00
|
|
|
config: config as NonNullable<ConfigReadResult["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: [],
|
|
|
|
|
serviceTiers: [],
|
|
|
|
|
defaultServiceTier: null,
|
|
|
|
|
isDefault: false,
|
|
|
|
|
};
|
|
|
|
|
}
|