Skip to content

Commit

Permalink
Merge pull request #3551 from continuedev/pe/fix-lancedb-unsupported-…
Browse files Browse the repository at this point in the history
…cpus

fix: disable indexing for unsupported CPUs
  • Loading branch information
sestinj authored Jan 11, 2025
2 parents 53fb631 + f271024 commit 95a2329
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 20 deletions.
11 changes: 9 additions & 2 deletions core/config/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import CustomLLMClass from "../llm/llms/CustomLLM";
import FreeTrial from "../llm/llms/FreeTrial";
import { LLMReranker } from "../llm/llms/llm";
import TransformersJsEmbeddingsProvider from "../llm/llms/TransformersJsEmbeddingsProvider";
import { slashCommandFromPromptFileV1 } from "../promptFiles/v1/slashCommandFromPromptFile";
import { getAllPromptFiles } from "../promptFiles/v2/getPromptFiles";
import { allTools } from "../tools";
import { copyOf } from "../util";
import { GlobalContext } from "../util/GlobalContext";
Expand All @@ -61,15 +63,14 @@ import {
getEsbuildBinaryPath,
} from "../util/paths";

import { slashCommandFromPromptFileV1 } from "../promptFiles/v1/slashCommandFromPromptFile";
import { getAllPromptFiles } from "../promptFiles/v2/getPromptFiles";
import {
defaultContextProvidersJetBrains,
defaultContextProvidersVsCode,
defaultSlashCommandsJetBrains,
defaultSlashCommandsVscode,
} from "./default";
import { getSystemPromptDotFile } from "./getSystemPromptDotFile";
import { isSupportedLanceDbCpuTarget } from "./util";
import { ConfigValidationError, validateConfig } from "./validation.js";

export interface ConfigResult<T> {
Expand Down Expand Up @@ -112,6 +113,7 @@ function loadSerializedConfig(
ideSettings: IdeSettings,
ideType: IdeType,
overrideConfigJson: SerializedContinueConfig | undefined,
ide: IDE,
): ConfigResult<SerializedContinueConfig> {
const configPath = getConfigJsonPath(ideType);
let config: SerializedContinueConfig = overrideConfigJson!;
Expand Down Expand Up @@ -174,6 +176,10 @@ function loadSerializedConfig(
? [...defaultSlashCommandsVscode]
: [...defaultSlashCommandsJetBrains];

if (!isSupportedLanceDbCpuTarget(ide)) {
config.disableIndexing = true;
}

return { config, errors, configLoadInterrupted: false };
}

Expand Down Expand Up @@ -767,6 +773,7 @@ async function loadFullConfigNode(
ideSettings,
ideType,
overrideConfigJson,
ide,
);

if (!serialized || configLoadInterrupted) {
Expand Down
86 changes: 86 additions & 0 deletions core/config/util.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { execSync } from "child_process";
import os from "os";

import {
ContextProviderWithParams,
ContinueConfig,
IDE,
ILLM,
ModelDescription,
ModelRoles,
} from "../";
import { GlobalContext } from "../util/GlobalContext";
import { editConfigJson } from "../util/paths";

function stringify(obj: any, indentation?: number): string {
Expand Down Expand Up @@ -96,3 +101,84 @@ export function getModelByRole<T extends keyof ModelRoles>(

return matchingModel;
}

/**
* This check is to determine if the user is on an unsupported CPU
* target for our Lance DB binaries.
*
* See here for details: https://github.com/continuedev/continue/issues/940
*/
export function isSupportedLanceDbCpuTarget(ide: IDE) {
const CPU_FEATURES_TO_CHECK = ["avx2", "fma"] as const;

const globalContext = new GlobalContext();
const globalContextVal = globalContext.get("isSupportedLanceDbCpuTarget");

// If we've already checked the CPU target, return the cached value
if (globalContextVal !== undefined) {
return globalContextVal;
}

const arch = os.arch();
const platform = os.platform();

// This check only applies to x64
//https://github.com/lancedb/lance/issues/2195#issuecomment-2057841311
if (arch !== "x64") {
globalContext.update("isSupportedLanceDbCpuTarget", true);
return true;
}

try {
const cpuFlags = (() => {
switch (platform) {
case "darwin":
return execSync("sysctl -n machdep.cpu.features")
.toString()
.toLowerCase();
case "linux":
return execSync("cat /proc/cpuinfo").toString().toLowerCase();
case "win32":
return execSync("wmic cpu get caption /format:list")
.toString()
.toLowerCase();
default:
return "";
}
})();

const isSupportedLanceDbCpuTarget = cpuFlags
? CPU_FEATURES_TO_CHECK.every((feature) => cpuFlags.includes(feature))
: true;

// If it's not a supported CPU target, and it's the first time we are checking,
// show a toast to inform the user that we are going to disable indexing.
if (!isSupportedLanceDbCpuTarget) {
// We offload our async toast to `showUnsupportedCpuToast` to prevent making
// our config loading async upstream of `isSupportedLanceDbCpuTarget`
void showUnsupportedCpuToast(ide);
}

globalContext.update(
"isSupportedLanceDbCpuTarget",
isSupportedLanceDbCpuTarget,
);

return isSupportedLanceDbCpuTarget;
} catch (error) {
// If we can't determine CPU features, default to true
return true;
}
}

async function showUnsupportedCpuToast(ide: IDE) {
const shouldOpenLink = await ide.showToast(
"warning",
"Codebase indexing is disabled due to CPU incompatibility",
"Learn more",
);

if (shouldOpenLink) {
void ide.openUrl("https://github.com/continuedev/continue/pull/3551");
}
}
1 change: 1 addition & 0 deletions core/util/GlobalContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type GlobalContextType = {
hasDismissedConfigTsNoticeJetBrains: boolean;
hasAlreadyCreatedAPromptFile: boolean;
showConfigUpdateToast: boolean;
isSupportedLanceDbCpuTarget: boolean;
};

/**
Expand Down
19 changes: 11 additions & 8 deletions gui/src/components/indexing/DocsIndexingStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,11 @@ function DocsIndexingStatus({ docConfig }: IndexingStatusViewerProps) {
if (!status) {
return 0;
}
return Math.min(100, Math.max(0, status.progress * 100));
return Math.min(100, Math.max(0, status.progress * 100)).toFixed(0);
}, [status?.progress]);

const Icon = STATUS_TO_ICON[status?.status];
const showProgressPercentage = progressPercentage !== "100";

if (hasDeleted) return null;

Expand Down Expand Up @@ -116,20 +117,22 @@ function DocsIndexingStatus({ docConfig }: IndexingStatusViewerProps) {
<div className="text-xs text-stone-500">Pending...</div>
) : (
<div className="flex flex-row items-center gap-1 text-stone-500">
<span className="text-xs">{progressPercentage.toFixed(0)}%</span>
{showProgressPercentage && (
<span className="text-xs">{progressPercentage}%</span>
)}
{status?.status !== "indexing" ? (
<TrashIcon
className="h-4 w-4 cursor-pointer text-stone-500 hover:brightness-125"
onClick={onDelete}
/>
) : null}
{Icon ? (
<Icon
className={`inline-block h-4 w-4 text-stone-500 ${
status?.status === "indexing" ? "animate-spin-slow" : ""
}`}
></Icon>
) : null}
{status?.status !== "indexing" ? (
<TrashIcon
className="h-4 w-4 cursor-pointer text-stone-500"
onClick={onDelete}
/>
) : null}
</div>
)}
</div>
Expand Down
4 changes: 2 additions & 2 deletions gui/src/components/indexing/DocsIndexingStatuses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ function DocsIndexingStatuses() {
return (
<div className="flex flex-col gap-1">
<div className="flex flex-row items-center justify-between">
<h3 className="mb-1 mt-0 text-xl">@docs indexes</h3>
<h3 className="mb-0 mt-0 text-xl">@docs indexes</h3>
{configDocs.length ? (
<SecondaryButton
className="flex h-7 flex-col items-center justify-center"
className="!my-0 flex h-7 flex-col items-center justify-center"
onClick={() => {
dispatch(setShowDialog(true));
dispatch(setDialogMessage(<AddDocsDialog />));
Expand Down
2 changes: 1 addition & 1 deletion gui/src/pages/More/IndexingProgress/IndexingProgress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function IndexingProgress() {
}

return (
<div className="mt-6 flex flex-col">
<div className="mt-4 flex flex-col">
<div className="mb-0 flex justify-between text-sm">
<IndexingProgressTitleText update={update} />
{update.status !== "loading" && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,15 @@ const STATUS_TO_ICON: Record<IndexingProgressUpdate["status"], any> = {
};

function IndexingProgressIndicator({ update }: IndexingProgressIndicatorProps) {
const progressPercentage = getProgressPercentage(update.progress);
const progressPercentage = getProgressPercentage(update.progress).toFixed(0);
const Icon = STATUS_TO_ICON[update.status];
const animateIcon = update.status === "indexing";
const showProgress = update.status !== "disabled";
const showProgress =
update.status !== "disabled" && progressPercentage !== "100";

return (
<div className="flex items-center justify-between gap-1 text-stone-500">
{showProgress && (
<span className="text-xs">{progressPercentage.toFixed(0)}%</span>
)}
{showProgress && <span className="text-xs">{progressPercentage}%</span>}

{Icon && (
<div className="flex items-center">
Expand Down
14 changes: 12 additions & 2 deletions gui/src/pages/More/More.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ import MoreHelpRow from "./MoreHelpRow";
import IndexingProgress from "./IndexingProgress";
import DocsIndexingStatuses from "../../components/indexing/DocsIndexingStatuses";
import PageHeader from "../../components/PageHeader";
import { useAppDispatch } from "../../redux/hooks";
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
import { saveCurrentSession } from "../../redux/thunks/session";

function MorePage() {
useNavigationListener();
const dispatch = useAppDispatch();
const navigate = useNavigate();
const ideMessenger = useContext(IdeMessengerContext);
const disableIndexing = useAppSelector(
(state) => state.config.config.disableIndexing,
);

return (
<div className="overflow-y-scroll">
Expand All @@ -34,8 +37,15 @@ function MorePage() {
Local embeddings of your codebase
</span>
</div>
<IndexingProgress />
{disableIndexing ? (
<div className="pb-2 pt-5 text-center font-semibold">
Indexing is disabled
</div>
) : (
<IndexingProgress />
)}
</div>

<div className="flex flex-col py-5">
<DocsIndexingStatuses />
</div>
Expand Down

0 comments on commit 95a2329

Please sign in to comment.