Skip to content

Commit 62e9f35

Browse files
authored
Merge pull request #3525 from continuedev/nate/config-result
Use ConfigResult everywhere
2 parents af396fa + 9551170 commit 62e9f35

26 files changed

+199
-120
lines changed

binary/test/binary.test.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { SerializedContinueConfig } from "core";
22
// import Mock from "core/llm/llms/Mock.js";
33
import { FromIdeProtocol, ToIdeProtocol } from "core/protocol/index.js";
4-
import FileSystemIde from "core/util/filesystem";
54
import { IMessenger } from "core/protocol/messenger";
5+
import FileSystemIde from "core/util/filesystem";
66
import fs from "fs";
77
import {
88
ChildProcessWithoutNullStreams,
@@ -186,10 +186,11 @@ describe("Test Suite", () => {
186186
});
187187

188188
it("should return valid config object", async () => {
189-
const { config } = await messenger.request(
189+
const { result } = await messenger.request(
190190
"config/getSerializedProfileInfo",
191191
undefined,
192192
);
193+
const { config } = result;
193194
expect(config).toHaveProperty("models");
194195
expect(config).toHaveProperty("embeddingsProvider");
195196
expect(config).toHaveProperty("contextProviders");
@@ -229,18 +230,17 @@ describe("Test Suite", () => {
229230
await messenger.request("config/addModel", {
230231
model,
231232
});
232-
const { config } = await messenger.request(
233-
"config/getSerializedProfileInfo",
234-
undefined,
235-
);
236-
expect(config.models.some((m) => m.title === model.title)).toBe(true);
233+
const {
234+
result: { config },
235+
} = await messenger.request("config/getSerializedProfileInfo", undefined);
236+
237+
expect(config!.models.some((m) => m.title === model.title)).toBe(true);
237238

238239
await messenger.request("config/deleteModel", { title: model.title });
239-
const { config: configAfterDelete } = await messenger.request(
240-
"config/getSerializedProfileInfo",
241-
undefined,
242-
);
243-
expect(configAfterDelete.models.some((m) => m.title === model.title)).toBe(
240+
const {
241+
result: { config: configAfterDelete },
242+
} = await messenger.request("config/getSerializedProfileInfo", undefined);
243+
expect(configAfterDelete!.models.some((m) => m.title === model.title)).toBe(
244244
false,
245245
);
246246
});

core/autocomplete/CompletionProvider.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ import { TRIAL_FIM_MODEL } from "../config/onboarding.js";
33
import { IDE, ILLM } from "../index.js";
44
import OpenAI from "../llm/llms/OpenAI.js";
55
import { DEFAULT_AUTOCOMPLETE_OPTS } from "../util/parameters.js";
6-
import { PosthogFeatureFlag, Telemetry } from "../util/posthog.js";
76

87
import { shouldCompleteMultiline } from "./classification/shouldCompleteMultiline.js";
98
import { ContextRetrievalService } from "./context/ContextRetrievalService.js";
10-
// @prettier-ignore
119

1210
import { BracketMatchingService } from "./filtering/BracketMatchingService.js";
1311
import { CompletionStreamer } from "./generation/CompletionStreamer.js";
@@ -123,10 +121,10 @@ export class CompletionProvider {
123121
}
124122

125123
private async _getAutocompleteOptions() {
126-
const config = await this.configHandler.loadConfig();
124+
const { config } = await this.configHandler.loadConfig();
127125
const options = {
128126
...DEFAULT_AUTOCOMPLETE_OPTS,
129-
...config.tabAutocompleteOptions,
127+
...config?.tabAutocompleteOptions,
130128
};
131129
return options;
132130
}

core/config/ConfigHandler.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ describe.skip("Test the ConfigHandler and E2E config loading", () => {
1818
});
1919

2020
test("should load the default config successfully", async () => {
21-
const config = await testConfigHandler.loadConfig();
22-
expect(config.models.length).toBe(defaultConfig.models.length);
21+
const result = await testConfigHandler.loadConfig();
22+
expect(result.config!.models.length).toBe(defaultConfig.models.length);
2323
});
2424

2525
test.skip("should add a system message from config.ts", async () => {

core/config/ConfigHandler.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ export class ConfigHandler {
6060

6161
// Always load local profile immediately in case control plane doesn't load
6262
try {
63-
this.loadConfig();
63+
void this.loadConfig();
6464
} catch (e) {
6565
console.error("Failed to load config: ", e);
6666
}
6767

6868
// Load control plane profiles
69-
this.fetchControlPlaneProfiles();
69+
void this.fetchControlPlaneProfiles();
7070
}
7171

7272
// This will be the local profile
@@ -146,12 +146,8 @@ export class ConfigHandler {
146146

147147
async setSelectedProfile(profileId: string) {
148148
this.selectedProfileId = profileId;
149-
const newConfig = await this.loadConfig();
150-
this.notifyConfigListeners({
151-
config: newConfig,
152-
errors: undefined,
153-
configLoadInterrupted: false,
154-
});
149+
const result = await this.loadConfig();
150+
this.notifyConfigListeners(result);
155151
const selectedProfiles =
156152
this.globalContext.get("lastSelectedProfileForWorkspace") ?? {};
157153
selectedProfiles[await this.getWorkspaceId()] = profileId;
@@ -170,7 +166,7 @@ export class ConfigHandler {
170166
// Automatically refresh config when Continue-related IDE (e.g. VS Code) settings are changed
171167
updateIdeSettings(ideSettings: IdeSettings) {
172168
this.ideSettingsPromise = Promise.resolve(ideSettings);
173-
this.reloadConfig();
169+
void this.reloadConfig();
174170
}
175171

176172
updateControlPlaneSessionInfo(
@@ -236,24 +232,24 @@ export class ConfigHandler {
236232
return this.profiles.map((p) => p.profileDescription);
237233
}
238234

239-
async loadConfig(): Promise<ContinueConfig> {
240-
return (
241-
await this.currentProfile.loadConfig(this.additionalContextProviders)
242-
).config!; // <-- TODO
235+
async loadConfig(): Promise<ConfigResult<ContinueConfig>> {
236+
return await this.currentProfile.loadConfig(
237+
this.additionalContextProviders,
238+
);
243239
}
244240

245241
async llmFromTitle(title?: string): Promise<ILLM> {
246-
const config = await this.loadConfig();
247-
const model = config.models.find((m) => m.title === title);
242+
const { config } = await this.loadConfig();
243+
const model = config?.models.find((m) => m.title === title);
248244
if (!model) {
249245
if (title === ONBOARDING_LOCAL_MODEL_TITLE) {
250246
// Special case, make calls to Ollama before we have it in the config
251247
const ollama = new Ollama({
252248
model: LOCAL_ONBOARDING_CHAT_MODEL,
253249
});
254250
return ollama;
255-
} else if (config.models.length > 0) {
256-
return config.models[0];
251+
} else if (config?.models?.length) {
252+
return config?.models[0];
257253
}
258254

259255
throw new Error("No model found");
@@ -264,6 +260,6 @@ export class ConfigHandler {
264260

265261
registerCustomContextProvider(contextProvider: IContextProvider) {
266262
this.additionalContextProviders.push(contextProvider);
267-
this.reloadConfig();
263+
void this.reloadConfig();
268264
}
269265
}

core/config/ProfileLifecycleManager.ts

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export interface ProfileDescription {
1313
}
1414

1515
export class ProfileLifecycleManager {
16-
private savedConfig: ConfigResult<ContinueConfig> | undefined;
17-
private savedBrowserConfig?: BrowserSerializedContinueConfig;
16+
private savedConfigResult: ConfigResult<ContinueConfig> | undefined;
17+
private savedBrowserConfigResult?: ConfigResult<BrowserSerializedContinueConfig>;
1818
private pendingConfigPromise?: Promise<ConfigResult<ContinueConfig>>;
1919

2020
constructor(private readonly profileLoader: IProfileLoader) {}
@@ -35,15 +35,15 @@ export class ProfileLifecycleManager {
3535
}
3636

3737
clearConfig() {
38-
this.savedConfig = undefined;
39-
this.savedBrowserConfig = undefined;
38+
this.savedConfigResult = undefined;
39+
this.savedBrowserConfigResult = undefined;
4040
this.pendingConfigPromise = undefined;
4141
}
4242

4343
// Clear saved config and reload
4444
async reloadConfig(): Promise<ConfigResult<ContinueConfig>> {
45-
this.savedConfig = undefined;
46-
this.savedBrowserConfig = undefined;
45+
this.savedConfigResult = undefined;
46+
this.savedBrowserConfigResult = undefined;
4747
this.pendingConfigPromise = undefined;
4848

4949
return this.loadConfig([], true);
@@ -55,8 +55,8 @@ export class ProfileLifecycleManager {
5555
): Promise<ConfigResult<ContinueConfig>> {
5656
// If we already have a config, return it
5757
if (!forceReload) {
58-
if (this.savedConfig) {
59-
return this.savedConfig;
58+
if (this.savedConfigResult) {
59+
return this.savedConfigResult;
6060
} else if (this.pendingConfigPromise) {
6161
return this.pendingConfigPromise;
6262
}
@@ -72,7 +72,7 @@ export class ProfileLifecycleManager {
7272
result.config.contextProviders ?? []
7373
).concat(additionalContextProviders);
7474

75-
this.savedConfig = result;
75+
this.savedConfigResult = result;
7676
resolve(result);
7777
} else if (result.errors) {
7878
reject(
@@ -82,28 +82,29 @@ export class ProfileLifecycleManager {
8282
});
8383

8484
// Wait for the config promise to resolve
85-
this.savedConfig = await this.pendingConfigPromise;
85+
this.savedConfigResult = await this.pendingConfigPromise;
8686
this.pendingConfigPromise = undefined;
87-
return this.savedConfig;
87+
return this.savedConfigResult;
8888
}
8989

9090
async getSerializedConfig(
9191
additionalContextProviders: IContextProvider[],
9292
): Promise<ConfigResult<BrowserSerializedContinueConfig>> {
93-
if (!this.savedBrowserConfig) {
93+
if (this.savedBrowserConfigResult) {
94+
return this.savedBrowserConfigResult;
95+
} else {
9496
const result = await this.loadConfig(additionalContextProviders);
9597
if (!result.config) {
9698
return {
9799
...result,
98100
config: undefined,
99101
};
100102
}
101-
this.savedBrowserConfig = finalToBrowserConfig(result.config);
103+
const serializedConfig = finalToBrowserConfig(result.config);
104+
return {
105+
...result,
106+
config: serializedConfig,
107+
};
102108
}
103-
return {
104-
config: this.savedBrowserConfig,
105-
errors: [],
106-
configLoadInterrupted: false,
107-
};
108109
}
109110
}

core/context/mcp/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
77
import { ContinueConfig, MCPOptions, SlashCommand, Tool } from "../..";
88
import { constructMcpSlashCommand } from "../../commands/slash/mcp";
99
import { ConfigValidationError } from "../../config/validation";
10+
import { encodeMCPToolUri } from "../../tools/callTool";
1011
import MCPContextProvider from "../providers/MCPContextProvider";
1112

1213
export class MCPManagerSingleton {
@@ -132,7 +133,7 @@ class MCPConnection {
132133
if (!error.message.startsWith("StdioClientTransport already started")) {
133134
return {
134135
fatal: false,
135-
message: `Failed to connect to MCP ${mcpId}: ${error.message}`,
136+
message: `Failed to connect to MCP: ${error.message}`,
136137
};
137138
}
138139
}
@@ -172,7 +173,7 @@ class MCPConnection {
172173
readonly: false,
173174
type: "function",
174175
wouldLikeTo: `use the ${tool.name} tool`,
175-
uri: `mcp://${tool.name}`,
176+
uri: encodeMCPToolUri(mcpId, tool.name),
176177
}));
177178

178179
config.tools = [...config.tools, ...continueTools];

core/context/providers/_context-providers.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import fetch from "node-fetch";
22

3+
import { contextProviderClassFromName } from ".";
34
import {
45
ContextProviderExtras,
56
ContextProviderWithParams,
67
IContextProvider,
78
} from "../..";
89
import { ConfigHandler } from "../../config/ConfigHandler";
9-
import { contextProviderClassFromName } from ".";
1010
import { ControlPlaneClient } from "../../control-plane/client";
11-
import FileSystemIde from "../../util/filesystem";
1211
import { TEST_DIR } from "../../test/testDir";
12+
import FileSystemIde from "../../util/filesystem";
1313

1414
const CONTEXT_PROVIDERS_TO_TEST: ContextProviderWithParams[] = [
1515
{ name: "diff", params: {} },
@@ -33,7 +33,10 @@ async function getContextProviderExtras(
3333
async (text) => {},
3434
new ControlPlaneClient(Promise.resolve(undefined)),
3535
);
36-
const config = await configHandler.loadConfig();
36+
const { config } = await configHandler.loadConfig();
37+
if (!config) {
38+
throw new Error("Config not found");
39+
}
3740

3841
return {
3942
fullInput,

0 commit comments

Comments
 (0)