Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2fbdc12
feat: add CrewAI and LangGraph framework support
Oct 26, 2025
1985190
docs: add README templates for CrewAI and LangGraph frameworks
Oct 26, 2025
35d9a17
docs
Oct 26, 2025
85009b8
Merge branch 'main' into feature/init-crewai-langgraph-templates
rishabh998186 Oct 27, 2025
6671805
fix: use GetFrameworkName() method instead of hardcoded framework str…
Oct 28, 2025
77c86db
Use GetFrameworkName() method and Rename PythonGenerator to ADKGener…
Oct 28, 2025
509d3ac
add language validation, extract helper functions, use constants
Oct 28, 2025
fcce92e
fix: resolve compilation errors and template function issues.
Oct 28, 2025
716512b
fix: resolve linter errors
Oct 28, 2025
c25a5e8
fix: add nolint comment to suppress false unused warning
Oct 28, 2025
8b1d2d7
fix: add nolint comment for RenderTemplate to suppress unused warning
Oct 29, 2025
1f5795e
fix: remove unused renderTemplate
Oct 29, 2025
56ddf37
fix:docker file of CrewAI and LangGraph and add dockercompose file
Oct 30, 2025
4016b1f
Merge branch 'main' into feature/init-crewai-langgraph-templates
rishabh998186 Oct 30, 2025
a4c5ad1
fix: complete createNewSecret function body after merge conflict
Oct 30, 2025
be81c1c
fix: add missing for loop in extractEnvVarsFromManifest.
Oct 30, 2025
5b8ea08
feat: Add MCP tools integration to LangGraph and CrewAI frameworks
Nov 3, 2025
12d428e
fix: correct framework dependencies and configuration
Nov 3, 2025
4b7ef07
update uv.lock dependencies for LangGraph and CrewAI
Nov 3, 2025
7c2f58f
Your commit message
Nov 25, 2025
fb93949
fix: add missing google-genai dependency
Nov 27, 2025
c07afe9
fix in crewai
Nov 28, 2025
dc88893
Merge branch 'main' into feature/init-crewai-langgraph-templates
rishabh998186 Dec 9, 2025
e6b7c2c
fix modulenotfounderror
Dec 9, 2025
b011695
Merge branch 'feature/init-crewai-langgraph-templates' of https://git…
Dec 9, 2025
67967d6
replace interface{} with any
Dec 9, 2025
c0cb47e
resolve all golangci-lint errors
Dec 9, 2025
bf812d2
resolve all golangci-lint errors
Dec 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions go/cli/cmd/kagent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,39 +213,43 @@ func main() {
}

initCmd := &cobra.Command{
Use: "init [framework] [language] [agent-name]",
Use: "init [agent-name]",
Short: "Initialize a new agent project",
Long: `Initialize a new agent project using the specified framework and language.
Long: `Initialize a new agent project using the specified framework .

You can customize the framework using the --framework flag (adk, crewai, langgraph).
You can customize the root agent instructions using the --instruction-file flag.
You can select a specific model using --model-provider and --model-name flags.
If no custom instruction file is provided, a default dice-rolling instruction will be used.
If no model is specified, the agent will need to be configured later.
If no custom instruction file is provided, framework-specific defaults will be used.

Examples:
kagent init adk python dice
kagent init adk python dice --instruction-file instructions.md
kagent init adk python dice --model-provider Gemini --model-name gemini-2.0-flash`,
Args: cobra.ExactArgs(3),
kagent init my-agent
kagent init my-agent --framework crewai
kagent init my-agent --framework langgraph --model-provider openai --model-name gpt-4
kagent init my-agent --framework adk --instruction-file instructions.md`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
initCfg.Framework = args[0]
initCfg.Language = args[1]
initCfg.AgentName = args[2]
initCfg.AgentName = args[0]

if err := cli.InitCmd(initCfg); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
},
Example: `kagent init adk python dice`,
}

// Add flags for custom instructions and model selection
// Add flags for framework selection and customization
initCmd.Flags().StringVarP(&initCfg.Framework, "framework", "f", "adk", "Framework to use (adk, crewai, langgraph)")
initCmd.Flags().StringVar(&initCfg.InstructionFile, "instruction-file", "", "Path to file containing custom instructions for the root agent")
initCmd.Flags().StringVar(&initCfg.ModelProvider, "model-provider", "Gemini", "Model provider (OpenAI, Anthropic, Gemini)")
initCmd.Flags().StringVar(&initCfg.ModelName, "model-name", "gemini-2.0-flash", "Model name (e.g., gpt-4, claude-3-5-sonnet, gemini-2.0-flash)")
initCmd.Flags().StringVar(&initCfg.ModelProvider, "model-provider", "Gemini", "Model provider (OpenAI, Anthropic, Gemini, AzureOpenAI)")
initCmd.Flags().StringVar(&initCfg.ModelName, "model-name", "Gemini-2.0-flash", "Model name (e.g., gpt-4, claude-3-5-sonnet, gemini-2.0-flash)")
initCmd.Flags().StringVar(&initCfg.Description, "description", "", "Description for the agent")

// Add shell completion for framework flag
_ = initCmd.RegisterFlagCompletionFunc("framework", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"adk", "crewai", "langgraph"}, cobra.ShellCompDirectiveNoFileComp
})

buildCfg := &cli.BuildCfg{
Config: cfg,
}
Expand Down
20 changes: 15 additions & 5 deletions go/cli/internal/agent/frameworks/adk/python/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,29 @@ import (
var templatesFS embed.FS

// PythonGenerator generates Python ADK projects
type PythonGenerator struct {
type ADKGenerator struct {
*common.BaseGenerator
}

// NewPythonGenerator creates a new ADK Python generator
func NewPythonGenerator() *PythonGenerator {
return &PythonGenerator{
// NewADKGenerator creates a new ADK Python generator
func NewADKGenerator() *ADKGenerator {
return &ADKGenerator{
BaseGenerator: common.NewBaseGenerator(templatesFS),
}
}

// GetFrameworkName returns the framework name
func (g *ADKGenerator) GetFrameworkName() string {
return "adk"
}

// GetLanguage returns the language
func (g *ADKGenerator) GetLanguage() string {
return "python"
}

// Generate creates a new Python ADK project
func (g *PythonGenerator) Generate(projectDir, agentName, instruction, modelProvider, modelName, description string, verbose bool, kagentVersion string) error {
func (g *ADKGenerator) Generate(projectDir, agentName, instruction, modelProvider, modelName, description string, verbose bool, kagentVersion string) error {
// Create the main project directory structure
subDir := filepath.Join(projectDir, agentName)
if err := os.MkdirAll(subDir, 0755); err != nil {
Expand Down
14 changes: 7 additions & 7 deletions go/cli/internal/agent/frameworks/common/base_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,6 @@ type BaseGenerator struct {
*generator.BaseGenerator
}

// NewBaseGenerator creates a new base generator that uses the shared generator
func NewBaseGenerator(templateFiles fs.FS) *BaseGenerator {
return &BaseGenerator{
BaseGenerator: generator.NewBaseGenerator(templateFiles, "templates"),
}
}

// GenerateProject generates a new project using the provided templates.
// This delegates to the shared generator implementation.
func (g *BaseGenerator) GenerateProject(config AgentConfig) error {
Expand All @@ -63,3 +56,10 @@ func (g *BaseGenerator) GenerateProject(config AgentConfig) error {
func (g *BaseGenerator) RenderTemplate(tmplContent string, data any) (string, error) {
return g.BaseGenerator.RenderTemplate(tmplContent, data)
}

// NewBaseGenerator creates a new BaseGenerator with the given template files
func NewBaseGenerator(templateFiles fs.FS) *BaseGenerator {
return &BaseGenerator{
BaseGenerator: generator.NewBaseGenerator(templateFiles, "templates"),
}
}
66 changes: 66 additions & 0 deletions go/cli/internal/agent/frameworks/common/framework_registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package common

import (
"fmt"
"strings"
)

// Generator defines the interface that all framework generators must implement
type Generator interface {
Generate(projectDir, agentName, instruction, modelProvider, modelName, description string, verbose bool, kagentVersion string) error
GetFrameworkName() string
GetLanguage() string
}

// GeneratorRegistry manages available framework generators
type GeneratorRegistry struct {
generators map[string]Generator
validator *FrameworkValidator
}

// NewGeneratorRegistry creates a new registry
func NewGeneratorRegistry() *GeneratorRegistry {
return &GeneratorRegistry{
generators: make(map[string]Generator),
validator: NewFrameworkValidator(),
}
}

// Register adds a generator to the registry
func (r *GeneratorRegistry) Register(gen Generator) error {
framework := strings.ToLower(gen.GetFrameworkName())

// Validate framework is supported
if err := r.validator.Validate(framework); err != nil {
return fmt.Errorf("cannot register unsupported framework: %w", err)
}

r.generators[framework] = gen
return nil
}

// Get retrieves a generator by framework name
func (r *GeneratorRegistry) Get(framework string) (Generator, error) {
framework = strings.ToLower(framework)

// Validate framework
if err := r.validator.Validate(framework); err != nil {
return nil, err
}

gen, exists := r.generators[framework]
if !exists {
return nil, fmt.Errorf("no generator registered for framework '%s'", framework)
}

return gen, nil
}

// List returns all registered framework names
func (r *GeneratorRegistry) List() []string {
frameworks := make([]string, 0, len(r.generators))
for framework := range r.generators {
frameworks = append(frameworks, framework)
}
return frameworks
}
38 changes: 38 additions & 0 deletions go/cli/internal/agent/frameworks/common/framework_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package common

import (
"fmt"
"slices"
"strings"
)

// SupportedFrameworks lists all available frameworks
var SupportedFrameworks = []string{"adk", "crewai", "langgraph"}

// FrameworkValidator validates framework selections
type FrameworkValidator struct{}

// NewFrameworkValidator creates a new validator
func NewFrameworkValidator() *FrameworkValidator {
return &FrameworkValidator{}
}

// Validate checks if the framework is supported
func (v *FrameworkValidator) Validate(framework string) error {
framework = strings.ToLower(framework)
if slices.Contains(SupportedFrameworks, framework) {
return nil
}
return fmt.Errorf("unsupported framework '%s'. Supported frameworks: %s",
framework, strings.Join(SupportedFrameworks, ", "))
}

// GetSupportedFrameworks returns the list of supported frameworks
func (v *FrameworkValidator) GetSupportedFrameworks() []string {
return SupportedFrameworks
}

// IsSupported checks if a framework is supported
func (v *FrameworkValidator) IsSupported(framework string) bool {
return v.Validate(framework) == nil
}
41 changes: 41 additions & 0 deletions go/cli/internal/agent/frameworks/common/template_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package common

import (
"strings"
"unicode"
)

// ToPascalCase converts a string to PascalCase
func ToPascalCase(s string) string {
// Split by common delimiters
words := strings.FieldsFunc(s, func(r rune) bool {
return r == '-' || r == '_' || r == ' '
})

for i, word := range words {
if len(word) > 0 {
// Capitalize first letter, lowercase rest
runes := []rune(word)
runes[0] = unicode.ToUpper(runes[0])
for j := 1; j < len(runes); j++ {
runes[j] = unicode.ToLower(runes[j])
}
words[i] = string(runes)
}
}

return strings.Join(words, "")
}

// ToUpper converts string to uppercase
func ToUpper(s string) string {
return strings.ToUpper(s)
}

// TemplateHelpers returns a map of helper functions for templates
func TemplateHelpers() map[string]any {
return map[string]any{
"ToPascalCase": ToPascalCase,
"ToUpper": ToUpper,
}
}
48 changes: 48 additions & 0 deletions go/cli/internal/agent/frameworks/common/versions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package common

// FrameworkVersions holds version information for framework dependencies
type FrameworkVersions struct {
CrewAI map[string]string
LangGraph map[string]string
KagentCore string
}

// DefaultVersions returns the default versions for all frameworks
func DefaultVersions() *FrameworkVersions {
return &FrameworkVersions{
CrewAI: map[string]string{
"crewai": "^0.76.0",
"crewai-tools": "^0.12.0",
},
LangGraph: map[string]string{
"langgraph": "^0.2.16",
"langchain": "^0.3.0",
},
KagentCore: "^0.3.0",
}
}

// GetCrewAIVersion returns the CrewAI package version
func (v *FrameworkVersions) GetCrewAIVersion() string {
return v.CrewAI["crewai"]
}

// GetCrewAIToolsVersion returns the CrewAI tools version
func (v *FrameworkVersions) GetCrewAIToolsVersion() string {
return v.CrewAI["crewai-tools"]
}

// GetLangGraphVersion returns the LangGraph version
func (v *FrameworkVersions) GetLangGraphVersion() string {
return v.LangGraph["langgraph"]
}

// GetLangChainVersion returns the LangChain version
func (v *FrameworkVersions) GetLangChainVersion() string {
return v.LangGraph["langchain"]
}

// GetKagentCoreVersion returns the kagent-core version
func (v *FrameworkVersions) GetKagentCoreVersion() string {
return v.KagentCore
}
Loading
Loading