| 1081 | var _ wsbuilder.UsageChecker = &API{} |
| 1082 | |
| 1083 | func (api *API) CheckBuildUsage( |
| 1084 | _ context.Context, |
| 1085 | _ database.Store, |
| 1086 | templateVersion *database.TemplateVersion, |
| 1087 | task *database.Task, |
| 1088 | transition database.WorkspaceTransition, |
| 1089 | ) (wsbuilder.UsageCheckResponse, error) { |
| 1090 | // If the template version has an external agent, we need to check that the |
| 1091 | // license is entitled to this feature. |
| 1092 | if templateVersion.HasExternalAgent.Valid && templateVersion.HasExternalAgent.Bool { |
| 1093 | feature, ok := api.Entitlements.Feature(codersdk.FeatureWorkspaceExternalAgent) |
| 1094 | if !ok || !feature.Enabled { |
| 1095 | return wsbuilder.UsageCheckResponse{ |
| 1096 | Permitted: false, |
| 1097 | Message: "You have a template which uses external agents but your license is not entitled to this feature. You will be unable to create new workspaces from these templates.", |
| 1098 | }, nil |
| 1099 | } |
| 1100 | } |
| 1101 | |
| 1102 | // Verify managed agent entitlement for AI task builds. |
| 1103 | // The count/limit check is intentionally omitted — breaching the |
| 1104 | // limit is advisory only and surfaced as a warning via entitlements. |
| 1105 | if transition != database.WorkspaceTransitionStart || task == nil { |
| 1106 | return wsbuilder.UsageCheckResponse{Permitted: true}, nil |
| 1107 | } |
| 1108 | |
| 1109 | if !api.Entitlements.HasLicense() { |
| 1110 | return wsbuilder.UsageCheckResponse{Permitted: true}, nil |
| 1111 | } |
| 1112 | |
| 1113 | managedAgentLimit, ok := api.Entitlements.Feature(codersdk.FeatureManagedAgentLimit) |
| 1114 | if !ok || !managedAgentLimit.Enabled { |
| 1115 | return wsbuilder.UsageCheckResponse{ |
| 1116 | Permitted: false, |
| 1117 | Message: "Your license is not entitled to managed agents. Please contact sales to continue using managed agents.", |
| 1118 | }, nil |
| 1119 | } |
| 1120 | |
| 1121 | return wsbuilder.UsageCheckResponse{Permitted: true}, nil |
| 1122 | } |
| 1123 | |
| 1124 | // getProxyDERPStartingRegionID returns the starting region ID that should be |
| 1125 | // used for workspace proxies. A proxy's actual region ID is the return value |