Skip to content

Commit 760d370

Browse files
committed
fix: load default model if no models, only option in headless
1 parent 2854b13 commit 760d370

File tree

9 files changed

+405
-298
lines changed

9 files changed

+405
-298
lines changed

extensions/cli/src/commands/remote.test.ts

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,32 @@ describe("remote command", () => {
353353
expect(mockFetch).toHaveBeenCalledWith(
354354
new URL("agents", mockEnv.env.apiBase),
355355
expect.objectContaining({
356-
body: expect.stringContaining(`"agent":"${testConfig}"`),
356+
body: expect.stringContaining(`"config":"${testConfig}"`),
357+
}),
358+
);
359+
});
360+
361+
it("should include agent in request body when agent option is provided", async () => {
362+
const testAgent = "test-agent";
363+
364+
await remote("test prompt", { agent: testAgent });
365+
366+
expect(mockFetch).toHaveBeenCalledWith(
367+
new URL("agents", mockEnv.env.apiBase),
368+
expect.objectContaining({
369+
method: "POST",
370+
headers: {
371+
"Content-Type": "application/json",
372+
Authorization: "Bearer test-token",
373+
},
374+
body: expect.stringContaining(`"agent":"${testAgent}"`),
375+
}),
376+
);
377+
378+
expect(mockFetch).toHaveBeenCalledWith(
379+
new URL("agents", mockEnv.env.apiBase),
380+
expect.objectContaining({
381+
body: expect.stringContaining(`"agent":"${testAgent}"`),
357382
}),
358383
);
359384
});
@@ -375,11 +400,31 @@ describe("remote command", () => {
375400
name: expect.stringMatching(/^devbox-\d+$/),
376401
prompt: "test prompt",
377402
idempotencyKey: testIdempotencyKey,
378-
agent: testConfig,
379403
config: testConfig,
380404
});
381405
});
382406

407+
it("should handle proper request body structure with agent field", async () => {
408+
const testAgent = "my-agent";
409+
const testIdempotencyKey = "test-with-config";
410+
411+
await remote("test prompt", {
412+
agent: testAgent,
413+
idempotencyKey: testIdempotencyKey,
414+
});
415+
416+
const fetchCall = mockFetch.mock.calls[0];
417+
const requestBody = JSON.parse(fetchCall[1].body);
418+
419+
expect(requestBody).toEqual({
420+
repoUrl: "https://github.com/user/test-repo.git",
421+
name: expect.stringMatching(/^devbox-\d+$/),
422+
prompt: "test prompt",
423+
idempotencyKey: testIdempotencyKey,
424+
agent: testAgent,
425+
});
426+
});
427+
383428
it("should not include config in request body when config option is not provided", async () => {
384429
await remote("test prompt", {});
385430

extensions/cli/src/configLoader.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export type ConfigSource =
3535
| { type: "saved-uri"; uri: string }
3636
| { type: "user-assistant"; slug: string }
3737
| { type: "default-config-yaml" }
38-
| { type: "default-agent" };
38+
| { type: "default-agent" }
39+
| { type: "no-config" };
3940

4041
/**
4142
* Streamlined configuration loader that implements the specification
@@ -46,12 +47,17 @@ export async function loadConfiguration(
4647
cliConfigPath: string | undefined,
4748
apiClient: DefaultApiInterface,
4849
injectBlocks: PackageIdentifier[],
50+
isHeadless: boolean | undefined,
4951
): Promise<ConfigLoadResult> {
5052
const organizationId = getOrganizationId(authConfig);
5153
const accessToken = getAccessToken(authConfig);
5254

5355
// Step 1: Determine config source using precedence rules
54-
const configSource = determineConfigSource(authConfig, cliConfigPath);
56+
const configSource = determineConfigSource(
57+
authConfig,
58+
cliConfigPath,
59+
isHeadless,
60+
);
5561

5662
// Step 2: Load configuration from the determined source
5763
const config = await loadFromSource(
@@ -82,12 +88,18 @@ export async function loadConfiguration(
8288
function determineConfigSource(
8389
authConfig: AuthConfig,
8490
cliConfigPath: string | undefined,
91+
isHeadless: boolean | undefined,
8592
): ConfigSource {
8693
// Priority 1: CLI --config flag
8794
if (cliConfigPath) {
8895
return { type: "cli-flag", path: cliConfigPath };
8996
}
9097

98+
// In headless, config fallback behavior isn't supported
99+
if (isHeadless) {
100+
return { type: "no-config" };
101+
}
102+
91103
// Priority 2: Saved config URI (only for file-based auth)
92104
if (!isEnvironmentAuthConfig(authConfig) && authConfig !== null) {
93105
const savedUri = getConfigUri(authConfig);
@@ -164,6 +176,12 @@ async function loadFromSource(
164176
injectBlocks,
165177
);
166178

179+
case "no-config":
180+
return {
181+
name: "No Config Specified",
182+
version: "1.0.0",
183+
};
184+
167185
default:
168186
throw new Error(`Unknown config source type: ${(source as any).type}`);
169187
}

extensions/cli/src/onboarding.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export async function initializeWithOnboarding(
147147
configPath,
148148
getApiClient(authConfig?.accessToken),
149149
[],
150+
false,
150151
);
151152
} catch (errorMessage) {
152153
throw new Error(

extensions/cli/src/services/AuthService.refactored.ts

Lines changed: 0 additions & 206 deletions
This file was deleted.

0 commit comments

Comments
 (0)