Download src/hooks/use-chat-input-profile-state.ts from SaylorTwift/openhands: direct link, hf CLI and curl.
- Browser
- Download file 4.45 kB
-
https://huggingface.co/SaylorTwift/openhands/resolve/main/src/hooks/use-chat-input-profile-state.ts
- Command line
-
hf download hf://SaylorTwift/openhands/src/hooks/use-chat-input-profile-state.ts
-
curl -L -o use-chat-input-profile-state.ts https://huggingface.co/SaylorTwift/openhands/resolve/main/src/hooks/use-chat-input-profile-state.ts
4.45 kB
| import { useCallback } from "react"; | |
| import { useIsMutating } from "@tanstack/react-query"; | |
| import type { AgentProfileSummary } from "#/api/agent-profiles-service/agent-profiles-service.api"; | |
| import { getStoredConversationMetadata } from "#/api/conversation-metadata-store"; | |
| import { useNavigation } from "#/context/navigation-context"; | |
| import { useAgentProfiles } from "#/hooks/query/use-agent-profiles"; | |
| import { useActiveConversation } from "#/hooks/query/use-active-conversation"; | |
| import { | |
| CREATE_CONVERSATION_MUTATION_KEY, | |
| useCreateConversation, | |
| type CreateConversationVariables, | |
| } from "#/hooks/mutation/use-create-conversation"; | |
| import { | |
| useActivateAgentProfile, | |
| ACTIVATE_AGENT_PROFILE_MUTATION_KEY, | |
| } from "#/hooks/mutation/use-activate-agent-profile"; | |
| export interface ChatInputProfileState { | |
| profiles: AgentProfileSummary[]; | |
| currentProfileId: string | null; | |
| currentProfileName: string | null; | |
| isInConversation: boolean; | |
| isLoading: boolean; | |
| isSwitching: boolean; | |
| selectProfile: (profile: AgentProfileSummary) => void; | |
| } | |
| export function useChatInputProfileState(): ChatInputProfileState { | |
| const { conversationId, navigate } = useNavigation(); | |
| const { data: conversation, isLoading: isLoadingConversation } = | |
| useActiveConversation(); | |
| const { data: agentProfiles, isLoading: isLoadingProfiles } = | |
| useAgentProfiles(); | |
| const createConversation = useCreateConversation(); | |
| const activateProfile = useActivateAgentProfile(); | |
| const activatingProfiles = useIsMutating({ | |
| mutationKey: ACTIVATE_AGENT_PROFILE_MUTATION_KEY, | |
| }); | |
| const creatingConversations = useIsMutating({ | |
| mutationKey: CREATE_CONVERSATION_MUTATION_KEY, | |
| }); | |
| const isTaskRoute = conversationId?.startsWith("task-") ?? false; | |
| const isSwitching = | |
| isTaskRoute || activatingProfiles > 0 || creatingConversations > 0; | |
| const profiles = agentProfiles?.profiles ?? []; | |
| const isInConversation = Boolean(conversationId); | |
| const currentProfileId = isInConversation | |
| ? (conversation?.launched_agent_profile?.agent_profile_id ?? | |
| agentProfiles?.active_agent_profile_id ?? | |
| null) | |
| : (agentProfiles?.active_agent_profile_id ?? null); | |
| const currentProfileName = | |
| profiles.find((p) => p.id != null && p.id === currentProfileId)?.name ?? | |
| null; | |
| const selectProfile = useCallback( | |
| (profile: AgentProfileSummary) => { | |
| if (isTaskRoute || !profile.id || profile.id === currentProfileId) return; | |
| if (!isInConversation) { | |
| activateProfile.mutate(profile.id); | |
| return; | |
| } | |
| const metadata = conversationId | |
| ? getStoredConversationMetadata(conversationId) | |
| : null; | |
| const variables: CreateConversationVariables = { | |
| agentProfileId: profile.id, | |
| entryPoint: "blank_conversation_profile_picker", | |
| }; | |
| if (conversation?.selected_repository) { | |
| variables.repository = { | |
| name: conversation.selected_repository, | |
| gitProvider: conversation.git_provider ?? "github", | |
| branch: conversation.selected_branch ?? undefined, | |
| }; | |
| } | |
| if (conversation?.selected_workspace) { | |
| variables.workingDir = conversation.selected_workspace; | |
| variables.workspaceMode = metadata?.workspace_mode ?? "local_repo"; | |
| } | |
| if (metadata?.plugins?.length) { | |
| variables.plugins = metadata.plugins; | |
| } | |
| // mutateAsync, not mutate-scoped callbacks: this hook lives inside the | |
| // tools-menu content, which unmounts as soon as a profile is picked, and | |
| // React Query drops mutate-scoped callbacks on unmount — the replacement | |
| // conversation would be created without ever navigating to it. The | |
| // promise (and the navigate closure) survive the unmount. Errors are | |
| // already surfaced by the global mutation toast; swallow the rejection. | |
| createConversation | |
| .mutateAsync(variables) | |
| .then((data) => navigate(`/conversations/${data.conversation_id}`)) | |
| .catch(() => {}); | |
| }, | |
| [ | |
| activateProfile, | |
| conversation, | |
| conversationId, | |
| createConversation, | |
| currentProfileId, | |
| isInConversation, | |
| isTaskRoute, | |
| navigate, | |
| ], | |
| ); | |
| return { | |
| profiles, | |
| currentProfileId, | |
| currentProfileName, | |
| isInConversation, | |
| isLoading: | |
| isLoadingProfiles || | |
| isTaskRoute || | |
| (isInConversation && isLoadingConversation), | |
| isSwitching, | |
| selectProfile, | |
| }; | |
| } | |