mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 17:30:31 +00:00
Organize runtime override semantics
This commit is contained in:
parent
12479e3d20
commit
379ce709c4
13 changed files with 95 additions and 85 deletions
|
|
@ -20,6 +20,10 @@ The repository checkout is the source of truth for implementation, version contr
|
|||
|
||||
The app-server API is experimental. The project tracks the supported Codex CLI minor and favors a clean current flow over broad old-protocol compatibility. Current optional and nullable fields are still part of the contract and must be normalized before display.
|
||||
|
||||
Runtime settings move through three panel-owned layers before they reach Codex. Chat state stores active runtime values reported by app-server plus pending runtime intents requested by the user; those intents are not app-server payload values. Effective runtime projections combine pending intent, active thread state, and runtime config for display and UI decisions. Only the app-server boundary converts intent into transport values: `undefined` omits a field, `null` explicitly clears or resets it, and concrete values set it. Config values are inputs to effective projection and selected start-thread defaults; they should not be treated as synonymous with transport `null`.
|
||||
|
||||
Fast mode is a panel runtime intent, not an arbitrary service tier override. The app-server still owns service tier ids and defaults, so the panel converts Fast mode enablement to the model catalog's Fast tier id when available, and converts Fast mode disablement or service-tier reset to an explicit clear request at the transport boundary.
|
||||
|
||||
## Code Boundaries
|
||||
|
||||
Generated app-server protocol types should stay behind `src/app-server/`. Services at that boundary adapt protocol payloads into panel-owned domain models or small projections before data reaches features, workspace coordination, settings, or UI. Feature-local app-server integration modules may route and apply those projections, but they should not hand-copy generated request or response shapes when a shared app-server protocol adapter can own that mapping.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
type PendingRuntimeSettingsPatch,
|
||||
} from "./thread-settings-update";
|
||||
import type { RuntimeSnapshot } from "../../domain/runtime/snapshot";
|
||||
import { nextCollaborationMode, type CollaborationModeSelection, type RequestedFastMode } from "../../domain/runtime/pending-settings";
|
||||
import { nextCollaborationMode, type CollaborationModeSelection, type RequestedFastMode } from "../../domain/runtime/intent";
|
||||
import type { ChatAction, ChatState } from "../state/root-reducer";
|
||||
import type { ChatStateStore } from "../state/store";
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
import { currentModel, currentReasoningEffort, fastRuntimeServiceTierRequestValue } from "../../domain/runtime/effective";
|
||||
import type { RuntimeConfigSnapshot } from "../../../../domain/runtime/config";
|
||||
import type { RuntimeSnapshot } from "../../domain/runtime/snapshot";
|
||||
import { effectiveCollaborationMode, type PendingRuntimeSetting } from "../../domain/runtime/pending-settings";
|
||||
import { effectiveCollaborationMode, type PendingRuntimeIntent } from "../../domain/runtime/intent";
|
||||
|
||||
type TurnCollaborationModeWarning = "missing-model";
|
||||
|
||||
|
|
@ -21,10 +21,9 @@ type TurnCollaborationModeSettings =
|
|||
warning: TurnCollaborationModeWarning;
|
||||
};
|
||||
|
||||
type RuntimeServiceTierTransportIntent =
|
||||
| { readonly kind: "omit" }
|
||||
| { readonly kind: "clear" }
|
||||
| { readonly kind: "set"; readonly value: string };
|
||||
// Transport intent is the app-server boundary vocabulary:
|
||||
// omit -> leave the field out, clear -> send null, set -> send a concrete value.
|
||||
type RuntimeTransportIntent<T> = { readonly kind: "omit" } | { readonly kind: "clear" } | { readonly kind: "set"; readonly value: T };
|
||||
|
||||
export interface PendingRuntimeSettingsPatch {
|
||||
update: RuntimeSettingsPatch;
|
||||
|
|
@ -32,7 +31,7 @@ export interface PendingRuntimeSettingsPatch {
|
|||
}
|
||||
|
||||
export function serviceTierRequestForThreadStart(snapshot: RuntimeSnapshot, config: RuntimeConfigSnapshot): RuntimeServiceTierRequest {
|
||||
return serviceTierRequestValue(serviceTierTransportIntent(snapshot, config, "thread-start"));
|
||||
return runtimeSettingsPatchValue(serviceTierTransportIntent(snapshot, config, "thread-start"));
|
||||
}
|
||||
|
||||
function requestedTurnCollaborationModeSettings(snapshot: RuntimeSnapshot, config: RuntimeConfigSnapshot): TurnCollaborationModeSettings {
|
||||
|
|
@ -50,21 +49,25 @@ export function pendingRuntimeSettingsPatch(snapshot: RuntimeSnapshot, config: R
|
|||
const runtimeCollaborationModeSettings = requestedTurnCollaborationModeSettings(snapshot, config);
|
||||
|
||||
if (snapshot.requestedModel.kind !== "unchanged") {
|
||||
applyRuntimeSettingsPatchValue(update, "model", runtimeSettingsPatchValueFromPendingSetting(snapshot.requestedModel));
|
||||
applyRuntimeSettingsPatchValue(update, "model", runtimeSettingsPatchValue(runtimeTransportIntentFromPending(snapshot.requestedModel)));
|
||||
}
|
||||
if (snapshot.requestedReasoningEffort.kind !== "unchanged") {
|
||||
applyRuntimeSettingsPatchValue(update, "effort", runtimeSettingsPatchValueFromPendingSetting(snapshot.requestedReasoningEffort));
|
||||
applyRuntimeSettingsPatchValue(
|
||||
update,
|
||||
"effort",
|
||||
runtimeSettingsPatchValue(runtimeTransportIntentFromPending(snapshot.requestedReasoningEffort)),
|
||||
);
|
||||
}
|
||||
applyRuntimeSettingsPatchValue(
|
||||
update,
|
||||
"serviceTier",
|
||||
serviceTierRequestValue(serviceTierTransportIntent(snapshot, config, "thread-update")),
|
||||
runtimeSettingsPatchValue(serviceTierTransportIntent(snapshot, config, "thread-update")),
|
||||
);
|
||||
if (snapshot.requestedApprovalsReviewer.kind !== "unchanged") {
|
||||
applyRuntimeSettingsPatchValue(
|
||||
update,
|
||||
"approvalsReviewer",
|
||||
runtimeSettingsPatchValueFromPendingSetting(snapshot.requestedApprovalsReviewer),
|
||||
runtimeSettingsPatchValue(runtimeTransportIntentFromPending(snapshot.requestedApprovalsReviewer)),
|
||||
);
|
||||
}
|
||||
if (snapshot.selectedCollaborationMode !== effectiveCollaborationMode(snapshot.activeCollaborationMode)) {
|
||||
|
|
@ -76,17 +79,17 @@ export function pendingRuntimeSettingsPatch(snapshot: RuntimeSnapshot, config: R
|
|||
return { update, collaborationModeWarning: null };
|
||||
}
|
||||
|
||||
function runtimeSettingsPatchValueFromPendingSetting<T>(setting: PendingRuntimeSetting<T>): T | null | undefined {
|
||||
if (setting.kind === "set") return setting.value;
|
||||
if (setting.kind === "resetToConfig") return null;
|
||||
return undefined;
|
||||
function runtimeTransportIntentFromPending<T>(intent: PendingRuntimeIntent<T>): RuntimeTransportIntent<T> {
|
||||
if (intent.kind === "set") return { kind: "set", value: intent.value };
|
||||
if (intent.kind === "resetToConfig") return { kind: "clear" };
|
||||
return { kind: "omit" };
|
||||
}
|
||||
|
||||
function serviceTierTransportIntent(
|
||||
snapshot: RuntimeSnapshot,
|
||||
config: RuntimeConfigSnapshot,
|
||||
target: "thread-start" | "thread-update",
|
||||
): RuntimeServiceTierTransportIntent {
|
||||
): RuntimeTransportIntent<string> {
|
||||
// app-server has no separate "reset to config" token for service tiers.
|
||||
// At the transport boundary, null is the explicit clear/off request; undefined omits the field.
|
||||
if (snapshot.requestedFastMode.kind === "set") {
|
||||
|
|
@ -99,7 +102,7 @@ function serviceTierTransportIntent(
|
|||
return { kind: "omit" };
|
||||
}
|
||||
|
||||
function serviceTierRequestValue(intent: RuntimeServiceTierTransportIntent): RuntimeServiceTierRequest {
|
||||
function runtimeSettingsPatchValue<T>(intent: RuntimeTransportIntent<T>): T | null | undefined {
|
||||
if (intent.kind === "set") return intent.value;
|
||||
if (intent.kind === "clear") return null;
|
||||
return undefined;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { upsertThread, type Thread } from "../../../../domain/threads/model";
|
|||
import { parseServiceTier, type ServiceTier } from "../../../../domain/runtime/policy";
|
||||
import { normalizeReasoningEffort, type ReasoningEffort } from "../../../../domain/catalog/metadata";
|
||||
import type { ChatRuntimeState } from "../../domain/runtime/state";
|
||||
import type { CollaborationModeSelection } from "../../domain/runtime/pending-settings";
|
||||
import type { CollaborationModeSelection } from "../../domain/runtime/intent";
|
||||
import type { MessageStreamItem } from "../../domain/message-stream/items";
|
||||
import type { PendingTurnStart } from "../conversation/turn-state";
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import type { RuntimeConfigSnapshot } from "../../../../domain/runtime/config";
|
|||
import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../../domain/runtime/metrics";
|
||||
import type { ApprovalsReviewer } from "../../../../domain/runtime/policy";
|
||||
import type { RuntimeSettingsPatch } from "../../../../domain/runtime/thread-settings";
|
||||
import type { CollaborationModeSelection } from "../../domain/runtime/pending-settings";
|
||||
import type { CollaborationModeSelection } from "../../domain/runtime/intent";
|
||||
import {
|
||||
commitPendingRuntimeSettingsPatchState,
|
||||
commitAppliedRuntimeSettingsPatchState,
|
||||
clearRequestedApprovalsReviewerRuntimeState,
|
||||
clearRequestedFastModeRuntimeState,
|
||||
initialActiveChatRuntimeState,
|
||||
|
|
@ -25,7 +25,7 @@ import {
|
|||
setSelectedCollaborationModeRuntimeState,
|
||||
type ChatRuntimeState,
|
||||
} from "../../domain/runtime/state";
|
||||
import type { RequestedFastMode } from "../../domain/runtime/pending-settings";
|
||||
import type { RequestedFastMode } from "../../domain/runtime/intent";
|
||||
import type { PendingRequestId } from "../../../../domain/pending-requests/model";
|
||||
import type { ComposerSuggestion } from "../composer/suggestions";
|
||||
import type { MessageStreamItem } from "../../domain/message-stream/items";
|
||||
|
|
@ -590,7 +590,7 @@ function reduceRuntimeSlice(state: ChatRuntimeState, action: ChatSliceAction): C
|
|||
case "runtime/requested-collaboration-mode-set":
|
||||
return patchObject(state, setSelectedCollaborationModeRuntimeState(state, action.collaborationMode));
|
||||
case "runtime/pending-thread-settings-committed":
|
||||
return patchObject(state, commitPendingRuntimeSettingsPatchState(state, action.update));
|
||||
return patchObject(state, commitAppliedRuntimeSettingsPatchState(state, action.update));
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,21 +2,24 @@ import type { ModeKind } from "../../../../domain/runtime/thread-settings";
|
|||
|
||||
export type CollaborationModeSelection = ModeKind;
|
||||
export type ActiveCollaborationMode = CollaborationModeSelection | null;
|
||||
export type PendingRuntimeSetting<T> =
|
||||
|
||||
// Pending runtime intents are panel-side user requests, not app-server payload values.
|
||||
// They are projected for display first and converted to transport values only at the app-server boundary.
|
||||
export type PendingRuntimeIntent<T> =
|
||||
| { readonly kind: "unchanged" }
|
||||
| { readonly kind: "set"; readonly value: T }
|
||||
| { readonly kind: "resetToConfig" };
|
||||
export type RequestedFastMode = "enabled" | "disabled";
|
||||
|
||||
export function unchangedRuntimeSetting<T>(): PendingRuntimeSetting<T> {
|
||||
export function unchangedRuntimeIntent<T>(): PendingRuntimeIntent<T> {
|
||||
return { kind: "unchanged" };
|
||||
}
|
||||
|
||||
export function setPendingRuntimeSetting<T>(value: T): PendingRuntimeSetting<T> {
|
||||
export function setRuntimeIntentValue<T>(value: T): PendingRuntimeIntent<T> {
|
||||
return { kind: "set", value };
|
||||
}
|
||||
|
||||
export function resetRuntimeSettingToConfig<T>(): PendingRuntimeSetting<T> {
|
||||
export function resetRuntimeIntentToConfig<T>(): PendingRuntimeIntent<T> {
|
||||
return { kind: "resetToConfig" };
|
||||
}
|
||||
|
||||
|
|
@ -2,7 +2,7 @@ import type { ModelMetadata, ReasoningEffort } from "../../../../domain/catalog/
|
|||
import type { RuntimeConfigSnapshot } from "../../../../domain/runtime/config";
|
||||
import type { RateLimitSnapshot, ThreadTokenUsage } from "../../../../domain/runtime/metrics";
|
||||
import type { ActivePermissionProfile, ApprovalPolicy, ApprovalsReviewer, ServiceTier } from "../../../../domain/runtime/policy";
|
||||
import type { ActiveCollaborationMode, CollaborationModeSelection, PendingRuntimeSetting, RequestedFastMode } from "./pending-settings";
|
||||
import type { ActiveCollaborationMode, CollaborationModeSelection, PendingRuntimeIntent, RequestedFastMode } from "./intent";
|
||||
|
||||
export interface RuntimeSnapshot {
|
||||
runtimeConfig: RuntimeConfigSnapshot | null;
|
||||
|
|
@ -14,11 +14,11 @@ export interface RuntimeSnapshot {
|
|||
activeApprovalPolicy: ApprovalPolicy | null;
|
||||
activeApprovalsReviewer: ApprovalsReviewer | null;
|
||||
activePermissionProfile: ActivePermissionProfile | null;
|
||||
requestedModel: PendingRuntimeSetting<string>;
|
||||
requestedReasoningEffort: PendingRuntimeSetting<ReasoningEffort>;
|
||||
requestedApprovalsReviewer: PendingRuntimeSetting<ApprovalsReviewer>;
|
||||
requestedModel: PendingRuntimeIntent<string>;
|
||||
requestedReasoningEffort: PendingRuntimeIntent<ReasoningEffort>;
|
||||
requestedApprovalsReviewer: PendingRuntimeIntent<ApprovalsReviewer>;
|
||||
selectedCollaborationMode: CollaborationModeSelection;
|
||||
requestedFastMode: PendingRuntimeSetting<RequestedFastMode>;
|
||||
requestedFastMode: PendingRuntimeIntent<RequestedFastMode>;
|
||||
tokenUsage: ThreadTokenUsage | null;
|
||||
rateLimit: RateLimitSnapshot | null;
|
||||
hasThreadTurns: boolean;
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@ import {
|
|||
import type { RuntimeSettingsPatch } from "../../../../domain/runtime/thread-settings";
|
||||
import { normalizeReasoningEffort, type ReasoningEffort } from "../../../../domain/catalog/metadata";
|
||||
import {
|
||||
resetRuntimeSettingToConfig,
|
||||
setPendingRuntimeSetting,
|
||||
unchangedRuntimeSetting,
|
||||
resetRuntimeIntentToConfig,
|
||||
setRuntimeIntentValue,
|
||||
unchangedRuntimeIntent,
|
||||
type ActiveCollaborationMode,
|
||||
type CollaborationModeSelection,
|
||||
type PendingRuntimeSetting,
|
||||
type PendingRuntimeIntent,
|
||||
type RequestedFastMode,
|
||||
} from "./pending-settings";
|
||||
} from "./intent";
|
||||
|
||||
export interface ChatRuntimeState {
|
||||
readonly activeModel: string | null;
|
||||
|
|
@ -25,11 +25,11 @@ export interface ChatRuntimeState {
|
|||
readonly activeApprovalPolicy: ApprovalPolicy | null;
|
||||
readonly activeApprovalsReviewer: ApprovalsReviewer | null;
|
||||
readonly activePermissionProfile: ActivePermissionProfile | null;
|
||||
readonly requestedModel: PendingRuntimeSetting<string>;
|
||||
readonly requestedReasoningEffort: PendingRuntimeSetting<ReasoningEffort>;
|
||||
readonly requestedApprovalsReviewer: PendingRuntimeSetting<ApprovalsReviewer>;
|
||||
readonly requestedModel: PendingRuntimeIntent<string>;
|
||||
readonly requestedReasoningEffort: PendingRuntimeIntent<ReasoningEffort>;
|
||||
readonly requestedApprovalsReviewer: PendingRuntimeIntent<ApprovalsReviewer>;
|
||||
readonly selectedCollaborationMode: CollaborationModeSelection;
|
||||
readonly requestedFastMode: PendingRuntimeSetting<RequestedFastMode>;
|
||||
readonly requestedFastMode: PendingRuntimeIntent<RequestedFastMode>;
|
||||
}
|
||||
|
||||
export function initialActiveChatRuntimeState(): Pick<
|
||||
|
|
@ -56,67 +56,67 @@ export function initialActiveChatRuntimeState(): Pick<
|
|||
export function initialChatRuntimeState(): ChatRuntimeState {
|
||||
return {
|
||||
...initialActiveChatRuntimeState(),
|
||||
requestedModel: unchangedRuntimeSetting(),
|
||||
requestedReasoningEffort: unchangedRuntimeSetting(),
|
||||
requestedApprovalsReviewer: unchangedRuntimeSetting(),
|
||||
requestedModel: unchangedRuntimeIntent(),
|
||||
requestedReasoningEffort: unchangedRuntimeIntent(),
|
||||
requestedApprovalsReviewer: unchangedRuntimeIntent(),
|
||||
selectedCollaborationMode: "default",
|
||||
requestedFastMode: unchangedRuntimeSetting(),
|
||||
requestedFastMode: unchangedRuntimeIntent(),
|
||||
};
|
||||
}
|
||||
|
||||
export function requestModelRuntimeState(state: ChatRuntimeState, model: string): ChatRuntimeState {
|
||||
return {
|
||||
...state,
|
||||
requestedModel: setPendingRuntimeSetting(model),
|
||||
requestedModel: setRuntimeIntentValue(model),
|
||||
};
|
||||
}
|
||||
|
||||
export function resetModelToConfigRuntimeState(state: ChatRuntimeState): ChatRuntimeState {
|
||||
return {
|
||||
...state,
|
||||
requestedModel: resetRuntimeSettingToConfig(),
|
||||
requestedModel: resetRuntimeIntentToConfig(),
|
||||
};
|
||||
}
|
||||
|
||||
export function requestReasoningEffortRuntimeState(state: ChatRuntimeState, effort: ReasoningEffort): ChatRuntimeState {
|
||||
return {
|
||||
...state,
|
||||
requestedReasoningEffort: setPendingRuntimeSetting(effort),
|
||||
requestedReasoningEffort: setRuntimeIntentValue(effort),
|
||||
};
|
||||
}
|
||||
|
||||
export function resetReasoningEffortToConfigRuntimeState(state: ChatRuntimeState): ChatRuntimeState {
|
||||
return {
|
||||
...state,
|
||||
requestedReasoningEffort: resetRuntimeSettingToConfig(),
|
||||
requestedReasoningEffort: resetRuntimeIntentToConfig(),
|
||||
};
|
||||
}
|
||||
|
||||
export function requestFastModeRuntimeState(state: ChatRuntimeState, fastMode: RequestedFastMode): ChatRuntimeState {
|
||||
return {
|
||||
...state,
|
||||
requestedFastMode: setPendingRuntimeSetting(fastMode),
|
||||
requestedFastMode: setRuntimeIntentValue(fastMode),
|
||||
};
|
||||
}
|
||||
|
||||
export function clearRequestedFastModeRuntimeState(state: ChatRuntimeState): ChatRuntimeState {
|
||||
return {
|
||||
...state,
|
||||
requestedFastMode: unchangedRuntimeSetting(),
|
||||
requestedFastMode: unchangedRuntimeIntent(),
|
||||
};
|
||||
}
|
||||
|
||||
export function requestApprovalsReviewerRuntimeState(state: ChatRuntimeState, approvalsReviewer: ApprovalsReviewer): ChatRuntimeState {
|
||||
return {
|
||||
...state,
|
||||
requestedApprovalsReviewer: setPendingRuntimeSetting(approvalsReviewer),
|
||||
requestedApprovalsReviewer: setRuntimeIntentValue(approvalsReviewer),
|
||||
};
|
||||
}
|
||||
|
||||
export function clearRequestedApprovalsReviewerRuntimeState(state: ChatRuntimeState): ChatRuntimeState {
|
||||
return {
|
||||
...state,
|
||||
requestedApprovalsReviewer: unchangedRuntimeSetting(),
|
||||
requestedApprovalsReviewer: unchangedRuntimeIntent(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -130,23 +130,23 @@ export function setSelectedCollaborationModeRuntimeState(
|
|||
};
|
||||
}
|
||||
|
||||
export function commitPendingRuntimeSettingsPatchState(state: ChatRuntimeState, update: RuntimeSettingsPatch): ChatRuntimeState {
|
||||
export function commitAppliedRuntimeSettingsPatchState(state: ChatRuntimeState, update: RuntimeSettingsPatch): ChatRuntimeState {
|
||||
return {
|
||||
...state,
|
||||
...("model" in update ? { activeModel: update.model ?? null, requestedModel: unchangedRuntimeSetting<string>() } : {}),
|
||||
...("model" in update ? { activeModel: update.model ?? null, requestedModel: unchangedRuntimeIntent<string>() } : {}),
|
||||
...("effort" in update
|
||||
? {
|
||||
activeReasoningEffort: normalizeReasoningEffort(update.effort),
|
||||
requestedReasoningEffort: unchangedRuntimeSetting<ReasoningEffort>(),
|
||||
requestedReasoningEffort: unchangedRuntimeIntent<ReasoningEffort>(),
|
||||
}
|
||||
: {}),
|
||||
...("serviceTier" in update
|
||||
? { activeServiceTier: parseServiceTier(update.serviceTier), requestedFastMode: unchangedRuntimeSetting<RequestedFastMode>() }
|
||||
? { activeServiceTier: parseServiceTier(update.serviceTier), requestedFastMode: unchangedRuntimeIntent<RequestedFastMode>() }
|
||||
: {}),
|
||||
...("approvalsReviewer" in update
|
||||
? {
|
||||
activeApprovalsReviewer: update.approvalsReviewer ?? null,
|
||||
requestedApprovalsReviewer: unchangedRuntimeSetting<ApprovalsReviewer>(),
|
||||
requestedApprovalsReviewer: unchangedRuntimeIntent<ApprovalsReviewer>(),
|
||||
}
|
||||
: {}),
|
||||
...(update.collaborationMode ? { activeCollaborationMode: update.collaborationMode.mode } : {}),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ReasoningEffort } from "../../../../domain/catalog/metadata";
|
||||
import type { CollaborationModeSelection } from "../../domain/runtime/pending-settings";
|
||||
import type { CollaborationModeSelection } from "../../domain/runtime/intent";
|
||||
|
||||
export function compactReasoningEffortLabel(effort: ReasoningEffort | null): string {
|
||||
if (!effort) return "default";
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import type { ModelMetadata } from "../../../../src/domain/catalog/metadata";
|
|||
import { chatStateFixture, chatStateWith } from "../support/state";
|
||||
|
||||
describe("createChatRuntimeSettingsActions", () => {
|
||||
it("applies pending runtime overrides through thread settings and commits them", async () => {
|
||||
it("applies pending runtime intents through thread settings and commits them", async () => {
|
||||
let state = chatStateFixture();
|
||||
state = chatStateWith(state, { activeThread: { id: "thread" } });
|
||||
const store = createChatStateStore(state);
|
||||
|
|
@ -193,7 +193,7 @@ describe("createChatRuntimeSettingsActions", () => {
|
|||
expect(messages).toEqual(["Plan mode on for subsequent turns."]);
|
||||
});
|
||||
|
||||
it("leaves pending override in place when the app-server update fails", async () => {
|
||||
it("leaves pending runtime intent in place when the app-server update fails", async () => {
|
||||
let state = chatStateFixture();
|
||||
state = chatStateWith(state, { activeThread: { id: "thread" } });
|
||||
const store = createChatStateStore(state);
|
||||
|
|
@ -267,7 +267,7 @@ describe("createChatRuntimeSettingsActions", () => {
|
|||
expect(messages).toEqual([]);
|
||||
});
|
||||
|
||||
it("does not commit stale runtime updates after a newer pending override replaces them", async () => {
|
||||
it("does not commit stale runtime updates after a newer pending intent replaces them", async () => {
|
||||
let state = chatStateFixture();
|
||||
state = chatStateWith(state, { activeThread: { id: "thread" } });
|
||||
const store = createChatStateStore(state);
|
||||
|
|
|
|||
|
|
@ -666,7 +666,7 @@ describe("chatReducer", () => {
|
|||
expect(objectiveChanged.ui.disclosures.goalObjectiveExpanded.size).toBe(0);
|
||||
});
|
||||
|
||||
it("commits pending runtime settings and resets applied overrides", () => {
|
||||
it("commits applied runtime settings and clears applied intents", () => {
|
||||
let state = chatStateFixture();
|
||||
state = chatReducer(state, { type: "runtime/model-requested", model: "gpt-5.1" });
|
||||
state = chatReducer(state, { type: "runtime/reasoning-effort-requested", effort: "high" });
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { collaborationModeLabel } from "../../src/features/chat/presentation/runtime/messages";
|
||||
import { nextCollaborationMode } from "../../src/features/chat/domain/runtime/pending-settings";
|
||||
import { nextCollaborationMode } from "../../src/features/chat/domain/runtime/intent";
|
||||
|
||||
describe("runtime collaboration mode", () => {
|
||||
it("toggles between Default and Plan mode", () => {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import {
|
|||
supportedReasoningEfforts,
|
||||
} from "../../src/features/chat/domain/runtime/effective";
|
||||
import type { RuntimeSnapshot } from "../../src/features/chat/domain/runtime/snapshot";
|
||||
import { resetRuntimeSettingToConfig, setPendingRuntimeSetting } from "../../src/features/chat/domain/runtime/pending-settings";
|
||||
import { resetRuntimeIntentToConfig, setRuntimeIntentValue } from "../../src/features/chat/domain/runtime/intent";
|
||||
import {
|
||||
pendingRuntimeSettingsPatch,
|
||||
serviceTierRequestForThreadStart,
|
||||
|
|
@ -39,8 +39,8 @@ describe("runtime settings", () => {
|
|||
|
||||
it("keeps runtime defaults, resets, and collaboration mode semantics distinct", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
requestedModel: resetRuntimeSettingToConfig(),
|
||||
requestedReasoningEffort: resetRuntimeSettingToConfig(),
|
||||
requestedModel: resetRuntimeIntentToConfig(),
|
||||
requestedReasoningEffort: resetRuntimeIntentToConfig(),
|
||||
});
|
||||
|
||||
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBe("gpt-5.5");
|
||||
|
|
@ -51,10 +51,10 @@ describe("runtime settings", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("uses explicit runtime overrides as current values and settings payload values", () => {
|
||||
it("projects explicit runtime intents into current values and settings payload values", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
requestedModel: setPendingRuntimeSetting("gpt-5.4"),
|
||||
requestedReasoningEffort: setPendingRuntimeSetting("low"),
|
||||
requestedModel: setRuntimeIntentValue("gpt-5.4"),
|
||||
requestedReasoningEffort: setRuntimeIntentValue("low"),
|
||||
});
|
||||
|
||||
expect(currentModel(snapshot, snapshotConfig(snapshot))).toBe("gpt-5.4");
|
||||
|
|
@ -80,7 +80,7 @@ describe("runtime settings", () => {
|
|||
it("keeps model reset tied to config when active thread model differs", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
activeModel: "gpt-5-active",
|
||||
requestedModel: resetRuntimeSettingToConfig(),
|
||||
requestedModel: resetRuntimeIntentToConfig(),
|
||||
runtimeConfig: runtimeConfigFixture({
|
||||
model_reasoning_effort: "high",
|
||||
service_tier: "flex",
|
||||
|
|
@ -98,8 +98,8 @@ describe("runtime settings", () => {
|
|||
it("builds the Plan collaboration mode payload from selected runtime settings", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
selectedCollaborationMode: "plan",
|
||||
requestedModel: setPendingRuntimeSetting("gpt-5.5"),
|
||||
requestedReasoningEffort: setPendingRuntimeSetting("high"),
|
||||
requestedModel: setRuntimeIntentValue("gpt-5.5"),
|
||||
requestedReasoningEffort: setRuntimeIntentValue("high"),
|
||||
});
|
||||
|
||||
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
||||
|
|
@ -145,10 +145,10 @@ describe("runtime settings", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("keeps collaboration mode settings separate from reviewer and direct runtime overrides", () => {
|
||||
it("keeps collaboration mode settings separate from reviewer and direct runtime intents", () => {
|
||||
const reviewerSnapshot = runtimeSnapshot({
|
||||
selectedCollaborationMode: "plan",
|
||||
requestedApprovalsReviewer: setPendingRuntimeSetting("auto_review"),
|
||||
requestedApprovalsReviewer: setRuntimeIntentValue("auto_review"),
|
||||
});
|
||||
const activeRuntimeSnapshot = runtimeSnapshot({
|
||||
selectedCollaborationMode: "plan",
|
||||
|
|
@ -183,7 +183,7 @@ describe("runtime settings", () => {
|
|||
|
||||
it("resolves auto-review mode from requested, active, then effective config", () => {
|
||||
const requested = runtimeSnapshot({
|
||||
requestedApprovalsReviewer: setPendingRuntimeSetting("user"),
|
||||
requestedApprovalsReviewer: setRuntimeIntentValue("user"),
|
||||
activeApprovalsReviewer: "auto_review",
|
||||
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "guardian_subagent" }),
|
||||
});
|
||||
|
|
@ -219,7 +219,7 @@ describe("runtime settings", () => {
|
|||
|
||||
it("uses requested reviewer above active and configured reviewers", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
requestedApprovalsReviewer: setPendingRuntimeSetting("user"),
|
||||
requestedApprovalsReviewer: setRuntimeIntentValue("user"),
|
||||
activeApprovalsReviewer: "user",
|
||||
runtimeConfig: runtimeConfigFixture({ approvals_reviewer: "auto_review" }),
|
||||
});
|
||||
|
|
@ -308,7 +308,7 @@ describe("runtime settings", () => {
|
|||
|
||||
it("uses requested Fast mode above active and configured service tiers", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
requestedFastMode: setPendingRuntimeSetting("disabled"),
|
||||
requestedFastMode: setRuntimeIntentValue("disabled"),
|
||||
activeServiceTier: "flex",
|
||||
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
||||
});
|
||||
|
|
@ -318,7 +318,7 @@ describe("runtime settings", () => {
|
|||
});
|
||||
|
||||
it("resolves requested approval reviewer without adding it to turn runtime settings", () => {
|
||||
const snapshot = runtimeSnapshot({ requestedApprovalsReviewer: setPendingRuntimeSetting("auto_review") });
|
||||
const snapshot = runtimeSnapshot({ requestedApprovalsReviewer: setRuntimeIntentValue("auto_review") });
|
||||
|
||||
expect(autoReviewActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
||||
expect(pendingRuntimeSettingsPatch(snapshot, snapshotConfig(snapshot))).toMatchObject({
|
||||
|
|
@ -326,7 +326,7 @@ describe("runtime settings", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("treats active thread runtime as display state without persisting it into turn overrides", () => {
|
||||
it("treats active thread runtime as display state without persisting it into runtime intent patches", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
activeModel: "gpt-5-active",
|
||||
activeServiceTier: "fast",
|
||||
|
|
@ -341,7 +341,7 @@ describe("runtime settings", () => {
|
|||
|
||||
it("uses the explicit config when finding supported reasoning efforts", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
requestedModel: resetRuntimeSettingToConfig(),
|
||||
requestedModel: resetRuntimeIntentToConfig(),
|
||||
runtimeConfig: runtimeConfigFixture({ model: "snapshot-model" }),
|
||||
availableModels: [
|
||||
{ ...modelFixture("snapshot-model"), supportedReasoningEfforts: ["low"] },
|
||||
|
|
@ -354,7 +354,7 @@ describe("runtime settings", () => {
|
|||
});
|
||||
|
||||
it("summarizes service tier and context meter state from one runtime snapshot", () => {
|
||||
const snapshot = runtimeSnapshot({ requestedFastMode: setPendingRuntimeSetting("enabled"), activeThreadId: "thread" });
|
||||
const snapshot = runtimeSnapshot({ requestedFastMode: setRuntimeIntentValue("enabled"), activeThreadId: "thread" });
|
||||
|
||||
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
||||
expect(fastModeActive(snapshot, snapshotConfig(snapshot))).toBe(true);
|
||||
|
|
@ -394,7 +394,7 @@ describe("runtime settings", () => {
|
|||
it("serializes disabled Fast mode as a null service tier request", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
||||
requestedFastMode: setPendingRuntimeSetting("disabled"),
|
||||
requestedFastMode: setRuntimeIntentValue("disabled"),
|
||||
});
|
||||
|
||||
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBeNull();
|
||||
|
|
@ -405,7 +405,7 @@ describe("runtime settings", () => {
|
|||
it("serializes service tier reset for thread start as an explicit null request", () => {
|
||||
const snapshot = runtimeSnapshot({
|
||||
runtimeConfig: runtimeConfigFixture({ service_tier: "fast" }),
|
||||
requestedFastMode: resetRuntimeSettingToConfig(),
|
||||
requestedFastMode: resetRuntimeIntentToConfig(),
|
||||
});
|
||||
|
||||
expect(currentServiceTier(snapshot, snapshotConfig(snapshot))).toBe("fast");
|
||||
|
|
@ -419,7 +419,7 @@ describe("runtime settings", () => {
|
|||
serviceTiers: [{ id: "priority", name: "Fast" }],
|
||||
};
|
||||
const snapshot = runtimeSnapshot({
|
||||
requestedFastMode: setPendingRuntimeSetting("enabled"),
|
||||
requestedFastMode: setRuntimeIntentValue("enabled"),
|
||||
runtimeConfig: runtimeConfigFixture({ model: "gpt-5.5" }),
|
||||
availableModels: [model],
|
||||
});
|
||||
|
|
@ -428,7 +428,7 @@ describe("runtime settings", () => {
|
|||
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBe("priority");
|
||||
});
|
||||
|
||||
it("omits service tier when neither config nor override selects one", () => {
|
||||
it("omits service tier when neither config nor pending intent selects one", () => {
|
||||
const snapshot = runtimeSnapshot({ runtimeConfig: runtimeConfigFixture({}) });
|
||||
|
||||
expect(serviceTierRequestForThreadStart(snapshot, snapshotConfig(snapshot))).toBeUndefined();
|
||||
|
|
|
|||
Loading…
Reference in a new issue