Implementation:Langgenius Dify Provider Context
| Knowledge Sources | |
|---|---|
| Domains | Frontend, Model Management, Billing, Feature Flags |
| Last Updated | 2026-02-12 07:00 GMT |
Overview
A React context provider that manages model provider data, billing plan information, feature flags, and education plan status for the Dify console application.
Description
The ProviderContext is a central data hub for model infrastructure and billing state. It aggregates data from multiple sources: model providers and text generation models via TanStack Query hooks (useModelProviders, useModelListByType), supported retrieval methods via useSupportRetrievalMethods, current billing plan details via fetchCurrentPlanInfo, and education account status via useEducationStatus.
The ProviderContextProvider performs a plan info fetch on mount and parses the response to populate over a dozen feature flags and configuration values. These include enableBilling, enableReplaceWebAppLogo, modelLoadBalancingEnabled, datasetOperatorEnabled, enableEducationPlan, isEducationWorkspace, webappCopyrightEnabled, isAllowTransferWorkspace, isAllowPublishAsCustomKnowledgePipelineTemplate, and humanInputEmailDeliveryEnabled. The plan information includes usage and total quotas with reset dates, and the license limit tracks workspace member capacity.
The provider also includes side effects: it syncs the current plan type to Zendesk conversation fields for support context, and displays a one-time Anthropic trial quota notification toast for workspaces that still have unused Anthropic trial credits (with a date-based expiry and localStorage-based dismissal). Error handling for the plan fetch gracefully falls back to safe defaults to prevent undefined state errors.
Usage
Use useProviderContext() to access the full context or useProviderContextSelector() for optimized selective subscriptions. This context is typically consumed by billing-related components, model selection UIs, feature-gated sections, and any component that needs to know whether a specific platform capability is enabled. The provider should wrap the authenticated console layout, below AppContextProvider.
Code Reference
Source Location
- Repository: Langgenius_Dify
- File: web/context/provider-context.tsx
- Lines: 1-266
Signature
export type ProviderContextState = {
modelProviders: ModelProvider[]
refreshModelProviders: () => void
textGenerationModelList: Model[]
supportRetrievalMethods: RETRIEVE_METHOD[]
isAPIKeySet: boolean
plan: {
type: Plan
usage: UsagePlanInfo
total: UsagePlanInfo
reset: UsageResetInfo
}
isFetchedPlan: boolean
enableBilling: boolean
onPlanInfoChanged: () => void
enableReplaceWebAppLogo: boolean
modelLoadBalancingEnabled: boolean
datasetOperatorEnabled: boolean
enableEducationPlan: boolean
isEducationWorkspace: boolean
isEducationAccount: boolean
allowRefreshEducationVerify: boolean
educationAccountExpireAt: number | null
isLoadingEducationAccountInfo: boolean
isFetchingEducationAccountInfo: boolean
webappCopyrightEnabled: boolean
licenseLimit: {
workspace_members: { size: number; limit: number }
}
refreshLicenseLimit: () => void
isAllowTransferWorkspace: boolean
isAllowPublishAsCustomKnowledgePipelineTemplate: boolean
humanInputEmailDeliveryEnabled: boolean
}
export const useProviderContext: () => ProviderContextState
export const useProviderContextSelector: <T,>(selector: (state: ProviderContextState) => T) => T
export const ProviderContextProvider: FC<{ children: React.ReactNode }>
export const baseProviderContextValue: ProviderContextState
Import
import {
useProviderContext,
useProviderContextSelector,
ProviderContextProvider,
baseProviderContextValue,
} from '@/context/provider-context'
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| children | React.ReactNode |
Yes | Child components that will have access to the provider context |
Outputs
| Name | Type | Description |
|---|---|---|
| modelProviders | ModelProvider[] |
List of available model providers with their configuration status |
| refreshModelProviders | () => void |
Invalidates the model providers query to trigger a refetch |
| textGenerationModelList | Model[] |
List of text generation models available in the workspace |
| supportRetrievalMethods | RETRIEVE_METHOD[] |
Supported document retrieval methods for the workspace |
| isAPIKeySet | boolean |
True if at least one text generation model has active status |
| plan | { type, usage, total, reset } |
Current billing plan details with usage and quota information |
| isFetchedPlan | boolean |
True after the plan information has been successfully fetched |
| enableBilling | boolean |
True if the billing feature is enabled for the workspace |
| onPlanInfoChanged | () => void |
Triggers a refetch of the plan information |
| enableReplaceWebAppLogo | boolean |
True if the workspace can replace the web app logo |
| modelLoadBalancingEnabled | boolean |
True if model load balancing is enabled |
| datasetOperatorEnabled | boolean |
True if the dataset operator role is enabled |
| enableEducationPlan | boolean |
True if the education plan feature is enabled |
| isEducationWorkspace | boolean |
True if the current workspace has an active education plan |
| isEducationAccount | boolean |
True if the current user has a verified education account |
| allowRefreshEducationVerify | boolean |
True if the user can re-verify their education status |
| educationAccountExpireAt | null | Unix timestamp when the education account expires |
| webappCopyrightEnabled | boolean |
True if web app copyright display is enabled |
| licenseLimit | { workspace_members: { size, limit } } |
Current workspace member count and limit |
| refreshLicenseLimit | () => void |
Triggers a refetch of license limit information |
| isAllowTransferWorkspace | boolean |
True if workspace transfer is permitted |
| isAllowPublishAsCustomKnowledgePipelineTemplate | boolean |
True if publishing custom knowledge pipeline templates is allowed |
| humanInputEmailDeliveryEnabled | boolean |
True if human input email delivery is enabled |
Usage Examples
Checking Billing and Upgrading
import { useProviderContext } from '@/context/provider-context'
function PlanStatus() {
const { plan, enableBilling, onPlanInfoChanged } = useProviderContext()
if (!enableBilling) return null
return (
<div>
<span>Current plan: {plan.type}</span>
<span>Messages used: {plan.usage.messageCredits} / {plan.total.messageCredits}</span>
<button onClick={onPlanInfoChanged}>Refresh Plan</button>
</div>
)
}
Feature-Gated UI with Selective Subscription
import { useProviderContextSelector } from '@/context/provider-context'
function LoadBalancingSection() {
const enabled = useProviderContextSelector(s => s.modelLoadBalancingEnabled)
if (!enabled) return null
return <LoadBalancingConfiguration />
}
Checking API Key Configuration
import { useProviderContext } from '@/context/provider-context'
function ModelSetupBanner() {
const { isAPIKeySet, modelProviders } = useProviderContext()
if (isAPIKeySet) return null
return (
<div className="banner-warning">
No active model configured. Please set up a model provider.
Available providers: {modelProviders.length}
</div>
)
}