mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-07 00:44:49 +00:00
* fix(app): keep profile modes scoped to providers Applying a profile through sequential field setters allowed a provider change to race mode persistence, poisoning modeless provider preferences with another provider's mode. Apply profiles as one form transition and heal invalid provider-scoped mode preferences when profiles are used. * test(app): cover profile features across providers
120 lines
3.3 KiB
TypeScript
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",
|
|
featureValues: { web_search: true },
|
|
}),
|
|
),
|
|
).toEqual({
|
|
provider: "claude",
|
|
modelId: "claude-opus-5",
|
|
modeId: "plan",
|
|
thinkingOptionId: "think-hard",
|
|
featureValues: { web_search: true },
|
|
});
|
|
});
|
|
|
|
it("treats omitted and blank fields the same", () => {
|
|
expect(materializeAgentProfile(profile({ model: " ", modeId: "" }))).toEqual({
|
|
provider: "claude",
|
|
modelId: "",
|
|
modeId: "",
|
|
thinkingOptionId: "",
|
|
featureValues: {},
|
|
});
|
|
});
|
|
|
|
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",
|
|
featureValues: { web_search: true },
|
|
}),
|
|
),
|
|
),
|
|
).toEqual({
|
|
modelId: "claude-opus-5",
|
|
modeId: "plan",
|
|
thinkingOptionId: "think-hard",
|
|
featureValues: { 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({ featureValues: {} }))),
|
|
).not.toHaveProperty("featureValues");
|
|
});
|
|
|
|
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" });
|
|
});
|
|
});
|