-
Notifications
You must be signed in to change notification settings - Fork 32
fix: 'create agent' command to show template, bolt framework, and agent framework options #479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
a523c56
71f9b28
a7bb34a
60a669c
c8b280a
e82f2a9
897d858
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,14 +44,14 @@ func getSelectionOptions(categoryID string) []promptObject { | |
| }, | ||
| }, | ||
| "slack-cli#ai-apps": { | ||
| { | ||
| Title: fmt.Sprintf("Support Agent %s", style.Secondary("Resolve IT support cases")), | ||
| Repository: "slack-cli#ai-apps/support-agent", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("Starter Agent %s", style.Secondary("Start from scratch")), | ||
| Repository: "slack-cli#ai-apps/starter-agent", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("Support Agent %s", style.Secondary("Resolve IT support cases")), | ||
| Repository: "slack-cli#ai-apps/support-agent", | ||
| }, | ||
| }, | ||
| "slack-cli#automation-apps": { | ||
| { | ||
|
|
@@ -71,38 +71,96 @@ func getSelectionOptions(categoryID string) []promptObject { | |
| return templatePromptObjects[categoryID] | ||
| } | ||
|
|
||
| // getFrameworkOptions returns the framework choices for a given template. | ||
| // getFrameworkOptions returns the framework choices for a given AI app template. | ||
| func getFrameworkOptions(template string) []promptObject { | ||
| frameworkPromptObjects := map[string][]promptObject{ | ||
| "slack-cli#ai-apps/support-agent": { | ||
| { | ||
| Title: fmt.Sprintf("Claude Agent SDK %s", style.Secondary("Bolt for Python")), | ||
| Title: fmt.Sprintf("Bolt for JavaScript %s", style.Secondary("Node.js")), | ||
|
||
| Repository: "slack-cli#ai-apps/support-agent/bolt-js", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("Bolt for Python %s", style.Secondary("Python")), | ||
| Repository: "slack-cli#ai-apps/support-agent/bolt-python", | ||
| }, | ||
| }, | ||
| "slack-cli#ai-apps/starter-agent": { | ||
| { | ||
| Title: fmt.Sprintf("Bolt for JavaScript %s", style.Secondary("Node.js")), | ||
| Repository: "slack-cli#ai-apps/starter-agent/bolt-js", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("Bolt for Python %s", style.Secondary("Python")), | ||
| Repository: "slack-cli#ai-apps/starter-agent/bolt-python", | ||
| }, | ||
| }, | ||
| } | ||
| return frameworkPromptObjects[template] | ||
| } | ||
|
|
||
| // getAdapterOptions returns the AI agent framework choices for a given template and framework. | ||
| func getAdapterOptions(framework string) []promptObject { | ||
| adapterPromptObjects := map[string][]promptObject{ | ||
| "slack-cli#ai-apps/support-agent/bolt-js": { | ||
| { | ||
| Title: fmt.Sprintf("Claude Agent SDK %s", style.Secondary("Bolt for JavaScript - Support Agent Template")), | ||
| Repository: "slack-samples/bolt-js-support-agent", | ||
| Subdir: "claude-agent-sdk", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("OpenAI Agents SDK %s", style.Secondary("Bolt for JavaScript - Support Agent Template")), | ||
| Repository: "slack-samples/bolt-js-support-agent", | ||
| Subdir: "openai-agents-sdk", | ||
| }, | ||
| }, | ||
| "slack-cli#ai-apps/support-agent/bolt-python": { | ||
| { | ||
| Title: fmt.Sprintf("Claude Agent SDK %s", style.Secondary("Bolt for Python - Support Agent Template")), | ||
| Repository: "slack-samples/bolt-python-support-agent", | ||
| Subdir: "claude-agent-sdk", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("OpenAI Agents SDK %s", style.Secondary("Bolt for Python")), | ||
| Title: fmt.Sprintf("OpenAI Agents SDK %s", style.Secondary("Bolt for Python - Support Agent Template")), | ||
| Repository: "slack-samples/bolt-python-support-agent", | ||
| Subdir: "openai-agents-sdk", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("Pydantic AI %s", style.Secondary("Bolt for Python")), | ||
| Title: fmt.Sprintf("Pydantic AI %s", style.Secondary("Bolt for Python - Support Agent Template")), | ||
| Repository: "slack-samples/bolt-python-support-agent", | ||
| Subdir: "pydantic-ai", | ||
| }, | ||
| }, | ||
| "slack-cli#ai-apps/starter-agent": { | ||
| "slack-cli#ai-apps/starter-agent/bolt-js": { | ||
| { | ||
| Title: fmt.Sprintf("Bolt for JavaScript %s", style.Secondary("Node.js")), | ||
| Title: fmt.Sprintf("Claude Agent SDK %s", style.Secondary("Bolt for JavaScript - Starter Agent Template")), | ||
| Repository: "slack-samples/bolt-js-starter-agent", | ||
| Subdir: "claude-agent-sdk", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("Bolt for Python %s", style.Secondary("Python")), | ||
| Title: fmt.Sprintf("OpenAI Agents SDK %s", style.Secondary("Bolt for JavaScript - Starter Agent Template")), | ||
| Repository: "slack-samples/bolt-js-starter-agent", | ||
| Subdir: "openai-agents-sdk", | ||
| }, | ||
| }, | ||
| "slack-cli#ai-apps/starter-agent/bolt-python": { | ||
| { | ||
| Title: fmt.Sprintf("Claude Agent SDK %s", style.Secondary("Bolt for Python - Starter Agent Template")), | ||
| Repository: "slack-samples/bolt-python-starter-agent", | ||
| Subdir: "claude-agent-sdk", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("OpenAI Agents SDK %s", style.Secondary("Bolt for Python - Starter Agent Template")), | ||
| Repository: "slack-samples/bolt-python-starter-agent", | ||
| Subdir: "openai-agents-sdk", | ||
| }, | ||
| { | ||
| Title: fmt.Sprintf("Pydantic AI %s", style.Secondary("Bolt for Python - Starter Agent Template")), | ||
| Repository: "slack-samples/bolt-python-starter-agent", | ||
| Subdir: "pydantic-ai", | ||
| }, | ||
| }, | ||
| } | ||
| return frameworkPromptObjects[template] | ||
| return adapterPromptObjects[framework] | ||
| } | ||
|
|
||
| // getSelectionOptionsForCategory returns the top-level category options for | ||
|
|
@@ -223,31 +281,63 @@ func promptTemplateSelection(cmd *cobra.Command, clients *shared.ClientFactory, | |
| } | ||
| template := options[selection.Index].Repository | ||
|
|
||
| // Prompt for the example framework | ||
| examples := getFrameworkOptions(template) | ||
| choices := make([]string, len(examples)) | ||
| for i, opt := range examples { | ||
| choices[i] = opt.Title | ||
| // Prompt for the framework | ||
| frameworks := getFrameworkOptions(template) | ||
| frameworkChoices := make([]string, len(frameworks)) | ||
| for i, opt := range frameworks { | ||
| frameworkChoices[i] = opt.Title | ||
| } | ||
| choice, err := clients.IO.SelectPrompt(ctx, "Select a framework:", choices, iostreams.SelectPromptConfig{ | ||
| frameworkSelection, err := clients.IO.SelectPrompt(ctx, "Select a Bolt framework:", frameworkChoices, iostreams.SelectPromptConfig{ | ||
| Description: func(value string, index int) string { | ||
| return examples[index].Description | ||
| return frameworks[index].Description | ||
| }, | ||
| Required: true, | ||
| Template: getSelectionTemplate(clients), | ||
| }) | ||
| if err != nil { | ||
| return create.Template{}, err | ||
| } else if choice.Flag { | ||
| } else if frameworkSelection.Flag { | ||
| return create.Template{}, slackerror.New(slackerror.ErrPrompt) | ||
| } | ||
| example := examples[choice.Index] | ||
| resolved, err := create.ResolveTemplateURL(example.Repository) | ||
| framework := frameworks[frameworkSelection.Index] | ||
|
|
||
| // Check if there are adapter options for this framework | ||
| adapters := getAdapterOptions(framework.Repository) | ||
| if len(adapters) > 0 { | ||
| adapterChoices := make([]string, len(adapters)) | ||
| for i, opt := range adapters { | ||
| adapterChoices[i] = opt.Title | ||
| } | ||
| adapterSelection, err := clients.IO.SelectPrompt(ctx, "Select an agent framework:", adapterChoices, iostreams.SelectPromptConfig{ | ||
| Description: func(value string, index int) string { | ||
| return adapters[index].Description | ||
| }, | ||
| Required: true, | ||
| Template: getSelectionTemplate(clients), | ||
| }) | ||
| if err != nil { | ||
| return create.Template{}, err | ||
| } else if adapterSelection.Flag { | ||
| return create.Template{}, slackerror.New(slackerror.ErrPrompt) | ||
| } | ||
| adapter := adapters[adapterSelection.Index] | ||
| resolved, err := create.ResolveTemplateURL(adapter.Repository) | ||
| if err != nil { | ||
| return create.Template{}, err | ||
| } | ||
| if adapter.Subdir != "" { | ||
| resolved.SetSubdir(adapter.Subdir) | ||
| } | ||
| return resolved, nil | ||
| } | ||
|
|
||
| // No adapter options - resolve the framework directly | ||
| resolved, err := create.ResolveTemplateURL(framework.Repository) | ||
| if err != nil { | ||
| return create.Template{}, err | ||
| } | ||
| if example.Subdir != "" { | ||
| resolved.SetSubdir(example.Subdir) | ||
| if framework.Subdir != "" { | ||
| resolved.SetSubdir(framework.Subdir) | ||
| } | ||
| return resolved, nil | ||
| } | ||
|
|
@@ -300,27 +390,33 @@ func listTemplates(ctx context.Context, clients *shared.ClientFactory, categoryS | |
| var categories []categoryInfo | ||
| if categoryShortcut == "agent" { | ||
| categories = []categoryInfo{ | ||
| {id: "slack-cli#ai-apps/support-agent", name: "Support agent"}, | ||
| {id: "slack-cli#ai-apps/starter-agent", name: "Starter agent"}, | ||
| {id: "slack-cli#ai-apps/support-agent", name: "Support agent"}, | ||
| } | ||
| } else { | ||
| categories = []categoryInfo{ | ||
| {id: "slack-cli#getting-started", name: "Getting started"}, | ||
| {id: "slack-cli#ai-apps/support-agent", name: "Support agent"}, | ||
| {id: "slack-cli#ai-apps/starter-agent", name: "Starter agent"}, | ||
| {id: "slack-cli#ai-apps/support-agent", name: "Support agent"}, | ||
| {id: "slack-cli#automation-apps", name: "Automation apps"}, | ||
| } | ||
| } | ||
|
|
||
| for _, category := range categories { | ||
| var secondary []string | ||
| if frameworks := getFrameworkOptions(category.id); len(frameworks) > 0 { | ||
| for _, tmpl := range frameworks { | ||
| repo := tmpl.Repository | ||
| if tmpl.Subdir != "" { | ||
| repo = fmt.Sprintf("%s --subdir %s", repo, tmpl.Subdir) | ||
| for _, fw := range frameworks { | ||
| if adapters := getAdapterOptions(fw.Repository); len(adapters) > 0 { | ||
| for _, adapter := range adapters { | ||
| repo := adapter.Repository | ||
| if adapter.Subdir != "" { | ||
| repo = fmt.Sprintf("%s --subdir %s", repo, adapter.Subdir) | ||
| } | ||
| secondary = append(secondary, repo) | ||
| } | ||
| } else { | ||
| secondary = append(secondary, fw.Repository) | ||
| } | ||
| secondary = append(secondary, repo) | ||
| } | ||
| } else { | ||
| for _, tmpl := range getSelectionOptions(category.id) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.