Skip to content

Commit

Permalink
vscode setting for platform
Browse files Browse the repository at this point in the history
  • Loading branch information
sestinj committed Jan 24, 2025
1 parent 5e91e46 commit 468acac
Show file tree
Hide file tree
Showing 24 changed files with 225 additions and 134 deletions.
65 changes: 51 additions & 14 deletions core/config/ConfigHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@ import Ollama from "../llm/llms/Ollama.js";
import { GlobalContext } from "../util/GlobalContext.js";
import { getConfigJsonPath, getConfigYamlPath } from "../util/paths.js";

import { ConfigResult, ConfigYaml } from "@continuedev/config-yaml";
import { ConfigResult, ConfigYaml, FullSlug } from "@continuedev/config-yaml";
import * as YAML from "yaml";
import { controlPlaneEnv } from "../control-plane/env.js";
import { usePlatform } from "../control-plane/flags.js";
import { getControlPlaneEnv, useHub } from "../control-plane/env.js";
import { localPathToUri } from "../util/pathToUri.js";
import {
LOCAL_ONBOARDING_CHAT_MODEL,
ONBOARDING_LOCAL_MODEL_TITLE,
} from "./onboarding.js";
import ControlPlaneProfileLoader from "./profile/ControlPlaneProfileLoader.js";
import LocalProfileLoader from "./profile/LocalProfileLoader.js";
import PlatformProfileLoader from "./profile/PlatformProfileLoader.js";
import PlatformProfileLoader from "./profile/PlatformProfileLoader.1.js";
import {
ProfileDescription,
ProfileLifecycleManager,
Expand Down Expand Up @@ -63,7 +62,7 @@ export class ConfigHandler {
controlPlaneClient,
writeLog,
);
this.profiles = [new ProfileLifecycleManager(localProfileLoader)];
this.profiles = [new ProfileLifecycleManager(localProfileLoader, this.ide)];
this.selectedProfileId = localProfileLoader.description.id;

// Always load local profile immediately in case control plane doesn't load
Expand Down Expand Up @@ -107,7 +106,8 @@ export class ConfigHandler {
await this.ide.openFile(localPathToUri(getConfigJsonPath()));
}
} else {
await this.ide.openUrl(`${controlPlaneEnv.APP_URL}${openProfileId}`);
const env = await getControlPlaneEnv(this.ide.getIdeSettings());
await this.ide.openUrl(`${env.APP_URL}${openProfileId}`);
}
}

Expand Down Expand Up @@ -145,7 +145,7 @@ export class ConfigHandler {
...this.profiles.filter(
(profile) => profile.profileDescription.id === "local",
),
new ProfileLifecycleManager(profileLoader),
new ProfileLifecycleManager(profileLoader, this.ide),
];
}),
);
Expand Down Expand Up @@ -177,15 +177,49 @@ export class ConfigHandler {
}

private platformProfilesRefreshInterval: NodeJS.Timeout | undefined;
// We use this to keep track of whether we should reload the assistants
private lastFullSlugsList: FullSlug[] = [];

private fullSlugsListsDiffer(a: FullSlug[], b: FullSlug[]): boolean {
if (a.length !== b.length) {
return true;
}
for (let i = 0; i < a.length; i++) {
if (a[i].ownerSlug !== b[i].ownerSlug) {
return true;
}
if (a[i].packageSlug !== b[i].packageSlug) {
return true;
}
if (a[i].versionSlug !== b[i].versionSlug) {
return true;
}
}
return false;
}

private async fetchControlPlaneProfiles() {
if (usePlatform()) {
if (await useHub(this.ideSettingsPromise)) {
clearInterval(this.platformProfilesRefreshInterval);
await this.loadPlatformProfiles();
this.platformProfilesRefreshInterval = setInterval(
this.loadPlatformProfiles.bind(this),
PlatformProfileLoader.RELOAD_INTERVAL,
);

// Every 5 seconds we ask the platform whether there are any assistant updates in the last 5 seconds
// If so, we do the full (more expensive) reload
this.platformProfilesRefreshInterval = setInterval(async () => {
const newFullSlugsList =
await this.controlPlaneClient.listAssistantFullSlugs();

if (newFullSlugsList) {
const shouldReload = this.fullSlugsListsDiffer(
newFullSlugsList,
this.lastFullSlugsList,
);
if (shouldReload) {
await this.loadPlatformProfiles();
}
this.lastFullSlugsList = newFullSlugsList;
}
}, PlatformProfileLoader.RELOAD_INTERVAL);
} else {
this.controlPlaneClient
.listWorkspaces()
Expand All @@ -203,7 +237,9 @@ export class ConfigHandler {
this.writeLog,
this.reloadConfig.bind(this),
);
this.profiles.push(new ProfileLifecycleManager(profileLoader));
this.profiles.push(
new ProfileLifecycleManager(profileLoader, this.ide),
);
});

this.notifyProfileListeners(
Expand Down Expand Up @@ -258,11 +294,12 @@ export class ConfigHandler {
void this.reloadConfig();
}

updateControlPlaneSessionInfo(
async updateControlPlaneSessionInfo(
sessionInfo: ControlPlaneSessionInfo | undefined,
) {
this.controlPlaneClient = new ControlPlaneClient(
Promise.resolve(sessionInfo),
this.ideSettingsPromise,
);
this.fetchControlPlaneProfiles().catch((e) => {
console.error("Failed to fetch control plane profiles: ", e);
Expand Down
13 changes: 10 additions & 3 deletions core/config/ProfileLifecycleManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import {
BrowserSerializedContinueConfig,
ContinueConfig,
IContextProvider,
IDE,
} from "../index.js";

import { finalToBrowserConfig } from "./load.js";
import { IProfileLoader } from "./profile/IProfileLoader.js";

export interface ProfileDescription {
fullSlug: FullSlug;
profileType: string;
profileType: "control-plane" | "local" | "platform";
title: string;
id: string;
errors: ConfigValidationError[] | undefined;
Expand All @@ -25,7 +26,10 @@ export class ProfileLifecycleManager {
private savedBrowserConfigResult?: ConfigResult<BrowserSerializedContinueConfig>;
private pendingConfigPromise?: Promise<ConfigResult<ContinueConfig>>;

constructor(private readonly profileLoader: IProfileLoader) {}
constructor(
private readonly profileLoader: IProfileLoader,
private readonly ide: IDE,
) {}

get profileDescription(): ProfileDescription {
return this.profileLoader.description;
Expand Down Expand Up @@ -93,7 +97,10 @@ export class ProfileLifecycleManager {
config: undefined,
};
}
const serializedConfig = finalToBrowserConfig(result.config);
const serializedConfig = await finalToBrowserConfig(
result.config,
this.ide,
);
return {
...result,
config: serializedConfig,
Expand Down
11 changes: 6 additions & 5 deletions core/config/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ import {
} from "../util/paths";

import { ConfigResult, ConfigValidationError } from "@continuedev/config-yaml";
import { usePlatform } from "../control-plane/flags";
import {
defaultContextProvidersJetBrains,
defaultContextProvidersVsCode,
Expand All @@ -72,8 +71,9 @@ import {
} from "./default";
import { getSystemPromptDotFile } from "./getSystemPromptDotFile";
// import { isSupportedLanceDbCpuTarget } from "./util";
import { validateConfig } from "./validation.js";
import { useHub } from "../control-plane/env";
import { localPathToUri } from "../util/pathToUri";
import { validateConfig } from "./validation.js";

function resolveSerializedConfig(filepath: string): SerializedContinueConfig {
let content = fs.readFileSync(filepath, "utf8");
Expand Down Expand Up @@ -547,9 +547,10 @@ async function intermediateToFinalConfig(
return { config: continueConfig, errors };
}

function finalToBrowserConfig(
async function finalToBrowserConfig(
final: ContinueConfig,
): BrowserSerializedContinueConfig {
ide: IDE,
): Promise<BrowserSerializedContinueConfig> {
return {
allowAnonymousTelemetry: final.allowAnonymousTelemetry,
models: final.models.map((m) => ({
Expand Down Expand Up @@ -582,7 +583,7 @@ function finalToBrowserConfig(
experimental: final.experimental,
docs: final.docs,
tools: final.tools,
usePlatform: usePlatform(),
usePlatform: await useHub(ide.getIdeSettings()),
};
}

Expand Down
2 changes: 1 addition & 1 deletion core/config/profile/LocalProfileLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default class LocalProfileLoader implements IProfileLoader {
static ID = "local";
description: ProfileDescription = {
id: LocalProfileLoader.ID,
profileType: LocalProfileLoader.ID,
profileType: "local",
fullSlug: {
ownerSlug: "",
packageSlug: "",
Expand Down
32 changes: 1 addition & 31 deletions core/config/profile/PlatformProfileLoader.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { ConfigYaml } from "@continuedev/config-yaml/dist/schemas/index.js";
import * as YAML from "yaml";

import { ControlPlaneClient } from "../../control-plane/client.js";
import { ContinueConfig, IDE, IdeSettings } from "../../index.js";

import { ConfigResult } from "@continuedev/config-yaml";
import { ProfileDescription } from "../ProfileLifecycleManager.js";
import { clientRenderHelper } from "../yaml/clientRender.js";
import doLoadConfig from "./doLoadConfig.js";
import { IProfileLoader } from "./IProfileLoader.js";

Expand All @@ -21,7 +19,7 @@ export interface PlatformConfigMetadata {
}

export default class PlatformProfileLoader implements IProfileLoader {
static RELOAD_INTERVAL = 1000 * 60 * 15; // every 15 minutes
static RELOAD_INTERVAL = 1000 * 5; // 5 seconds

description: ProfileDescription;

Expand All @@ -47,34 +45,6 @@ export default class PlatformProfileLoader implements IProfileLoader {
title: `${ownerSlug}/${packageSlug}@${versionSlug}`,
errors: configResult.errors,
};

setInterval(async () => {
const assistants = await this.controlPlaneClient.listAssistants();
const newConfigResult = assistants.find(
(assistant) =>
assistant.packageSlug === this.packageSlug &&
assistant.ownerSlug === this.ownerSlug,
)?.configResult;
if (!newConfigResult) {
return;
}

let renderedConfig: ConfigYaml | undefined = undefined;
if (newConfigResult.config) {
renderedConfig = await clientRenderHelper(
YAML.stringify(newConfigResult.config),
this.ide,
this.controlPlaneClient,
);
}

this.configResult = {
config: renderedConfig,
errors: newConfigResult.errors,
configLoadInterrupted: false,
};
this.onReload();
}, PlatformProfileLoader.RELOAD_INTERVAL);
}

async doLoadConfig(): Promise<ConfigResult<ContinueConfig>> {
Expand Down
6 changes: 4 additions & 2 deletions core/config/profile/doLoadConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from "../../";
import { ControlPlaneProxyInfo } from "../../control-plane/analytics/IAnalyticsProvider.js";
import { ControlPlaneClient } from "../../control-plane/client.js";
import { controlPlaneEnv } from "../../control-plane/env.js";
import { getControlPlaneEnv } from "../../control-plane/env.js";
import { TeamAnalytics } from "../../control-plane/TeamAnalytics.js";
import ContinueProxy from "../../llm/llms/stubs/ContinueProxy";
import { getConfigYamlPath } from "../../util/paths";
Expand Down Expand Up @@ -99,9 +99,11 @@ export default async function doLoadConfig(
const controlPlane = (newConfig as any).controlPlane;
const useOnPremProxy =
controlPlane?.useContinueForTeamsProxy === false && controlPlane?.proxyUrl;

const env = await getControlPlaneEnv(ideSettingsPromise);
let controlPlaneProxyUrl: string = useOnPremProxy
? controlPlane?.proxyUrl
: controlPlaneEnv.DEFAULT_CONTROL_PLANE_PROXY_URL;
: env.DEFAULT_CONTROL_PLANE_PROXY_URL;

if (!controlPlaneProxyUrl.endsWith("/")) {
controlPlaneProxyUrl += "/";
Expand Down
11 changes: 5 additions & 6 deletions core/context/providers/ContinueProxyContextProvider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { controlPlaneEnv } from "../../control-plane/env.js";
import { getControlPlaneEnv } from "../../control-plane/env.js";
import {
ContextItem,
ContextProviderDescription,
Expand Down Expand Up @@ -35,11 +35,9 @@ class ContinueProxyContextProvider extends BaseContextProvider {
async loadSubmenuItems(
args: LoadSubmenuItemsArgs,
): Promise<ContextSubmenuItem[]> {
const env = await getControlPlaneEnv(args.ide.getIdeSettings());
const response = await args.fetch(
new URL(
`/proxy/context/${this.options.id}/list`,
controlPlaneEnv.CONTROL_PLANE_URL,
),
new URL(`/proxy/context/${this.options.id}/list`, env.CONTROL_PLANE_URL),
{
method: "GET",
headers: {
Expand All @@ -56,10 +54,11 @@ class ContinueProxyContextProvider extends BaseContextProvider {
query: string,
extras: ContextProviderExtras,
): Promise<ContextItem[]> {
const env = await getControlPlaneEnv(extras.ide.getIdeSettings());
const response = await extras.fetch(
new URL(
`/proxy/context/${this.options.id}/retrieve`,
controlPlaneEnv.CONTROL_PLANE_URL,
env.CONTROL_PLANE_URL,
),
{
method: "POST",
Expand Down
2 changes: 1 addition & 1 deletion core/context/providers/_context-providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async function getContextProviderExtras(
ide,
ideSettingsPromise,
async (text) => {},
new ControlPlaneClient(Promise.resolve(undefined)),
new ControlPlaneClient(Promise.resolve(undefined), ideSettingsPromise),
);
const { config } = await configHandler.loadConfig();
if (!config) {
Expand Down
13 changes: 8 additions & 5 deletions core/control-plane/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { v4 as uuidv4 } from "uuid";
import { IdeSettings } from "../..";
import { getControlPlaneEnv } from "../env";

import { controlPlaneEnv } from "../env";

export async function getAuthUrlForTokenPage(): Promise<string> {
export async function getAuthUrlForTokenPage(
ideSettingsPromise: Promise<IdeSettings>,
): Promise<string> {
const env = await getControlPlaneEnv(ideSettingsPromise);
const url = new URL("https://api.workos.com/user_management/authorize");
const params = {
response_type: "code",
client_id: controlPlaneEnv.WORKOS_CLIENT_ID,
redirect_uri: `${controlPlaneEnv.APP_URL}tokens/callback`,
client_id: env.WORKOS_CLIENT_ID,
redirect_uri: `${env.APP_URL}tokens/callback`,
// redirect_uri: "http://localhost:3000/tokens/callback",
state: uuidv4(),
provider: "authkit",
Expand Down
Loading

0 comments on commit 468acac

Please sign in to comment.