Replace USE_V1_CONVERSATION_API feature flag with user setting (#11893)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
Tim O'Farrell 2025-12-03 09:02:40 -07:00 committed by GitHub
parent 816d8acf1f
commit 8f91db8ec4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 21 additions and 12 deletions

View File

@ -4,8 +4,8 @@ import V1ConversationService from "#/api/conversation-service/v1-conversation-se
import { SuggestedTask } from "#/utils/types";
import { Provider } from "#/types/settings";
import { CreateMicroagent, Conversation } from "#/api/open-hands.types";
import { USE_V1_CONVERSATION_API } from "#/utils/feature-flags";
import { useTracking } from "#/hooks/use-tracking";
import { useSettings } from "#/hooks/query/use-settings";
interface CreateConversationVariables {
query?: string;
@ -34,6 +34,7 @@ interface CreateConversationResponse extends Partial<Conversation> {
export const useCreateConversation = () => {
const queryClient = useQueryClient();
const { trackConversationCreated } = useTracking();
const { data: settings } = useSettings();
return useMutation({
mutationKey: ["create-conversation"],
@ -50,7 +51,7 @@ export const useCreateConversation = () => {
agentType,
} = variables;
const useV1 = USE_V1_CONVERSATION_API() && !createMicroagent;
const useV1 = !!settings?.V1_ENABLED && !createMicroagent;
if (useV1) {
// Use V1 API - creates a conversation start task

View File

@ -35,6 +35,7 @@ const saveSettingsMutationFn = async (settings: Partial<PostSettings>) => {
settings.GIT_USER_NAME?.trim() || DEFAULT_SETTINGS.GIT_USER_NAME,
git_user_email:
settings.GIT_USER_EMAIL?.trim() || DEFAULT_SETTINGS.GIT_USER_EMAIL,
v1_enabled: settings.V1_ENABLED,
};
await SettingsService.saveSettings(apiSettings);

View File

@ -36,6 +36,7 @@ const getSettingsQueryFn = async (): Promise<Settings> => {
GIT_USER_EMAIL:
apiSettings.git_user_email || DEFAULT_SETTINGS.GIT_USER_EMAIL,
IS_NEW_USER: false,
V1_ENABLED: apiSettings.v1_enabled ?? DEFAULT_SETTINGS.V1_ENABLED,
};
};

View File

@ -1,6 +1,6 @@
import { useQuery } from "@tanstack/react-query";
import V1ConversationService from "#/api/conversation-service/v1-conversation-service.api";
import { USE_V1_CONVERSATION_API } from "#/utils/feature-flags";
import { useSettings } from "#/hooks/query/use-settings";
/**
* Hook to fetch in-progress V1 conversation start tasks
@ -13,13 +13,17 @@ import { USE_V1_CONVERSATION_API } from "#/utils/feature-flags";
* @param limit Maximum number of tasks to return (max 100)
* @returns Query result with array of in-progress start tasks
*/
export const useStartTasks = (limit = 10) =>
useQuery({
export const useStartTasks = (limit = 10) => {
const { data: settings } = useSettings();
const isV1Enabled = settings?.V1_ENABLED;
return useQuery({
queryKey: ["start-tasks", "search", limit],
queryFn: () => V1ConversationService.searchStartTasks(limit),
enabled: USE_V1_CONVERSATION_API(),
enabled: isV1Enabled,
select: (tasks) =>
tasks.filter(
(task) => task.status !== "READY" && task.status !== "ERROR",
),
});
};

View File

@ -28,7 +28,6 @@ import { KeyStatusIcon } from "#/components/features/settings/key-status-icon";
import { DEFAULT_SETTINGS } from "#/services/settings";
import { getProviderId } from "#/utils/map-provider";
import { DEFAULT_OPENHANDS_MODEL } from "#/utils/verified-models";
import { USE_V1_CONVERSATION_API } from "#/utils/feature-flags";
interface OpenHandsApiKeyHelpProps {
testId: string;
@ -119,8 +118,8 @@ function LlmSettingsScreen() {
const isSaasMode = config?.APP_MODE === "saas";
const shouldUseOpenHandsKey = isOpenHandsProvider && isSaasMode;
// Determine if we should hide the agent dropdown when V1 conversation API feature flag is enabled
const isV1Enabled = USE_V1_CONVERSATION_API();
// Determine if we should hide the agent dropdown when V1 conversation API is enabled
const isV1Enabled = settings?.V1_ENABLED;
React.useEffect(() => {
const determineWhetherToToggleAdvancedSettings = () => {

View File

@ -31,6 +31,7 @@ export const DEFAULT_SETTINGS: Settings = {
},
GIT_USER_NAME: "openhands",
GIT_USER_EMAIL: "openhands@all-hands.dev",
V1_ENABLED: false,
};
/**

View File

@ -35,6 +35,7 @@ export type ApiSettings = {
email_verified?: boolean;
git_user_name?: string;
git_user_email?: string;
v1_enabled?: boolean;
};
export type PostApiSettings = ApiSettings & {

View File

@ -63,6 +63,7 @@ export type Settings = {
EMAIL_VERIFIED?: boolean;
GIT_USER_NAME?: string;
GIT_USER_EMAIL?: string;
V1_ENABLED?: boolean;
};
export type PostSettings = Settings & {

View File

@ -17,6 +17,4 @@ export const HIDE_LLM_SETTINGS = () => loadFeatureFlag("HIDE_LLM_SETTINGS");
export const VSCODE_IN_NEW_TAB = () => loadFeatureFlag("VSCODE_IN_NEW_TAB");
export const ENABLE_TRAJECTORY_REPLAY = () =>
loadFeatureFlag("TRAJECTORY_REPLAY");
export const USE_V1_CONVERSATION_API = () =>
loadFeatureFlag("USE_V1_CONVERSATION_API");
export const USE_PLANNING_AGENT = () => loadFeatureFlag("USE_PLANNING_AGENT");

View File

@ -1,5 +1,7 @@
from __future__ import annotations
import os
from pydantic import (
BaseModel,
ConfigDict,
@ -48,7 +50,7 @@ class Settings(BaseModel):
email_verified: bool | None = None
git_user_name: str | None = None
git_user_email: str | None = None
v1_enabled: bool | None = None
v1_enabled: bool | None = Field(default=bool(os.getenv('V1_ENABLED') == '1'))
model_config = ConfigDict(
validate_assignment=True,