Files
microsoft--magentic-ui/frontend/src/api/onboarding.ts
T
wehub-resource-sync 25576b0be6
Checks (magui2.0) / python-lint (push) Failing after 1s
Checks (magui2.0) / python-test (push) Failing after 0s
Checks (magui2.0) / frontend-lint (push) Failing after 0s
CodeQL Advanced / Analyze (actions) (push) Failing after 1s
Checks (magui2.0) / python-format (push) Failing after 1s
CodeQL Advanced / Analyze (python) (push) Failing after 0s
Checks (magui2.0) / python-pyright (push) Failing after 1s
Checks (magui2.0) / frontend-format (push) Failing after 1s
Checks (magui2.0) / frontend-typecheck (push) Failing after 0s
Checks (magui2.0) / frontend-test (push) Failing after 2s
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:24:32 +08:00

175 lines
5.2 KiB
TypeScript

/**
* Onboarding API
*
* Client functions for the /api/onboarding endpoints.
*/
import { useQuery, type QueryClient } from '@tanstack/react-query'
import { apiClient } from './client'
// =============================================================================
// Constants
// =============================================================================
/**
* Sentinel value the backend returns instead of real API keys.
* When sent back to the backend, it means "keep the existing DB value".
*/
export const API_KEY_MASKED = '__MASKED__'
/**
* Deployment mode controlling which agents are active.
* Mirrors `AgentMode` in `magentic_ui_config.py`.
*/
export type AgentMode = 'all' | 'omniagent_only' | 'websurfer_only'
// =============================================================================
// Types (mirror backend Pydantic models)
// =============================================================================
export interface ModelInfoConfig {
vision: boolean
function_calling: boolean
json_output: boolean
family: string
structured_output: boolean
multiple_system_messages: boolean
}
export interface ModelClientConfig {
provider: string
config: {
model: string
api_key: string
base_url: string
max_retries: number
model_info: ModelInfoConfig
}
}
export interface OnboardingStatus {
onboarding_completed: boolean
}
export interface ModelEndpointsResponse {
orchestrator: ModelClientConfig | null
web_surfer: ModelClientConfig | null
agent_mode: AgentMode
}
export interface ModelEndpointVerification {
success: boolean
error?: string
}
export interface ModelVerifyResponse {
/** Present when the verify request included `orchestrator`. */
orchestrator?: ModelEndpointVerification
/** Present when the verify request included `web_surfer`. */
web_surfer?: ModelEndpointVerification
}
export interface ModelEndpointInput {
base_url: string
model: string
api_key: string
}
export interface VerifyEndpointsPayload {
/** Required when `agent_mode` includes the orchestrator. */
orchestrator?: ModelEndpointInput
/** Required when `agent_mode` includes the web surfer. */
web_surfer?: ModelEndpointInput
/** Defaults to 'all' on the backend. */
agent_mode?: AgentMode
}
// =============================================================================
// API Functions
// =============================================================================
/**
* Check if onboarding is completed.
* Lightweight — reads only the Settings.onboarding_completed column.
*/
export function getOnboardingStatus(): Promise<OnboardingStatus> {
return apiClient.get<OnboardingStatus>('/onboarding/status')
}
/**
* Get saved model endpoints (masked api_keys).
* Used by settings page.
*/
export function getOnboardingEndpoints(): Promise<ModelEndpointsResponse> {
return apiClient.get<ModelEndpointsResponse>('/onboarding/endpoints')
}
/**
* Verify model endpoints and save them to DB.
* Only sends user-provided fields; backend fills role defaults.
*
* Caller must include the role(s) required by `agent_mode`. The inactive
* role may be omitted; its previously saved config is left untouched.
*/
export function verifyEndpoints(payload: VerifyEndpointsPayload): Promise<ModelVerifyResponse> {
return apiClient.post<ModelVerifyResponse>('/onboarding/verify', payload)
}
/**
* Update only the active `agent_mode` — no model verification.
*
* The backend rejects with HTTP 400 if the new mode requires a model that
* has no saved config yet.
*/
export function setAgentMode(mode: AgentMode): Promise<{ agent_mode: AgentMode }> {
return apiClient.post<{ agent_mode: AgentMode }>('/onboarding/agent-mode', {
agent_mode: mode,
})
}
/**
* Mark onboarding as completed.
* Requires both endpoints to be verified.
*/
export function completeOnboarding(): Promise<void> {
return apiClient.post('/onboarding/complete')
}
/**
* Reset onboarding config (clear model endpoints and completed flag).
*/
export function resetOnboarding(): Promise<void> {
return apiClient.post('/onboarding/reset')
}
// =============================================================================
// Query Hooks
// =============================================================================
const onboardingKeys = {
all: ['onboarding'] as const,
endpoints: () => [...onboardingKeys.all, 'endpoints'] as const,
}
/**
* The user's currently-saved `agent_mode` from settings.
*
* Cached indefinitely (`gcTime: Infinity` so the data survives even with no
* observers). Invalidate via `invalidateOnboardingEndpoints` after mutations.
*/
export function useCurrentAgentMode(): { agentMode: AgentMode | null; isLoading: boolean } {
const query = useQuery({
queryKey: onboardingKeys.endpoints(),
queryFn: getOnboardingEndpoints,
staleTime: Infinity,
gcTime: Infinity,
refetchOnWindowFocus: false,
select: (data) => data.agent_mode ?? null,
})
return { agentMode: query.data ?? null, isLoading: query.isLoading }
}
/** Invalidate the cached onboarding endpoints (and therefore `agent_mode`). */
export function invalidateOnboardingEndpoints(queryClient: QueryClient): Promise<void> {
return queryClient.invalidateQueries({ queryKey: onboardingKeys.endpoints() })
}