Files
paseo/packages/app/src/agent-profiles/internal/materialize-profile.test.ts
T
Mohamed Boudra 0d82eed6b5 feat(app): the client and app work on options and controls
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.
2026-11-05 15:30:11 +01:00

120 lines
3.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { AgentProfile } from "@getpaseo/protocol/messages";
import {
materializeAgentProfile,
reconcileMaterializedProfileMode,
toAgentConfigApply,
} from "./materialize-profile";
function profile(overrides: Partial<AgentProfile> = {}): AgentProfile {
return {
id: "ui-work",
name: "UI work",
provider: "claude",
...overrides,
};
}
describe("materializeAgentProfile", () => {
it("resolves every field a full profile names", () => {
expect(
materializeAgentProfile(
profile({
model: "claude-opus-5",
modeId: "plan",
thinkingOptionId: "think-hard",
options: { web_search: true },
}),
),
).toEqual({
provider: "claude",
modelId: "claude-opus-5",
modeId: "plan",
thinkingOptionId: "think-hard",
options: { web_search: true },
});
});
it("treats omitted and blank fields the same", () => {
expect(materializeAgentProfile(profile({ model: " ", modeId: "" }))).toEqual({
provider: "claude",
modelId: "",
modeId: "",
thinkingOptionId: "",
options: {},
});
});
it("trims stored ids", () => {
expect(materializeAgentProfile(profile({ model: " claude-opus-5 " })).modelId).toBe(
"claude-opus-5",
);
});
});
describe("toAgentConfigApply", () => {
it("sends every value the profile names", () => {
expect(
toAgentConfigApply(
materializeAgentProfile(
profile({
model: "claude-opus-5",
modeId: "plan",
thinkingOptionId: "think-hard",
options: { web_search: true },
}),
),
),
).toEqual({
modelId: "claude-opus-5",
modeId: "plan",
thinkingOptionId: "think-hard",
options: { web_search: true },
});
});
it("omits what the profile leaves alone rather than clearing it", () => {
expect(toAgentConfigApply(materializeAgentProfile(profile({ modeId: "plan" })))).toEqual({
modeId: "plan",
});
});
it("omits an empty feature map so the agent keeps its own feature values", () => {
expect(
toAgentConfigApply(materializeAgentProfile(profile({ options: {} }))),
).not.toHaveProperty("options");
});
it("never carries a provider, which a running agent cannot change", () => {
expect(
toAgentConfigApply(materializeAgentProfile(profile({ model: "claude-opus-5" }))),
).not.toHaveProperty("provider");
});
});
describe("reconcileMaterializedProfileMode", () => {
it("waits when the current provider mode catalog is unknown", () => {
expect(
reconcileMaterializedProfileMode(materializeAgentProfile(profile({ modeId: "plan" })), null),
).toBeNull();
});
it("drops a profile mode removed from the current provider catalog", () => {
expect(
reconcileMaterializedProfileMode(
materializeAgentProfile(profile({ modeId: "removed-mode" })),
["plan", "default"],
),
).toMatchObject({ modeId: "" });
});
it("preserves a profile mode still offered by the provider", () => {
expect(
reconcileMaterializedProfileMode(materializeAgentProfile(profile({ modeId: "plan" })), [
"plan",
"default",
]),
).toMatchObject({ modeId: "plan" });
});
});