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
caa1d3f
feat(group): add unified Group type deriving toolset and promptset views
twishabansal Jun 22, 2026
47e8679
refactor(group): store toolset and promptset to preserve O(1) lookups
twishabansal Jun 22, 2026
847f22b
Merge branch 'main' into feat/groups-pr1-group-package
twishabansal Jun 29, 2026
3ecb078
Merge branch 'main' into feat/groups-pr1-group-package
twishabansal Jul 1, 2026
0d45138
refactor(server): make group the source of truth in ResourceManager
twishabansal Jul 2, 2026
a97762a
Merge branch 'main' into feat/groups-pr1-group-package
twishabansal Jul 7, 2026
7854329
test(tool/cloudgda): update NewResourceManager call to groups signature
twishabansal Jul 7, 2026
1d0a810
test(server): assert against groups instead of legacy toolset/prompts…
twishabansal Jul 8, 2026
796ecaf
Merge branch 'main' into feat/groups-pr1-group-package
twishabansal Jul 8, 2026
c55df6e
test(server): drop stale nil opts arg in setUpServer calls
twishabansal Jul 8, 2026
00d4541
feat(group): parse kind: group config and wire into initialization
twishabansal Jul 8, 2026
8a7c30f
fix(group): clarify merge-conflict message for default nameless group
twishabansal Jul 8, 2026
de8ae9b
Merge branch 'main' into feat/groups-pr1-group-package
twishabansal Jul 9, 2026
38a0d41
refactor(group): make Group a standalone primitive
twishabansal Jul 10, 2026
f457f98
Merge branch 'feat/groups-pr1-group-package' into feat/groups-pr1b-wi…
twishabansal Jul 10, 2026
4f939ad
Merge branch 'feat/groups-pr1b-wiring' into feat/groups-pr1c-parsing
twishabansal Jul 10, 2026
7aa4b4a
fix(group): update dataplex test call sites for new UnmarshalResource…
twishabansal Jul 10, 2026
70fa826
Merge branch 'feat/groups' into feat/groups-pr1b-wiring
twishabansal Jul 13, 2026
75b8f60
refactor(skills): derive --toolset skill tools from group
twishabansal Jul 13, 2026
f9d240c
test(server): assert full structs and cover GetGroup
twishabansal Jul 13, 2026
3fc681a
Merge branch 'feat/groups-pr1b-wiring' into feat/groups-pr1c-parsing
twishabansal Jul 13, 2026
6cf05dd
refactor(group): fold kind:toolset into GroupConfigs at unmarshal
twishabansal Jul 13, 2026
47ea71d
refactor(group): simplify group config unmarshal and consolidate tests
twishabansal Jul 13, 2026
613d11c
Update internal/server/config.go
twishabansal Jul 13, 2026
67c3fdd
fix(group): return zero GroupConfig instead of nil on decode error
twishabansal Jul 13, 2026
eb7fe01
refactor(group): drop empty-name special case in group merge conflict
twishabansal Jul 13, 2026
d119d79
refactor(server): simplify group name and dedup handling
twishabansal Jul 13, 2026
5c27d07
feat(server): reject duplicate resource names across all kinds
twishabansal Jul 13, 2026
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: 18 additions & 16 deletions cmd/internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ type Config struct {
AuthServices server.AuthServiceConfigs `yaml:"authServices"`
EmbeddingModels server.EmbeddingModelConfigs `yaml:"embeddingModels"`
Tools server.ToolConfigs `yaml:"tools"`
Toolsets server.ToolsetConfigs `yaml:"toolsets"`
Prompts server.PromptConfigs `yaml:"prompts"`
Groups server.GroupConfigs `yaml:"groups"`
}

type ConfigParser struct {
Expand Down Expand Up @@ -150,7 +150,7 @@ func (p *ConfigParser) ParseConfig(ctx context.Context, raw []byte) (Config, err
}

// Parse contents
config.Sources, config.AuthServices, config.EmbeddingModels, config.Tools, config.Toolsets, config.Prompts, err = server.UnmarshalResourceConfig(ctx, raw)
config.Sources, config.AuthServices, config.EmbeddingModels, config.Tools, config.Prompts, config.Groups, err = server.UnmarshalResourceConfig(ctx, raw)
if err != nil {
return config, err
}
Expand Down Expand Up @@ -180,7 +180,7 @@ func ConvertConfig(raw []byte) ([]byte, error) {
decoder := yaml.NewDecoder(bytes.NewReader(raw), yaml.UseOrderedMap())
encoder := yaml.NewEncoder(&buf, yaml.UseLiteralStyleIfMultiline(true))

nestedFormatKey := []string{"sources", "authServices", "embeddingModels", "tools", "toolsets", "prompts"}
nestedFormatKey := []string{"sources", "authServices", "embeddingModels", "tools", "toolsets", "prompts", "groups"}
docIndex := 0
for {
if err := decoder.Decode(&input); err != nil {
Expand Down Expand Up @@ -217,6 +217,8 @@ func ConvertConfig(raw []byte) ([]byte, error) {
key = "toolset"
case "prompts":
key = "prompt"
case "groups":
key = "group"
}
transformed, err := transformDocs(key, slice)
if err != nil {
Expand Down Expand Up @@ -306,16 +308,16 @@ func processValue(v any, isToolset bool) any {
}

// mergeConfigs merges multiple Config structs into one.
// Detects and raises errors for resource conflicts in sources, authServices, tools, and toolsets.
// All resource names (sources, authServices, tools, toolsets) must be unique across all files.
// Detects and raises errors for resource conflicts in sources, authServices, tools, and groups.
// All resource names (sources, authServices, tools, groups) must be unique across all files.
func mergeConfigs(files ...Config) (Config, error) {
merged := Config{
Sources: make(server.SourceConfigs),
AuthServices: make(server.AuthServiceConfigs),
EmbeddingModels: make(server.EmbeddingModelConfigs),
Tools: make(server.ToolConfigs),
Toolsets: make(server.ToolsetConfigs),
Prompts: make(server.PromptConfigs),
Groups: make(server.GroupConfigs),
}

var conflicts []string
Expand Down Expand Up @@ -359,15 +361,6 @@ func mergeConfigs(files ...Config) (Config, error) {
}
}

// Check for conflicts and merge toolsets
for name, toolset := range file.Toolsets {
if _, exists := merged.Toolsets[name]; exists {
conflicts = append(conflicts, fmt.Sprintf("toolset '%s' (file #%d)", name, fileIndex+1))
} else {
merged.Toolsets[name] = toolset
}
}

// Check for conflicts and merge prompts
for name, prompt := range file.Prompts {
if _, exists := merged.Prompts[name]; exists {
Expand All @@ -376,11 +369,20 @@ func mergeConfigs(files ...Config) (Config, error) {
merged.Prompts[name] = prompt
}
}

// Check for conflicts and merge groups
for name, grp := range file.Groups {
if _, exists := merged.Groups[name]; exists {
conflicts = append(conflicts, fmt.Sprintf("group '%s' (file #%d)", name, fileIndex+1))
} else {
merged.Groups[name] = grp
}
}
}

// If conflicts were detected, return an error
if len(conflicts) > 0 {
return Config{}, fmt.Errorf("resource conflicts detected:\n - %s\n\nPlease ensure each source, authService, tool, toolset and prompt has a unique name across all files", strings.Join(conflicts, "\n - "))
return Config{}, fmt.Errorf("resource conflicts detected:\n - %s\n\nPlease ensure each source, authService, tool, prompt and group has a unique name across all files", strings.Join(conflicts, "\n - "))
}

// Ensure only one authService has mcpEnabled = true
Expand Down
Loading
Loading