Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 20 additions & 24 deletions assistant/src/__tests__/config-loader-platform-defaults.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ function readConfig(): Record<string, unknown> {
}

const MANAGED_SERVICES = [
"inference",
"image-generation",
"web-search",
"google-oauth",
Expand Down Expand Up @@ -126,7 +125,7 @@ describe("platform-managed config defaults", () => {
}
});

test("IS_PLATFORM=true, no config file → all 8 service modes written as 'managed'", () => {
test("IS_PLATFORM=true, no config file → all 7 managed service modes written as 'managed'", () => {
process.env.IS_PLATFORM = "true";

loadConfig();
Expand All @@ -140,7 +139,7 @@ describe("platform-managed config defaults", () => {
}
});

test("IS_PLATFORM=false, no config file → service modes default to 'your-own'", () => {
test("IS_PLATFORM=false, no config file → managed service modes default to 'your-own'", () => {
process.env.IS_PLATFORM = "false";

loadConfig();
Expand All @@ -154,7 +153,7 @@ describe("platform-managed config defaults", () => {
}
});

test("IS_PLATFORM unset, no config file → service modes default to 'your-own'", () => {
test("IS_PLATFORM unset, no config file → managed service modes default to 'your-own'", () => {
delete process.env.IS_PLATFORM;

loadConfig();
Expand All @@ -171,13 +170,13 @@ describe("platform-managed config defaults", () => {
test("IS_PLATFORM=true, config file already exists → existing service mode values are preserved", () => {
process.env.IS_PLATFORM = "true";

// Write an existing config with inference mode explicitly set to "your-own"
// Write an existing config with image-generation mode explicitly set to "your-own"
writeFileSync(
CONFIG_PATH,
JSON.stringify(
{
services: {
inference: { mode: "your-own" },
"image-generation": { mode: "your-own" },
},
},
null,
Expand All @@ -191,13 +190,11 @@ describe("platform-managed config defaults", () => {
expect(written.services).toBeDefined();
// The existing value must be preserved — backfill path, not fresh-write path
expect(
(written.services!["inference"] as { mode?: string })?.mode,
(written.services!["image-generation"] as { mode?: string })?.mode,
).toBe("your-own");
// ...and the in-memory config must mirror the explicit user choice (the
// fill-defaults pass must not override an explicit "your-own").
expect(
(config.services.inference as { mode: string }).mode,
).toBe("your-own");
expect(config.services["image-generation"].mode).toBe("your-own");
});

test("IS_PLATFORM=true, config file exists without a services key → in-memory config has all managed modes", () => {
Expand Down Expand Up @@ -367,15 +364,15 @@ describe("GET /v1/config handler — context-default fill on raw response", () =
}
});

test("IS_PLATFORM=true, raw config has explicit services.inference.mode='your-own' → preserved", () => {
test("IS_PLATFORM=true, raw config has explicit services.image-generation.mode='your-own' → preserved", () => {
process.env.IS_PLATFORM = "true";

// User has explicitly chosen "your-own" via the macOS Save flow.
// The patch handler persisted that to disk; the fill pass must not
// override an explicit user choice.
// User has explicitly chosen "your-own" for image-generation via the macOS
// Save flow. The patch handler persisted that to disk; the fill pass must
// not override an explicit user choice. inference carries no mode field.
const raw: Record<string, unknown> = {
services: {
inference: { mode: "your-own" },
"image-generation": { mode: "your-own" },
},
};

Expand All @@ -384,9 +381,8 @@ describe("GET /v1/config handler — context-default fill on raw response", () =
unknown
>;
const services = result["services"] as Record<string, { mode: string }>;
expect(services["inference"]!.mode).toBe("your-own");
// Other services were missing entirely → context defaults fill them in.
expect(services["image-generation"]!.mode).toBe("managed");
expect(services["image-generation"]!.mode).toBe("your-own");
// inference has no mode field in the schema; web-search was missing → fill.
expect(services["web-search"]!.mode).toBe("managed");
});

Expand All @@ -408,12 +404,12 @@ describe("GET /v1/config handler — context-default fill on raw response", () =
expect(result["services"]).toBeUndefined();
});

test("IS_PLATFORM=true, raw config has partial services.inference subtree → preserves user fields, fills missing mode", () => {
test("IS_PLATFORM=true, raw config has partial services subtree → preserves user fields, fills missing mode", () => {
process.env.IS_PLATFORM = "true";

// User set image-generation.provider but never chose a mode for any
// service. The fill pass adds the missing modes without clobbering
// the user-supplied provider.
// User set image-generation.provider but never chose a mode.
// The fill pass adds the missing mode without clobbering the user-supplied
// provider. inference carries no mode field (removed in Phase 1.2).
const raw: Record<string, unknown> = {
services: {
"image-generation": { provider: "openai" },
Expand All @@ -430,8 +426,8 @@ describe("GET /v1/config handler — context-default fill on raw response", () =
>;
expect(services["image-generation"]!.mode).toBe("managed");
expect(services["image-generation"]!.provider).toBe("openai");
// Inference, which was missing entirely, picks up the context default.
expect(services["inference"]!.mode).toBe("managed");
// inference is not touched by context defaults (no mode field in schema).
expect(services["inference"]).toBeUndefined();
});

// -------------------------------------------------------------------------
Expand Down
6 changes: 3 additions & 3 deletions assistant/src/__tests__/config-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ function writeConfig(obj: unknown): void {
describe("AssistantConfigSchema", () => {
test("parses empty object with full defaults", () => {
const result = AssistantConfigSchema.parse({});
// services.inference now carries only `mode`; provider/model live under
// llm.default.{provider,model} (see PR 19 of unify-llm-callsites).
expect(result.services.inference.mode).toBe("your-own");
// services.inference is now an empty object; provider/model live under
// llm.default.{provider,model}, auth routing via provider_connections.
expect(result.services.inference).toEqual({});
expect(result.llm.default.provider).toBe("anthropic");
expect(result.llm.default.model).toBe("claude-opus-4-7");
expect(result.services["image-generation"].provider).toBe("gemini");
Expand Down
62 changes: 0 additions & 62 deletions assistant/src/__tests__/config-set-platform-guard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,27 +197,6 @@ describe("config set — platform connection guard for service mode paths", () =
mockGetNestedValue = () => undefined;
});

test("config set services.inference.mode managed — fails when not connected", async () => {
const { exitCode, stdout } = await runCli([
"node",
"assistant",
"--json",
"config",
"set",
"services.inference.mode",
"managed",
]);

expect(exitCode).toBe(1);
const parsed = JSON.parse(stdout);
expect(parsed.ok).toBe(false);
expect(parsed.error).toContain("vellum platform connect");
expect(parsed.error).toContain("Not connected");
// Config should NOT have been written
expect(mockSaveRawConfigCalls).toHaveLength(0);
expect(mockSetNestedValueCalls).toHaveLength(0);
});

test("config set services.image-generation.mode your-own — succeeds without platform connection", async () => {
const { exitCode } = await runCli([
"node",
Expand Down Expand Up @@ -284,26 +263,6 @@ describe("config set — platform connection guard for service mode paths", () =
});
});

test("config get services.inference.mode — works without platform connection", async () => {
mockGetNestedValue = (_obj, key) => {
if (key === "services.inference.mode") return "your-own";
return undefined;
};

const { exitCode } = await runCli([
"node",
"assistant",
"config",
"get",
"services.inference.mode",
]);

expect(exitCode).toBe(0);
// No writes should have occurred
expect(mockSaveRawConfigCalls).toHaveLength(0);
expect(mockSetNestedValueCalls).toHaveLength(0);
});

test("config set services.web-search.mode managed — fails when not connected", async () => {
const { exitCode, stdout } = await runCli([
"node",
Expand All @@ -322,25 +281,4 @@ describe("config set — platform connection guard for service mode paths", () =
expect(mockSaveRawConfigCalls).toHaveLength(0);
});

test("config set services.inference.mode managed — succeeds when connected", async () => {
mockPlatformClientCreate = async () => ({
platformAssistantId: "asst-123",
fetch: async () => new Response(),
});

const { exitCode } = await runCli([
"node",
"assistant",
"config",
"set",
"services.inference.mode",
"managed",
]);

expect(exitCode).toBe(0);
expect(mockSetNestedValueCalls).toHaveLength(1);
expect(mockSetNestedValueCalls[0]!.key).toBe("services.inference.mode");
expect(mockSetNestedValueCalls[0]!.value).toBe("managed");
expect(mockSaveRawConfigCalls).toHaveLength(1);
});
});
Loading
Loading