Skip to content

feat(go-sdk): add AgentRouter pattern for modular agent organisation Fixes #98#499

Merged
AbirAbbas merged 3 commits intoAgent-Field:mainfrom
dhanadeep6:feat/go-sdk-agent-router
Apr 25, 2026
Merged

feat(go-sdk): add AgentRouter pattern for modular agent organisation Fixes #98#499
AbirAbbas merged 3 commits intoAgent-Field:mainfrom
dhanadeep6:feat/go-sdk-agent-router

Conversation

@dhanadeep6
Copy link
Copy Markdown
Contributor

@dhanadeep6 dhanadeep6 commented Apr 24, 2026

Summary

Adds Router, RouterOptions, and Agent.IncludeRouter to the Go SDK,
bringing it to parity with the Python AgentRouter and TypeScript AgentRouter
already in the repo.

Files changed

File Change
sdk/go/agent/router.go New — complete implementation
sdk/go/agent/router_test.go New — 11 integration tests

Usage

userRouter := agent.NewRouter()
userRouter.RegisterReasoner("get-profile", getProfileFn,
    agent.WithDescription("Fetch a user by ID"))
userRouter.RegisterSkill("validate-email", validateEmailFn)

a.IncludeRouter(userRouter, agent.RouterOptions{
    Prefix: "users",
    Tags:   []string{"user-management"},
})
// Registers: users.get-profile, users.validate-email

// Nested:
adminRouter := agent.NewRouter()
adminRouter.IncludeRouter(userRouter, agent.RouterOptions{Prefix: "users"})
a.IncludeRouter(adminRouter, agent.RouterOptions{Prefix: "admin"})
// Registers: admin.users.get-profile, admin.users.validate-email

Design notes

  • No new exported types — uses existing HandlerFunc and ReasonerOption
  • withAppendTags (unexported) merges RouterOptions.Tags without clobbering per-handler WithReasonerTags
  • Agent.IncludeRouter calls existing RegisterReasoner only — DID auth, VC generation, and tracing fire unchanged
  • A Router is a pure immutable tree — safe to mount under multiple prefixes or into multiple agents

Test results

--- PASS: TestRouter_FlatMount
--- PASS: TestRouter_NoPrefix
--- PASS: TestRouter_NestedRouters
--- PASS: TestRouter_DeeplyNested
--- PASS: TestRouter_SharedRouter
--- PASS: TestRouter_EmptyRouter
--- PASS: TestRouter_HandlerFires
--- PASS: TestRouter_WithDescription
--- PASS: TestRouter_WithReasonerTags
--- PASS: TestRouter_RouterOptionsTagsApplied
--- PASS: TestRouter_MultipleMountsOnSameAgent
--- PASS: TestRouter_IssueExample
PASS

Note on go test ./... failures

The sdk/go/harness package has pre-existing failures on Windows that exist
on main before any of my changes. I verified this by running git stash (removing
my files entirely) and running go test ./... — identical failures appeared.

Root causes (none related to this PR):

  • Tests expect Unix binaries (opencode, codex, gemini, claude-code) that
    are not installed in this environment
  • Path separator mismatch: tests hardcode /tmp/... but Windows produces \tmp\...
  • Tests expect executable files at temp paths that don't exist on Windows

All packages except harness pass cleanly:

ok   github.com/Agent-Field/agentfield/sdk/go/agent
ok   github.com/Agent-Field/agentfield/sdk/go/ai
ok   github.com/Agent-Field/agentfield/sdk/go/client
ok   github.com/Agent-Field/agentfield/sdk/go/did
ok   github.com/Agent-Field/agentfield/sdk/go/types
FAIL github.com/Agent-Field/agentfield/sdk/go/harness  ← pre-existing, not introduced by this PR

Adds Router, RouterOptions, and Agent.IncludeRouter to the Go SDK,
mirroring the Python AgentRouter and TypeScript AgentRouter.

- NewRouter() groups reasoners and skills under a namespace
- RegisterReasoner / RegisterSkill accept any existing ReasonerOption
  (WithDescription, WithReasonerTags, etc.) - no new types added
- IncludeRouter mounts a router with dot-separated prefix + tag inheritance
  via a new internal withAppendTags helper that merges without clobbering
- Routers nest to arbitrary depth; same Router safe to reuse across agents
- Agent.IncludeRouter delegates to existing RegisterReasoner so all
  middleware (DID auth, VC generation, tracing) fires unchanged

Files added:
  sdk/go/agent/router.go          core implementation
  sdk/go/agent/router_test.go     11 integration tests
@dhanadeep6 dhanadeep6 requested review from a team and AbirAbbas as code owners April 24, 2026 01:46
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 24, 2026

CLA assistant check
All committers have signed the CLA.

@dhanadeep6 dhanadeep6 changed the title feat(go-sdk): add AgentRouter pattern for modular agent organisation feat(go-sdk): add AgentRouter pattern for modular agent organisation Fixes #98 Apr 24, 2026
@dhanadeep6
Copy link
Copy Markdown
Contributor Author

Hi this is my first time doing this if there is any issues do tell me

@santoshkumarradha
Copy link
Copy Markdown
Member

Hey @dhanadeep6, thank you, could you please click on the CLAassistant tag in the comment above and sign it? Once done we can proceed with the review :D

@dhanadeep6
Copy link
Copy Markdown
Contributor Author

dhanadeep6 commented Apr 25, 2026

@santoshkumarradha done bro

@github-actions
Copy link
Copy Markdown
Contributor

Performance

SDK Memory Δ Latency Δ Tests Status
Go 228 B -19% 0.64 µs -36%

✓ No regressions detected

@github-actions
Copy link
Copy Markdown
Contributor

📊 Coverage gate

Thresholds from .coverage-gate.toml: per-surface ≥ 86%, aggregate ≥ 88%, max per-surface regression ≤ 1.0 pp, max aggregate regression ≤ 0.50 pp.

Surface Current Baseline Δ
control-plane 87.40% 87.30% ↑ +0.10 pp 🟡
sdk-go 91.10% 90.70% ↑ +0.40 pp 🟢
sdk-python 93.63% 93.63% ↑ +0.00 pp 🟢
sdk-typescript 92.63% 92.56% ↑ +0.07 pp 🟢
web-ui 90.03% 90.01% ↑ +0.02 pp 🟢
aggregate 89.06% 89.01% ↑ +0.05 pp 🟡

✅ Gate passed

No surface regressed past the allowed threshold and the aggregate stayed above the floor.

@github-actions
Copy link
Copy Markdown
Contributor

📐 Patch coverage gate

Threshold: 80% on lines this PR touches vs origin/main (from .coverage-gate.toml:thresholds.min_patch).

Surface Touched lines Patch coverage Status
control-plane 0 ➖ no changes
sdk-go 72 97.00%
sdk-python 0 ➖ no changes
sdk-typescript 0 ➖ no changes
web-ui 0 ➖ no changes

✅ Patch gate passed

Every surface whose lines were touched by this PR has patch coverage at or above the threshold.

@AbirAbbas AbirAbbas merged commit 7d3008f into Agent-Field:main Apr 25, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants