[dotnet-port-api] Export reusable skills source types - #1046
Conversation
Port .NET skills source public surface by exposing reusable in-memory, aggregating, delegating, filtering, deduplicating, and caching source types in Go. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new reusable sources currently expose/mutate shared slices (and can panic on nil skills), which can cause incorrect behavior across callers and needs fixes before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR ports and exposes a reusable skills-source composition API in agent/skills, enabling consumers to build skill sources by composing in-memory, aggregating, delegating, filtering, deduplicating, and caching behaviors (aligned with the .NET public surface).
Changes:
- Introduces exported composable
Sourceimplementations inagent/skills/sources.go(aggregating/delegating/filtering/deduplicating/caching, plus exported in-memory concrete type). - Adds focused unit tests covering the new composable sources and caching concurrency behavior.
- Updates the .NET vs Go feature comparison doc to reflect the newly available reusable source composition surface.
File summaries
| File | Description |
|---|---|
| agent/skills/provider.go | Removes internal in-memory/dedup helpers now provided by the reusable sources surface. |
| agent/skills/sources.go | Adds exported, reusable composable skills Source implementations (aggregation, delegation, filtering, deduplication, caching). |
| agent/skills/sources_test.go | Adds tests validating ordering, delegation, filtering, deduplication, and caching concurrency behavior. |
| docs/dotnet-go-sdk-feature-comparison.md | Notes reusable skills source composition support in Go. |
Review details
Suppressed comments (2)
agent/skills/sources.go:229
- deduplicateSkillsByName compacts the input slice in place via skills[:0]. When used by DeduplicatingSource, this can mutate the slice returned by the inner source (including overwriting elements in the inner source’s backing array), producing surprising behavior across calls. Also, nil skills from an inner source would panic when accessing skill.Frontmatter.Name. Allocate a new output slice and defensively skip nil skills.
func deduplicateSkillsByName(skills []*Skill, logger *slog.Logger) []*Skill {
seen := make(map[string]struct{}, len(skills))
deduplicated := skills[:0]
for _, skill := range skills {
resolvedKey := strings.ToLower(skill.Frontmatter.Name)
agent/skills/sources.go:207
- CachingSource currently stores and serves the exact slice instance returned by the inner source (and returns the same slice to callers), so any caller mutation can corrupt the cached value for all future callers. Also, storing time.Now().UTC() strips the monotonic clock reading, making refresh comparisons vulnerable to wall-clock adjustments. Cache a shallow copy, keep monotonic time by using time.Now(), and return a copy from cachedSkillsLocked.
s.mu.Lock()
if err == nil {
s.cached = loaded
s.lastLoaded = time.Now().UTC()
}
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Copilot fix merge conflicts and address PR feedback |
…s-source-types-20260708-alt-26d2f7d2e0ec70cc # Conflicts: # agent/skills/provider.go Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com>
Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com>
Merged
|
|
Scope: public API Changed Go contract: New exported types/constructors in Upstream evidence reviewed:
Result: findings reported (one inline comment). The new source types (
|
There was a problem hiding this comment.
Generated by Go API Consistency Review Agent for #1046 · copilot · auto · 212 AIC · ⌖ 6.62 AIC · ⊞ 9.6K
| return &CachingSource{ | ||
| DelegatingSource: NewDelegatingSource(inner), | ||
| } | ||
| } |
There was a problem hiding this comment.
Upstream evidence: microsoft/agent-framework dotnet/src/Microsoft.Agents.AI/Skills/Decorators/CachingAgentSkillsSourceOptions.cs (commit b7fc23c61, present at the ported commit 00e4d4ffd and still in HEAD) exposes CachingAgentSkillsSourceOptions.RefreshInterval (nullable TimeSpan, default null = never expire) and CacheIsolationKeySelector, both settable via the CachingAgentSkillsSource(AgentSkillsSource, CachingAgentSkillsSourceOptions? options = null) constructor.
Go gap: CachingSource (agent/skills/sources.go) has an internal refreshAfter time.Duration field that gates cache expiry in cachedSkillsLocked, but NewCachingSource(inner Source) *CachingSource takes no options and never sets refreshAfter, so it is permanently zero and this code path is dead. There is no exported way for Go callers to configure cache refresh/expiry or cache-key isolation, unlike the .NET decorator this ports. Either expose an options parameter (e.g. NewCachingSource(inner Source, opts CachingSourceOptions) with a RefreshAfter time.Duration field mirroring RefreshInterval) or remove the unreachable refreshAfter plumbing until it is wired up.
|
Copilot resolve merge conflicts and address PR feedback |
…s-source-types-20260708-alt-26d2f7d2e0ec70cc # Conflicts: # docs/dotnet-go-sdk-feature-comparison.md Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com>
Merged the latest The earlier review feedback is already addressed and still intact after the merge: defensive slice copies in |
Summary
Port the public skills-source composition surface from microsoft/agent-framework#6838 by exposing reusable exported Go source types in
agent/skills.This change adds exported in-memory, aggregating, delegating, filtering, deduplicating, and caching source types, reuses the new in-memory source type from the existing provider path, adds focused tests for the new source surface, and updates the comparison doc to note the reusable source composition support now available in Go.
Upstream commit:
microsoft/agent-framework@00e4d4ffde1fef985095de97cfb5e90b8f7dd462Ported .NET PRs
Breaking Changes
No.
Tests and Examples
go test ./agent/skills/....Notes
upstream-agent-framework/mainatfb4be3bb1f8280b96613cb7ff68377883b22eac6.Closes #450