Spaces:
Paused
Paused
Hooks Module
React hooks for API data fetching, state management, and complex workflows (chat, streaming, file handling).
Key Components
- Query hooks (
useNotebookSources,useSource,useSources): TanStack Query wrappers for source data with infinite scroll and refetch strategies - Mutation hooks (
useCreateSource,useUpdateSource,useDeleteSource,useFileUpload,useRetrySource): Server mutations with toast notifications and cache invalidation - Chat hooks (
useNotebookChat,useSourceChat): Complex session management, context building, and message streaming - Streaming hooks (
useAsk): SSE parsing for multi-stage Ask workflows (strategy β answers β final answer) - Model/config hooks (
useModels,useSettings,useTransformations): Application-level settings and model management - Utility hooks (
useMediaQuery,useToast,useNavigation,useAuth): UI state and auth checking - i18n hook (
useTranslation): Thin wrapper around react-i18next witht('section.key')pattern and language switching
Important Patterns
- TanStack Query integration: All data hooks use
useQuery/useMutationwithQUERY_KEYSfor cache consistency - Optimistic updates: Mutations add local state before server response (e.g., notebook chat messages)
- Cache invalidation: Broad invalidation of query keys on mutations (e.g.,
['sources']catches all source queries) - Auto-refetch on return:
refetchOnWindowFocus: trueon frequently-changing data (sources, notebooks) - Manual refetch controls: Hooks return
refetch()for parent components to trigger refresh - SSE streaming pattern:
useAskmanually parses newline-delimited JSON from/api/search/ask; handles incomplete buffers - Status polling:
useSourceStatusauto-refetches every 2s whilestatus === 'running' | 'queued' | 'new' - Context building:
useNotebookChat.buildContext()assembles selected sources + notes with token/char counts - i18n pattern:
useTranslationreturns standard react-i18nexttfunction; access translations viat('section.key')
Key Dependencies
@tanstack/react-query: Data fetching and cachingsonner: Toast notifications@/lib/api/*: API module exports (sourcesApi, chatApi, searchApi, etc.)@/lib/types/api: TypeScript response types- Zustand stores:
useAuthStore, modal managers
How to Add New Hooks
- Data queries: Create
useQueryhook wrapping API call; useQUERY_KEYS.entityName(id)for cache key - Mutations: Create
useMutationhook withonSuccesscache invalidation + toast feedback - Complex state: Use
useState+ callbacks for local state (seeuseAsk,useNotebookChat) - Return shape: Export object with both state and action functions for composability
Important Quirks & Gotchas
- Cache invalidation breadth: Invalidating
['sources']affects ALL source queries; be precise if performance matters - Optimistic updates + error handling:
useNotebookChatremoves optimistic messages on error; ensure cleanup - SSE buffer handling:
useAskkeeps incomplete lines in buffer between reads; incomplete JSON silently skipped - Model override timing:
useNotebookChatstores pending model override if no session exists; applied on session creation - Pagination cursor:
useNotebookSourcesuses offset-based pagination;nextOffsetcalculated from page size - Status polling race:
useSourceStatusmay refetch stale data before server catches up; retry logic has 3-attempt limit - Keyboard trap in dialogs: Some hooks manage modal state; ensure Dialog/Modal components handle escape key properly
- Form data handling:
useFileUploadand source creation convert JSON fields to strings in FormData - useTranslation: Thin wrapper preserving
setLanguagewith language change events forLanguageLoadingOverlay
Testing Patterns
// Mock API
const mockApi = {
list: vi.fn().mockResolvedValue([...])
}
// Test hook with QueryClientProvider + wrapper
render(<Component />, { wrapper: QueryClientProvider })
// Assert mutations trigger cache invalidation
await waitFor(() => expect(queryClient.invalidateQueries).toHaveBeenCalled())
Credentials Hooks (use-credentials.ts)
Hooks for managing AI provider credentials with TanStack Query integration, toast notifications, and cache invalidation.
Query Keys
export const CREDENTIAL_QUERY_KEYS = {
all: ['credentials'] as const,
status: ['credentials', 'status'] as const,
envStatus: ['credentials', 'env-status'] as const,
byProvider: (provider: string) => ['credentials', 'provider', provider] as const,
detail: (id: string) => ['credentials', id] as const,
}
Query Hooks
| Hook | Description | Returns |
|---|---|---|
useCredentialStatus() |
Get configuration status of all providers | { configured, source, encryption_configured } |
useEnvStatus() |
Get which providers have env vars set | { [provider]: boolean } |
useCredentials(provider?) |
List all credentials (optional filter) | Credential[] |
useCredentialsByProvider(provider) |
List credentials for a specific provider | Credential[] |
useCredential(credentialId) |
Get a specific credential | Credential |
Mutation Hooks
| Hook | Description | Cache Invalidation |
|---|---|---|
useCreateCredential() |
Create new credential | all, providers |
useUpdateCredential() |
Update credential | all, providers |
useDeleteCredential() |
Delete credential | all, models, providers |
useTestCredential() |
Test credential connection | None (stores result locally) |
useDiscoverModels() |
Discover models for credential | None |
useRegisterModels() |
Register discovered models | models, all |
useMigrateFromEnv() |
Migrate from env vars | status, envStatus, models, providers |
useMigrateFromProviderConfig() |
Migrate from legacy ProviderConfig | status, envStatus, models, providers |
useTestCredential Details
Returns extended interface with local state management for test results:
const {
testCredential, // (credentialId: string) => void
testCredentialAsync, // (credentialId: string) => Promise<TestConnectionResult>
isPending, // boolean
testResults, // Record<string, TestConnectionResult>
clearResult, // (credentialId: string) => void
} = useTestCredential()
Cache Invalidation Strategy
All mutation hooks invalidate:
CREDENTIAL_QUERY_KEYS.allβ refreshes all credential queries (cascades to filtered queries)MODEL_QUERY_KEYS.providersβ refreshes provider list
Delete hook additionally invalidates:
MODEL_QUERY_KEYS.modelsβ refreshes full model list (linked models may be deleted)
Migration hooks additionally invalidate:
CREDENTIAL_QUERY_KEYS.statusβ refreshes configured/source infoCREDENTIAL_QUERY_KEYS.envStatusβ refreshes env var status
Usage Example
import {
useCredentialStatus,
useCredentials,
useCreateCredential,
useTestCredential,
useMigrateFromEnv
} from '@/lib/hooks/use-credentials'
function CredentialSettings() {
const { data: status, isLoading } = useCredentialStatus()
const { data: credentials } = useCredentials()
const createCredential = useCreateCredential()
const { testCredential, testResults, isPending } = useTestCredential()
const migrateFromEnv = useMigrateFromEnv()
const handleCreate = () => {
createCredential.mutate({
name: 'My OpenAI Key',
provider: 'openai',
modalities: ['language', 'embedding'],
api_key: 'sk-...'
})
}
const handleTest = (credentialId: string) => {
testCredential(credentialId)
}
const handleMigrate = () => {
migrateFromEnv.mutate()
}
return (
<div>
{credentials?.map(cred => (
<div key={cred.id}>
<span>{cred.name} ({cred.provider})</span>
<button onClick={() => handleTest(cred.id)} disabled={isPending}>Test</button>
{testResults[cred.id]?.success && <span>Connected!</span>}
</div>
))}
<button onClick={handleCreate}>Add Credential</button>
<button onClick={handleMigrate}>Migrate from .env</button>
</div>
)
}
Important Notes
- Toast notifications: All mutations show success/error toasts automatically
- i18n integration: Toast messages use translation keys from
t('apiKeys.*')andt('common.*') - Error handling: Uses
getApiErrorKey()utility to extract error messages from API responses - Local test results:
useTestCredentialstores results in local state (not cached in TanStack Query) - Migration feedback: Migration hooks show different toasts based on migrated/skipped/error counts