func()

in cli/azd/internal/cmd/add/add_select_ai.go [43:156]


func (a *AddAction) promptOpenAi(
	console input.Console,
	ctx context.Context,
	r *project.ResourceConfig,
	_ PromptOptions) (*project.ResourceConfig, error) {
	aiOption, err := console.Select(ctx, input.ConsoleOptions{
		Message: "Which type of Azure OpenAI service?",
		Options: []string{
			"Chat (GPT)",                   // 0 - chat
			"Embeddings (Document search)", // 1 - embeddings
		}})
	if err != nil {
		return nil, err
	}

	var allModels []ModelList
	for {
		err = provisioning.EnsureSubscriptionAndLocation(
			ctx, a.envManager, a.env, a.prompter, provisioning.EnsureSubscriptionAndLocationOptions{})
		if err != nil {
			return nil, err
		}

		console.ShowSpinner(
			ctx,
			fmt.Sprintf("Fetching available models in %s...", a.env.GetLocation()),
			input.Step)

		supportedModels, err := a.supportedModelsInLocation(ctx, a.env.GetSubscriptionId(), a.env.GetLocation())
		if err != nil {
			return nil, err
		}
		console.StopSpinner(ctx, "", input.Step)

		for _, model := range supportedModels {
			if model.Kind == "OpenAI" && slices.ContainsFunc(model.Model.Skus, func(sku ModelSku) bool {
				return sku.Name == "Standard"
			}) {
				switch aiOption {
				case 0:
					if model.Model.Name == "gpt-4o" || model.Model.Name == "gpt-4" {
						allModels = append(allModels, model)
					}
				case 1:
					if strings.HasPrefix(model.Model.Name, "text-embedding") {
						allModels = append(allModels, model)
					}
				}
			}

		}
		if len(allModels) > 0 {
			break
		}

		_, err = a.rm.FindResourceGroupForEnvironment(
			ctx, a.env.GetSubscriptionId(), a.env.Name())
		var notFoundError *azureutil.ResourceNotFoundError
		if errors.As(err, &notFoundError) { // not yet provisioned, we're safe here
			console.MessageUxItem(ctx, &ux.WarningMessage{
				Description: fmt.Sprintf("No models found in %s", a.env.GetLocation()),
			})
			confirm, err := console.Confirm(ctx, input.ConsoleOptions{
				Message: "Try a different location?",
			})
			if err != nil {
				return nil, err
			}
			if confirm {
				a.env.SetLocation("")
				continue
			}
		} else if err != nil {
			return nil, fmt.Errorf("finding resource group: %w", err)
		}

		return nil, fmt.Errorf("no models found in %s", a.env.GetLocation())
	}

	slices.SortFunc(allModels, func(a ModelList, b ModelList) int {
		return strings.Compare(b.Model.SystemData.CreatedAt, a.Model.SystemData.CreatedAt)
	})

	displayModels := make([]string, 0, len(allModels))
	models := make([]Model, 0, len(allModels))
	for _, model := range allModels {
		models = append(models, model.Model)
		displayModels = append(displayModels, fmt.Sprintf("%s\t%s", model.Model.Name, model.Model.Version))
	}

	if console.IsSpinnerInteractive() {
		displayModels, err = output.TabAlign(displayModels, 5)
		if err != nil {
			return nil, fmt.Errorf("writing models: %w", err)
		}
	}

	sel, err := console.Select(ctx, input.ConsoleOptions{
		Message: "Select the model",
		Options: displayModels,
	})
	if err != nil {
		return nil, err
	}

	r.Props = project.AIModelProps{
		Model: project.AIModelPropsModel{
			Name:    models[sel].Name,
			Version: models[sel].Version,
		},
	}

	return r, nil
}