mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 17:30:31 +00:00
496 lines
21 KiB
TypeScript
496 lines
21 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { runtimeConfigOrDefault } from "../../../../../src/domain/runtime/config";
|
|
import {
|
|
resetRuntimeIntentToConfig,
|
|
setCollaborationModeIntent,
|
|
setRuntimeIntentValue,
|
|
} from "../../../../../src/features/chat/domain/runtime/intent";
|
|
import { resolveRuntimeControls } from "../../../../../src/features/chat/domain/runtime/resolution";
|
|
import { serviceTierRequestForThreadStart } from "../../../../../src/features/chat/domain/runtime/thread-settings-patch";
|
|
import {
|
|
autoReviewActive,
|
|
configLayer,
|
|
currentModel,
|
|
currentReasoningEffort,
|
|
currentServiceTier,
|
|
fastModeActive,
|
|
fastRuntimeServiceTierRequestValue,
|
|
modelFixture,
|
|
modelPendingIntentCases,
|
|
runtimeConfigFixture,
|
|
runtimeLayerCase,
|
|
runtimeSnapshot,
|
|
snapshotConfig,
|
|
supportedReasoningEfforts,
|
|
} from "./support";
|
|
|
|
describe("runtime control resolution", () => {
|
|
it("falls back to startup permissions until active thread permissions are reported", () => {
|
|
const configured = runtimeSnapshot({
|
|
runtimeConfig: runtimeConfigFixture({
|
|
default_permissions: ":workspace",
|
|
approval_policy: "on-request",
|
|
}),
|
|
});
|
|
expect(resolveRuntimeControls(configured, snapshotConfig(configured))).toMatchObject({
|
|
permissionProfile: { effective: ":workspace", source: "config" },
|
|
sandboxPolicy: { effective: null, source: "none" },
|
|
approvalPolicy: { effective: "on-request", source: "config" },
|
|
});
|
|
|
|
const activeUnreported = runtimeSnapshot({
|
|
activeThreadId: "thread",
|
|
runtimeConfig: runtimeConfigFixture({
|
|
default_permissions: ":workspace",
|
|
approval_policy: "on-request",
|
|
}),
|
|
});
|
|
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" },
|
|
});
|
|
|
|
const activeReported = runtimeSnapshot({
|
|
activeThreadId: "thread",
|
|
active: {
|
|
approvalPolicyKnown: true,
|
|
sandboxPolicyKnown: true,
|
|
permissionProfileKnown: true,
|
|
approvalPolicy: "never",
|
|
sandboxPolicy: { type: "readOnly", networkAccess: false },
|
|
activePermissionProfile: { id: ":read-only", extends: null },
|
|
approvalsReviewer: "user",
|
|
},
|
|
pending: { approvalsReviewer: setRuntimeIntentValue("auto_review") },
|
|
});
|
|
expect(resolveRuntimeControls(activeReported, snapshotConfig(activeReported))).toMatchObject({
|
|
approvalsReviewer: { effective: "auto_review", source: "pending" },
|
|
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",
|
|
},
|
|
});
|
|
expect(resolveRuntimeControls(approvalOnlyReported, snapshotConfig(approvalOnlyReported))).toMatchObject({
|
|
permissionProfile: { effective: ":workspace", source: "config" },
|
|
sandboxPolicy: { effective: null, source: "none" },
|
|
approvalPolicy: { effective: "never", source: "active-thread" },
|
|
});
|
|
});
|
|
|
|
it("marks the sandbox policy pending and unknown when selecting a different permission profile", () => {
|
|
const runtimeConfig = runtimeConfigFixture({});
|
|
const snapshot = runtimeSnapshot({
|
|
activeThreadId: "thread",
|
|
runtimeConfig: {
|
|
...runtimeConfig,
|
|
startupPermissions: {
|
|
approvalPolicy: "on-request",
|
|
activePermissionProfile: { id: ":startup", extends: null },
|
|
sandboxPolicy: {
|
|
type: "workspaceWrite",
|
|
writableRoots: ["/vault"],
|
|
networkAccess: true,
|
|
excludeTmpdirEnvVar: true,
|
|
excludeSlashTmp: false,
|
|
},
|
|
},
|
|
},
|
|
active: {
|
|
sandboxPolicyKnown: true,
|
|
permissionProfileKnown: true,
|
|
sandboxPolicy: { type: "readOnly", networkAccess: false },
|
|
activePermissionProfile: { id: ":read-only", extends: null },
|
|
},
|
|
pending: { permissionProfile: setRuntimeIntentValue(":workspace") },
|
|
});
|
|
|
|
expect(resolveRuntimeControls(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
|
permissionProfile: { effective: ":workspace", source: "pending" },
|
|
sandboxPolicy: {
|
|
confirmed: { type: "readOnly", networkAccess: false },
|
|
confirmedSource: "active-thread",
|
|
effective: null,
|
|
source: "pending",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("uses the configured sandbox policy when reselecting the startup permission profile", () => {
|
|
const configuredPolicy = {
|
|
type: "workspaceWrite" as const,
|
|
writableRoots: ["/vault"],
|
|
networkAccess: true,
|
|
excludeTmpdirEnvVar: true,
|
|
excludeSlashTmp: false,
|
|
};
|
|
const runtimeConfig = runtimeConfigFixture({});
|
|
const snapshot = runtimeSnapshot({
|
|
activeThreadId: "thread",
|
|
runtimeConfig: {
|
|
...runtimeConfig,
|
|
startupPermissions: {
|
|
approvalPolicy: "on-request",
|
|
activePermissionProfile: { id: ":workspace", extends: null },
|
|
sandboxPolicy: configuredPolicy,
|
|
},
|
|
},
|
|
active: {
|
|
sandboxPolicyKnown: true,
|
|
permissionProfileKnown: true,
|
|
sandboxPolicy: { type: "readOnly", networkAccess: false },
|
|
activePermissionProfile: { id: ":read-only", extends: null },
|
|
},
|
|
pending: { permissionProfile: setRuntimeIntentValue(":workspace") },
|
|
});
|
|
const config = snapshotConfig(snapshot);
|
|
const resolution = resolveRuntimeControls(snapshot, config);
|
|
|
|
expect(resolution.sandboxPolicy).toMatchObject({
|
|
confirmed: { type: "readOnly", networkAccess: false },
|
|
confirmedSource: "active-thread",
|
|
effective: configuredPolicy,
|
|
source: "pending",
|
|
});
|
|
});
|
|
|
|
it("resolves auto-review mode from requested, active, then effective config", () => {
|
|
const requested = runtimeSnapshot({
|
|
pending: { approvalsReviewer: setRuntimeIntentValue("user") },
|
|
active: { approvalsReviewer: "auto_review" },
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
|
});
|
|
const active = runtimeSnapshot({
|
|
active: { approvalsReviewer: "user" },
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
|
});
|
|
const configured = runtimeSnapshot({
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
|
});
|
|
|
|
expect(autoReviewActive(requested, snapshotConfig(requested))).toBe(false);
|
|
expect(autoReviewActive(active, snapshotConfig(active))).toBe(false);
|
|
expect(autoReviewActive(configured, snapshotConfig(configured))).toBe(true);
|
|
});
|
|
|
|
it("uses the active reviewer before configured reviewer", () => {
|
|
const snapshot = runtimeSnapshot({
|
|
active: { approvalsReviewer: "user" },
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "auto_review" }),
|
|
});
|
|
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
|
});
|
|
|
|
it("treats guardian subagent reviewer as active auto-review", () => {
|
|
const snapshot = runtimeSnapshot({
|
|
active: { approvalsReviewer: "guardian_subagent" },
|
|
});
|
|
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
|
});
|
|
|
|
it("uses requested reviewer above active and configured reviewers", () => {
|
|
const snapshot = runtimeSnapshot({
|
|
pending: { approvalsReviewer: setRuntimeIntentValue("user") },
|
|
active: { approvalsReviewer: "user" },
|
|
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "auto_review" }),
|
|
});
|
|
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
|
});
|
|
|
|
it("uses effective approval reviewer values and reports selected profile metadata", () => {
|
|
const runtimeConfig = runtimeConfigFixture({ approvals_reviewer: "auto_review" }, [
|
|
configLayer({}, null),
|
|
configLayer({ approvals_reviewer: "auto_review" }, "auto"),
|
|
]);
|
|
const snapshot = runtimeSnapshot({
|
|
runtimeConfig,
|
|
});
|
|
|
|
expect(runtimeConfigOrDefault(runtimeConfig).profile).toBe("auto");
|
|
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
|
});
|
|
|
|
it("uses effective model, effort, and fast mode config values", () => {
|
|
const snapshot = runtimeSnapshot({
|
|
runtimeConfig: runtimeConfigFixture(
|
|
{
|
|
model: "gpt-profile",
|
|
model_reasoning_effort: "high",
|
|
service_tier: "fast",
|
|
},
|
|
[
|
|
configLayer({}, null),
|
|
configLayer({ model: "gpt-profile", model_reasoning_effort: "high", service_tier: "fast" }, "fast-profile"),
|
|
],
|
|
),
|
|
});
|
|
|
|
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBe("gpt-profile");
|
|
expect(currentReasoningEffort(snapshot, snapshotConfig(snapshot))).toBe("high");
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
|
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
|
});
|
|
|
|
it("uses active service tier before configured service tier", () => {
|
|
const snapshot = runtimeSnapshot({
|
|
activeThreadId: "thread",
|
|
active: { serviceTier: "flex" },
|
|
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
|
});
|
|
const resolution = resolveRuntimeControls(snapshot, snapshotConfig(snapshot));
|
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("flex");
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
|
expect(resolution.serviceTier).toMatchObject({ effective: "flex", source: "active-thread" });
|
|
expect(resolution.fastMode).toMatchObject({ active: false, source: "active-thread", effectiveServiceTier: "flex" });
|
|
});
|
|
|
|
it("treats the catalog Fast service tier id as fast mode while preserving the id", () => {
|
|
const model = {
|
|
...modelFixture("gpt-5.5"),
|
|
serviceTiers: [{ id: "priority", name: "Fast" }],
|
|
};
|
|
// app-server may advertise Fast with an id such as "priority";
|
|
// last verified against codex app-server 0.142.0.
|
|
const snapshot = runtimeSnapshot({
|
|
activeThreadId: "thread",
|
|
active: { model: "gpt-5.5", serviceTier: "priority" },
|
|
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
|
|
availableModels: [model],
|
|
});
|
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("priority");
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
|
expect(fastRuntimeServiceTierRequestValue(snapshot, snapshotConfig(snapshot))).toBe("priority");
|
|
});
|
|
|
|
it("treats the app-server reported default tier after clearing Fast as fast mode off", () => {
|
|
const model = {
|
|
...modelFixture("gpt-5.5"),
|
|
serviceTiers: [{ id: "priority", name: "Fast" }],
|
|
};
|
|
const snapshot = runtimeSnapshot({
|
|
activeThreadId: "thread",
|
|
active: { model: "gpt-5.5", serviceTier: "default" },
|
|
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
|
|
availableModels: [model],
|
|
});
|
|
|
|
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("default");
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(false);
|
|
});
|
|
|
|
it("uses requested Fast mode above active and configured service tiers", () => {
|
|
const snapshot = runtimeSnapshot({
|
|
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 },
|
|
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: "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",
|
|
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,
|
|
},
|
|
approvals_reviewer: "auto_review",
|
|
service_tier: "fast",
|
|
}),
|
|
});
|
|
const active = runtimeSnapshot({
|
|
...configured,
|
|
activeThreadId: "thread",
|
|
active: {
|
|
approvalPolicyKnown: true,
|
|
sandboxPolicyKnown: true,
|
|
permissionProfileKnown: true,
|
|
model: "gpt-active",
|
|
reasoningEffort: "high",
|
|
activePermissionProfile: { id: ":read-only", extends: null },
|
|
sandboxPolicy: { type: "readOnly", networkAccess: false },
|
|
approvalPolicy: "never",
|
|
approvalsReviewer: "user",
|
|
serviceTier: "flex",
|
|
},
|
|
});
|
|
const pending = runtimeSnapshot({
|
|
...active,
|
|
pending: {
|
|
...active.pending,
|
|
model: setRuntimeIntentValue("gpt-pending"),
|
|
reasoningEffort: setRuntimeIntentValue("low"),
|
|
permissionProfile: setRuntimeIntentValue(":workspace"),
|
|
approvalPolicy: setRuntimeIntentValue("on-request"),
|
|
approvalsReviewer: setRuntimeIntentValue("guardian_subagent"),
|
|
fastMode: setRuntimeIntentValue("enabled"),
|
|
},
|
|
});
|
|
|
|
expect(resolveRuntimeControls(configured, snapshotConfig(configured))).toMatchObject({
|
|
model: { effective: "gpt-config", source: "config" },
|
|
reasoningEffort: { effective: "medium", source: "config" },
|
|
permissionProfile: { effective: ":workspace", source: "config" },
|
|
sandboxPolicy: { effective: null, source: "none" },
|
|
approvalPolicy: { effective: "on-request", source: "config" },
|
|
approvalsReviewer: { effective: "auto_review", source: "config" },
|
|
serviceTier: { effective: "fast", source: "config" },
|
|
});
|
|
expect(resolveRuntimeControls(active, snapshotConfig(active))).toMatchObject({
|
|
model: { effective: "gpt-active", source: "active-thread" },
|
|
reasoningEffort: { effective: "high", source: "active-thread" },
|
|
permissionProfile: { effective: ":read-only", source: "active-thread" },
|
|
sandboxPolicy: { effective: { type: "readOnly", networkAccess: false }, source: "active-thread" },
|
|
approvalPolicy: { effective: "never", source: "active-thread" },
|
|
approvalsReviewer: { effective: "user", source: "active-thread" },
|
|
serviceTier: { effective: "flex", source: "active-thread" },
|
|
});
|
|
expect(resolveRuntimeControls(pending, snapshotConfig(pending))).toMatchObject({
|
|
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",
|
|
},
|
|
approvalPolicy: { confirmed: "never", confirmedSource: "active-thread", effective: "on-request", source: "pending" },
|
|
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",
|
|
},
|
|
});
|
|
});
|
|
|
|
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,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
it("reports collaboration mode dirtiness and missing model blockers from the resolved runtime", () => {
|
|
const blocked = runtimeSnapshot({
|
|
pending: { collaborationMode: setCollaborationModeIntent("plan") },
|
|
runtimeConfig: runtimeConfigFixture({}),
|
|
});
|
|
const ready = runtimeSnapshot({
|
|
pending: {
|
|
collaborationMode: setCollaborationModeIntent("plan"),
|
|
model: setRuntimeIntentValue("gpt-5.5"),
|
|
},
|
|
});
|
|
|
|
expect(resolveRuntimeControls(blocked, snapshotConfig(blocked)).collaborationMode).toMatchObject({
|
|
pending: setCollaborationModeIntent("plan"),
|
|
confirmed: "default",
|
|
effective: "plan",
|
|
dirty: true,
|
|
blockedReason: "missing-model",
|
|
});
|
|
expect(resolveRuntimeControls(ready, snapshotConfig(ready)).collaborationMode).toMatchObject({
|
|
pending: setCollaborationModeIntent("plan"),
|
|
confirmed: "default",
|
|
effective: "plan",
|
|
dirty: true,
|
|
blockedReason: null,
|
|
});
|
|
});
|
|
|
|
it("uses the explicit config when finding supported reasoning efforts", () => {
|
|
const snapshot = runtimeSnapshot({
|
|
pending: { model: resetRuntimeIntentToConfig() },
|
|
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"]);
|
|
});
|
|
|
|
it.each([
|
|
{ name: "catalog Fast tier", serviceTier: "catalog-fast", serviceTiers: [{ id: "catalog-fast", name: "Fast" }], expected: true },
|
|
{ name: "catalog Priority tier", serviceTier: "priority", serviceTiers: [{ id: "priority", name: "Priority" }], expected: false },
|
|
{ name: "catalog Flex tier", serviceTier: "flex", serviceTiers: [{ id: "flex", name: "Flex" }], expected: false },
|
|
])("classifies received $name from catalog metadata", ({ serviceTier, serviceTiers, expected }) => {
|
|
const snapshot = runtimeSnapshot({
|
|
activeThreadId: "thread",
|
|
active: { model: "gpt-5.5", serviceTier },
|
|
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
|
|
availableModels: [{ ...modelFixture("gpt-5.5"), serviceTiers }],
|
|
});
|
|
|
|
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(expected);
|
|
});
|
|
});
|