mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-07 00:44:49 +00:00
The agent snapshot's `options` are the state and `controls` only draw them. Running and closed agents draw from the snapshot; drafts and profile forms ask `provider.controls.list.request` with their `providerOptions`, so aliases such as a legacy Fast profile's `service_tier: "fast"` are resolved once, by the daemon, and the draft keeps Fast highlighted. A draft adds only the user's edits and each provider's last-used control values; applying a profile seeds its non-control options (e.g. `sandbox_mode`) into the draft, and a profile form saves them back instead of pruning to the controls it can draw. A daemon without `server_info.features.providerOptionControls` still sends `features` and `featureValues`. `LegacyProviderOptions` in the client package is the one place that translates snapshots, draft listings, create and apply requests, and daemon-config profiles, so the app never branches on it. Persisted preferences and tab layouts rename `featureValues` through tagged COMPAT preprocessors. The features/controls bridge moves from the server into the protocol package so the client can reuse it.
93 lines
2.1 KiB
TypeScript
93 lines
2.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { mergeProviderPreferences } from "./use-form-preferences";
|
|
|
|
describe("mergeProviderPreferences", () => {
|
|
it("stores the selected model for a provider", () => {
|
|
expect(
|
|
mergeProviderPreferences({
|
|
preferences: {},
|
|
provider: "claude",
|
|
updates: { model: "claude-opus-4-6" },
|
|
}),
|
|
).toEqual({
|
|
provider: "claude",
|
|
providerPreferences: {
|
|
claude: {
|
|
model: "claude-opus-4-6",
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it("merges thinking preferences by model without dropping existing entries", () => {
|
|
expect(
|
|
mergeProviderPreferences({
|
|
preferences: {
|
|
provider: "claude",
|
|
providerPreferences: {
|
|
claude: {
|
|
model: "claude-sonnet-4-6",
|
|
thinkingByModel: {
|
|
"claude-sonnet-4-6": "medium",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
provider: "claude",
|
|
updates: {
|
|
thinkingByModel: {
|
|
"claude-opus-4-6": "high",
|
|
},
|
|
},
|
|
}),
|
|
).toEqual({
|
|
provider: "claude",
|
|
providerPreferences: {
|
|
claude: {
|
|
model: "claude-sonnet-4-6",
|
|
thinkingByModel: {
|
|
"claude-sonnet-4-6": "medium",
|
|
"claude-opus-4-6": "high",
|
|
},
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it("merges feature values without dropping existing entries", () => {
|
|
expect(
|
|
mergeProviderPreferences({
|
|
preferences: {
|
|
provider: "codex",
|
|
providerPreferences: {
|
|
codex: {
|
|
model: "gpt-5.4",
|
|
options: {
|
|
fast_mode: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
provider: "codex",
|
|
updates: {
|
|
options: {
|
|
plan_mode: true,
|
|
},
|
|
},
|
|
}),
|
|
).toEqual({
|
|
provider: "codex",
|
|
providerPreferences: {
|
|
codex: {
|
|
model: "gpt-5.4",
|
|
options: {
|
|
fast_mode: true,
|
|
plan_mode: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
});
|
|
});
|