Normalize default thinking options (#1028)
This commit is contained in:
@@ -71,6 +71,15 @@ export interface AgentSelectOption {
|
||||
metadata?: AgentMetadata;
|
||||
}
|
||||
|
||||
export function normalizeAgentModelDefinition(model: AgentModelDefinition): AgentModelDefinition {
|
||||
const defaultThinkingOptionId =
|
||||
model.defaultThinkingOptionId ?? model.thinkingOptions?.find((option) => option.isDefault)?.id;
|
||||
if (!defaultThinkingOptionId || defaultThinkingOptionId === model.defaultThinkingOptionId) {
|
||||
return model;
|
||||
}
|
||||
return { ...model, defaultThinkingOptionId };
|
||||
}
|
||||
|
||||
export interface ProviderSnapshotEntry {
|
||||
provider: AgentProvider;
|
||||
status: ProviderStatus;
|
||||
|
||||
@@ -755,6 +755,45 @@ describe("model merging", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test("profile thinking option default is normalized onto the model", async () => {
|
||||
const registry = buildProviderRegistry(logger, {
|
||||
providerOverrides: {
|
||||
codex: {
|
||||
models: [
|
||||
{
|
||||
id: "profile-default",
|
||||
label: "Profile Default",
|
||||
isDefault: true,
|
||||
thinkingOptions: [
|
||||
{ id: "off", label: "Off" },
|
||||
{ id: "max", label: "Max", isDefault: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const models = await registry.codex.fetchModels({
|
||||
cwd: "/tmp/registry-models",
|
||||
force: false,
|
||||
});
|
||||
|
||||
expect(models).toEqual([
|
||||
{
|
||||
provider: "codex",
|
||||
id: "profile-default",
|
||||
label: "Profile Default",
|
||||
isDefault: true,
|
||||
thinkingOptions: [
|
||||
{ id: "off", label: "Off" },
|
||||
{ id: "max", label: "Max", isDefault: true },
|
||||
],
|
||||
defaultThinkingOptionId: "max",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test("additional models append to runtime models", async () => {
|
||||
mockState.runtimeModels.set("claude", [
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
ListPersistedAgentsOptions,
|
||||
PersistedAgentDescriptor,
|
||||
} from "./agent-sdk-types.js";
|
||||
import { normalizeAgentModelDefinition } from "./agent-sdk-types.js";
|
||||
import type { WorkspaceGitService } from "../workspace-git-service.js";
|
||||
import type {
|
||||
AgentProviderRuntimeSettingsMap,
|
||||
@@ -263,11 +264,11 @@ function mapPersistedAgentDescriptor(
|
||||
};
|
||||
}
|
||||
|
||||
function mapModel(provider: AgentProvider, model: AgentModelDefinition): AgentModelDefinition {
|
||||
return {
|
||||
...model,
|
||||
provider,
|
||||
};
|
||||
function mapModel(
|
||||
provider: AgentProvider,
|
||||
model: AgentModelDefinition | ProviderProfileModel,
|
||||
): AgentModelDefinition {
|
||||
return normalizeAgentModelDefinition({ ...model, provider });
|
||||
}
|
||||
|
||||
function mergeModels(
|
||||
@@ -281,10 +282,7 @@ function mergeModels(
|
||||
if (profileModels.length > 0 && options?.profileModelsAreAdditive !== true) {
|
||||
return mergeModelAdditions(
|
||||
provider,
|
||||
profileModels.map((model) => ({
|
||||
...model,
|
||||
provider,
|
||||
})),
|
||||
profileModels.map((model) => mapModel(provider, model)),
|
||||
additionalModels,
|
||||
);
|
||||
}
|
||||
@@ -305,10 +303,7 @@ function mergeModelAdditions(
|
||||
let hasAdditionalDefault = false;
|
||||
|
||||
for (const model of modelAdditions) {
|
||||
const additionalModel = {
|
||||
...model,
|
||||
provider,
|
||||
};
|
||||
const additionalModel = mapModel(provider, model);
|
||||
hasAdditionalDefault ||= additionalModel.isDefault === true;
|
||||
|
||||
const existingIndex = mergedModels.findIndex((candidate) => candidate.id === model.id);
|
||||
|
||||
@@ -38,6 +38,39 @@ describe("provider snapshot message schemas", () => {
|
||||
expect(parsed.enabled).toBe(true);
|
||||
});
|
||||
|
||||
test("normalizes thinking option defaults on provider snapshot models", () => {
|
||||
const parsed = ProviderSnapshotEntrySchema.parse({
|
||||
provider: "claude",
|
||||
status: "ready",
|
||||
models: [
|
||||
{
|
||||
provider: "claude",
|
||||
id: "MiniMax-M2.7",
|
||||
label: "MiniMax-M2.7",
|
||||
isDefault: true,
|
||||
thinkingOptions: [
|
||||
{ id: "off", label: "Off" },
|
||||
{ id: "max", label: "Max", isDefault: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(parsed.models).toEqual([
|
||||
{
|
||||
provider: "claude",
|
||||
id: "MiniMax-M2.7",
|
||||
label: "MiniMax-M2.7",
|
||||
isDefault: true,
|
||||
thinkingOptions: [
|
||||
{ id: "off", label: "Off" },
|
||||
{ id: "max", label: "Max", isDefault: true },
|
||||
],
|
||||
defaultThinkingOptionId: "max",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test("defaults missing enabled state in providers snapshot response entries", () => {
|
||||
const parsed = GetProvidersSnapshotResponseMessageSchema.parse({
|
||||
type: "get_providers_snapshot_response",
|
||||
|
||||
@@ -3,7 +3,10 @@ import { CLIENT_CAPS } from "./client-capabilities.js";
|
||||
import { AGENT_LIFECYCLE_STATUSES } from "./agent-lifecycle.js";
|
||||
import { MAX_EXPLICIT_AGENT_TITLE_CHARS } from "../server/agent/agent-title-limits.js";
|
||||
import { AgentProviderSchema } from "../server/agent/provider-manifest.js";
|
||||
import { TOOL_CALL_ICON_NAMES } from "../server/agent/agent-sdk-types.js";
|
||||
import {
|
||||
normalizeAgentModelDefinition,
|
||||
TOOL_CALL_ICON_NAMES,
|
||||
} from "../server/agent/agent-sdk-types.js";
|
||||
import {
|
||||
ChatCreateRequestSchema,
|
||||
ChatListRequestSchema,
|
||||
@@ -194,7 +197,8 @@ export const AgentFeatureSchema = z.discriminatedUnion("type", [
|
||||
AgentFeatureSelectSchema,
|
||||
]);
|
||||
|
||||
const AgentModelDefinitionSchema: z.ZodType<AgentModelDefinition> = z.object({
|
||||
const AgentModelDefinitionSchema: z.ZodType<AgentModelDefinition> = z
|
||||
.object({
|
||||
provider: AgentProviderSchema,
|
||||
id: z.string(),
|
||||
label: z.string(),
|
||||
@@ -203,7 +207,8 @@ const AgentModelDefinitionSchema: z.ZodType<AgentModelDefinition> = z.object({
|
||||
metadata: z.record(z.unknown()).optional(),
|
||||
thinkingOptions: z.array(AgentSelectOptionSchema).optional(),
|
||||
defaultThinkingOptionId: z.string().optional(),
|
||||
});
|
||||
})
|
||||
.transform(normalizeAgentModelDefinition);
|
||||
|
||||
export const ProviderSnapshotEntrySchema = z.object({
|
||||
provider: AgentProviderSchema,
|
||||
|
||||
Reference in New Issue
Block a user