Cluster T3.a — mechanical fixes for consistent-return and no-floating-promises. Files touched (15): - server/shared/tool-call-display.ts — default throw in buildCanonicalDetailDisplay switch - server/agent/prompt-attachments.ts — default throw in renderPromptAttachmentAsText switch - server/workspace-directory.ts — default throw in getSortValue switch - server/agent/mcp-server.ts — default throw in mcpCreateWorktreeInput switch - server/terminal/terminal-session-controller.ts — default return in dispatch switch - server/daemon-e2e/agent-configs.ts — default return false in isProviderAvailable switch - server/agent/agent-manager.ts — void dispatchSessionEvent fire-and-forget call - server/agent/mcp-shared.ts — void 4 notify() floating calls - app/agent-status-bar.utils.ts — default throw in getStatusSelectorHint switch - app/keyboard-shortcuts.ts — default throw in resolvePayload switch - app/resolve-agent-form.ts — default throw in resolveAgentForm switch - app/ui/dropdown-menu.tsx — void .then() + return undefined for promise/always-return - app/use-agent-form-state.ts — void refreshSnapshot() floating call - cli/worktree/create.ts — default throw in toDaemonCreateInput switch - cli/onboard.ts — return process.exit(1) to satisfy consistent-return in catch Deferred (outside 15-file cap or in EXCLUDE list): - server/worktree-session.ts — getSortValue (same pattern, cap reached) - Multiple files with other errors (unbound-method, unsafe-type-assertion) are separate clusters
148 lines
4.7 KiB
TypeScript
148 lines
4.7 KiB
TypeScript
import type { AgentFeature, AgentModelDefinition } from "@server/server/agent/agent-sdk-types";
|
|
|
|
export type ExplainedStatusSelector = "mode" | "model" | "thinking";
|
|
export type FeatureHighlightColor = "blue" | "default" | "yellow";
|
|
|
|
export function getStatusSelectorHint(selector: ExplainedStatusSelector): string {
|
|
switch (selector) {
|
|
case "thinking":
|
|
return "Thinking mode";
|
|
case "model":
|
|
return "Change model";
|
|
case "mode":
|
|
return "Change permission mode";
|
|
default:
|
|
throw new Error("unreachable");
|
|
}
|
|
}
|
|
|
|
export function normalizeModelId(modelId: string | null | undefined): string | null {
|
|
const normalized = typeof modelId === "string" ? modelId.trim() : "";
|
|
if (!normalized) {
|
|
return null;
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
export function getFeatureTooltip(feature: Pick<AgentFeature, "label" | "tooltip">): string {
|
|
return feature.tooltip ?? feature.label;
|
|
}
|
|
|
|
export function getFeatureHighlightColor(featureId: string): FeatureHighlightColor {
|
|
switch (featureId) {
|
|
case "fast_mode":
|
|
return "yellow";
|
|
case "plan_mode":
|
|
return "blue";
|
|
default:
|
|
return "default";
|
|
}
|
|
}
|
|
|
|
function findModelById(
|
|
models: AgentModelDefinition[] | null,
|
|
modelId: string | null,
|
|
): AgentModelDefinition | null {
|
|
if (!models || !modelId) {
|
|
return null;
|
|
}
|
|
return models.find((model) => model.id === modelId) ?? null;
|
|
}
|
|
|
|
function getFallbackModel(models: AgentModelDefinition[] | null): AgentModelDefinition | null {
|
|
return models?.find((model) => model.isDefault) ?? models?.[0] ?? null;
|
|
}
|
|
|
|
function resolvePreferredModelId(
|
|
runtimeSelectedModel: AgentModelDefinition | null,
|
|
normalizedConfiguredModelId: string | null,
|
|
normalizedRuntimeModelId: string | null,
|
|
): string | null {
|
|
return runtimeSelectedModel?.id ?? normalizedConfiguredModelId ?? normalizedRuntimeModelId;
|
|
}
|
|
|
|
function pickSelectedModel(
|
|
models: AgentModelDefinition[] | null,
|
|
preferredModelId: string | null,
|
|
fallbackModel: AgentModelDefinition | null,
|
|
): AgentModelDefinition | null {
|
|
if (!models || !preferredModelId) {
|
|
return fallbackModel;
|
|
}
|
|
return findModelById(models, preferredModelId) ?? fallbackModel;
|
|
}
|
|
|
|
function resolveThinkingId(
|
|
explicitThinkingOptionId: string | null | undefined,
|
|
selectedModel: AgentModelDefinition | null,
|
|
): string | null {
|
|
if (explicitThinkingOptionId && explicitThinkingOptionId !== "default") {
|
|
return explicitThinkingOptionId;
|
|
}
|
|
return selectedModel?.defaultThinkingOptionId ?? null;
|
|
}
|
|
|
|
type ThinkingOption = NonNullable<AgentModelDefinition["thinkingOptions"]>[number];
|
|
|
|
function resolveEffectiveThinking(
|
|
thinkingOptions: ThinkingOption[] | null,
|
|
resolvedThinkingId: string | null,
|
|
): ThinkingOption | null {
|
|
const selectedThinking =
|
|
thinkingOptions?.find((option) => option.id === resolvedThinkingId) ?? null;
|
|
return selectedThinking ?? thinkingOptions?.[0] ?? null;
|
|
}
|
|
|
|
function resolveModelDisplay(
|
|
selectedModel: AgentModelDefinition | null,
|
|
preferredModelId: string | null,
|
|
fallbackModel: AgentModelDefinition | null,
|
|
): { activeModelId: string | null; displayModel: string } {
|
|
return {
|
|
activeModelId: selectedModel?.id ?? preferredModelId ?? null,
|
|
displayModel:
|
|
selectedModel?.label ?? preferredModelId ?? fallbackModel?.label ?? "Unknown model",
|
|
};
|
|
}
|
|
|
|
export function resolveAgentModelSelection(input: {
|
|
models: AgentModelDefinition[] | null;
|
|
runtimeModelId: string | null | undefined;
|
|
configuredModelId: string | null | undefined;
|
|
explicitThinkingOptionId: string | null | undefined;
|
|
}) {
|
|
const { models, runtimeModelId, configuredModelId, explicitThinkingOptionId } = input;
|
|
const normalizedRuntimeModelId = normalizeModelId(runtimeModelId);
|
|
const normalizedConfiguredModelId = normalizeModelId(configuredModelId);
|
|
|
|
const runtimeSelectedModel = findModelById(models, normalizedRuntimeModelId);
|
|
const preferredModelId = resolvePreferredModelId(
|
|
runtimeSelectedModel,
|
|
normalizedConfiguredModelId,
|
|
normalizedRuntimeModelId,
|
|
);
|
|
const fallbackModel = getFallbackModel(models);
|
|
const selectedModel = pickSelectedModel(models, preferredModelId, fallbackModel);
|
|
|
|
const { activeModelId, displayModel } = resolveModelDisplay(
|
|
selectedModel,
|
|
preferredModelId,
|
|
fallbackModel,
|
|
);
|
|
|
|
const thinkingOptions = selectedModel?.thinkingOptions ?? null;
|
|
const resolvedThinkingId = resolveThinkingId(explicitThinkingOptionId, selectedModel);
|
|
const effectiveThinking = resolveEffectiveThinking(thinkingOptions, resolvedThinkingId);
|
|
const selectedThinkingId = effectiveThinking?.id ?? null;
|
|
const displayThinking = effectiveThinking?.label ?? selectedThinkingId ?? "Unknown";
|
|
|
|
return {
|
|
selectedModel,
|
|
activeModelId,
|
|
displayModel,
|
|
thinkingOptions,
|
|
selectedThinkingId,
|
|
displayThinking,
|
|
};
|
|
}
|