Skip to content

feat(pkg/kit): expose runtime add/remove of native Go tools (#74)#75

Merged
ezynda3 merged 3 commits into
masterfrom
feat/74-runtime-native-tools
Jun 25, 2026
Merged

feat(pkg/kit): expose runtime add/remove of native Go tools (#74)#75
ezynda3 merged 3 commits into
masterfrom
feat/74-runtime-native-tools

Conversation

@ezynda3

@ezynda3 ezynda3 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Description

This PR exposes session-level mutation of the native Go tool set on a live *Kit, closing the gap between native tools and the already-runtime-mutable MCP / skill subsystems.

Before this change, embedders could only add native tools at construction time (Options.Tools / Options.ExtraTools) or for a single call via PromptOptions.ExtraTools, which is reverted immediately after the call. Rebuilding the host to swap toolsets loses session state, MCP connections, and the composed system prompt.

After this change, native tools can be added, removed, replaced, and read back at runtime:

host.AddTools(crmTools...)
host.RemoveTools("crm_search_contacts", "crm_create_deal")
host.SetExtraTools(activeTools...)
extra := host.GetExtraTools()

AddTools is additive with last-write-wins replacement by tool name. RemoveTools is atomic and returns an error listing any missing names without changing the tool set. Core tools and MCP tools are unaffected. The new methods share the existing promptOptsMu (now an RWMutex) so concurrent reads are safe and writes are serialized.

Fixes #74

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactor

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the README / relevant documentation
  • New and existing unit tests pass locally with my changes (go test -race ./pkg/kit/...)

Additional Information

Files changed

  • pkg/kit/kit.go — adds AddTools, RemoveTools, SetExtraTools, and GetExtraTools; converts promptOptsMu to sync.RWMutex; locks ReloadExtensions tool swap.
  • pkg/kit/tools_test.go — adds regression and concurrency tests.
  • README.md — documents the new runtime native-tool API.

Backward compatibility

Purely additive. No existing signatures or behavior are changed.

Summary by CodeRabbit

  • New Features
    • Added runtime management for native Go tools, including adding, replacing, removing, and replacing the full tool set while the host is running.
    • Added a way to view the currently configured extra tools.
  • Bug Fixes
    • Tool changes are now applied safely and consistently, with removals failing atomically if any requested tool name is missing.
    • Updates take effect on the next model step, improving predictability during live changes.
  • Documentation
    • Expanded the Go SDK docs with guidance on live tool updates and expected behavior.

- Add Kit.AddTools, RemoveTools, SetExtraTools, and GetExtraTools

- Make native extra tools mutable at runtime under promptOptsMu

- Convert promptOptsMu to sync.RWMutex for concurrent reads

- Update ReloadExtensions to hold the lock when swapping extension tools

- Add unit tests for add/remove/replace, atomic removal, and concurrency

- Document the new API in README.md

Fixes #74
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ezynda3, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 38 minutes and 14 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 19f71e41-2eaa-4aa9-a392-a0381570a4fb

📥 Commits

Reviewing files that changed from the base of the PR and between b4ecef6 and 4bbc204.

📒 Files selected for processing (5)
  • README.md
  • pkg/kit/kit.go
  • pkg/kit/tools_test.go
  • www/pages/sdk/options.md
  • www/pages/sdk/overview.md
📝 Walkthrough

Walkthrough

Added live native-tool mutation APIs to Kit: add/replace, atomic removal, wholesale replacement, and snapshot reads. Extension reloads now use the same tool lock, and the README and tests describe and verify the runtime behavior.

Changes

Runtime Native Tool Mutation

Layer / File(s) Summary
Tool mutation API and locking
pkg/kit/kit.go
Kit gains AddTools, RemoveTools, SetExtraTools, and GetExtraTools; promptOptsMu becomes an RWMutex; removal errors report missing names in sorted order.
Extension reload synchronization
pkg/kit/kit.go
ReloadExtensions wraps the agent's extra-tool update with promptOptsMu locking.
Docs and runtime tests
README.md, pkg/kit/tools_test.go
The README documents runtime native-tool mutation semantics, and the new tests cover add/replace, atomic remove failures, wholesale replacement, and concurrent mutations.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

A bunny hopped through tool-time glow,
With AddTools bloom and RemoveTools snow.
I twitch my nose at locks so tight,
And nibble bugs away at night.
🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: runtime add/remove of native Go tools on Kit.
Linked Issues check ✅ Passed The PR implements the requested live Kit APIs for add, remove, replace, and readback of extra tools, matching #74.
Out of Scope Changes check ✅ Passed The README updates, tests, and mutex/concurrency changes directly support the new runtime tool-mutation feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/74-runtime-native-tools

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mark-iii-labs-huly

Copy link
Copy Markdown

Connected to Huly®: KIT-76

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
pkg/kit/tools_test.go (1)

401-405: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the remaining tool names, not just the count.

A bug that leaves some even-numbered tools and drops the same number of odd-numbered tools would still pass this test.

Proposed assertion
 	// Even-numbered tools were removed; odd ones remain.
-	got := host.GetToolNames()
-	if len(got) != n/2 {
-		t.Errorf("expected %d tools after concurrent mutation, got %d: %v", n/2, len(got), got)
+	got := sortedStrings(host.GetToolNames())
+	want := make([]string, 0, n/2)
+	for i := 1; i < n; i += 2 {
+		want = append(want, fmt.Sprintf("tool-%d", i))
+	}
+	if !slices.Equal(got, want) {
+		t.Errorf("expected odd-numbered tools after concurrent mutation, got %v", got)
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/kit/tools_test.go` around lines 401 - 405, The concurrent mutation test
in GetToolNames only checks the total count, so it can miss cases where
even-numbered tools remain and odd-numbered tools are incorrectly removed.
Update the assertion around host.GetToolNames to verify the exact remaining tool
names, not just len(got), by comparing against the expected odd-numbered names
after the removals.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/kit/kit.go`:
- Around line 894-897: The extension reload path is overwriting all extra tools,
so runtime-added native tools are being dropped when ReloadExtensions calls
agent.SetExtraTools. Update the reload flow around m.agent.SetExtraTools in
kit.go to keep extension tools separate from tools added via
AddTools/SetExtraTools, then compose both sets while holding promptOptsMu before
setting them back on the agent. Use the existing m.extRunner.RegisteredTools()
and Agent.SetExtraTools behavior to locate the affected code and preserve the
full combined tool list.
- Around line 262-265: SetExtraTools is passing the caller’s slice through
directly, so later mutations to the original tools slice can փոփոխe the live
tool set outside promptOptsMu. Update Kit.SetExtraTools to snapshot the variadic
tools input before calling m.agent.SetExtraTools, using the existing
SetExtraTools path on Kit/agent so the stored tool list is detached from the
caller’s backing array.
- Around line 180-199: In AddTools in kit.go, duplicate tool names passed in the
same call are not using last-write-wins when cur is empty because the second
loop appends the original tool instead of the final replacement. Update the
merge logic so every name in the tools slice resolves to the last Tool with that
Info().Name, using the existing replacements and seen maps, and ensure the
append path for new names also prefers the replacement entry rather than the
earlier duplicate.
- Around line 217-221: The missing-tool error path in kit.go is inconsistent
when cur is empty because it returns names in caller order without deduping or
sorting. Update the early-return branch in the tool lookup logic to apply the
same normalization used elsewhere in the missing-name handling, so the error
from the relevant function in pkg/kit/kit.go always reports a stable, sorted
list of unique tool names.

In `@pkg/kit/tools_test.go`:
- Around line 291-297: The tests using kit.New are not fully hermetic because
the default tool catalog can still be affected by local config, discovered
skills, and context files. Update the Options passed in the relevant kit.New
calls in tools_test.go to also set SkipConfig, NoSkills, and NoContextFiles
alongside Quiet, NoSession, NoExtensions, and DisableCoreTools so the initial
tool catalog stays empty regardless of local environment or KIT_* settings.

In `@README.md`:
- Around line 931-933: The README example for host.RemoveTools ignores the
returned error even though the surrounding text says missing names should
produce one, so update the snippet to handle or surface that error instead of
discarding it. Keep the example centered on host.RemoveTools and make it safe to
copy by showing the returned error being checked, logged, or otherwise
acknowledged in the sample.

---

Nitpick comments:
In `@pkg/kit/tools_test.go`:
- Around line 401-405: The concurrent mutation test in GetToolNames only checks
the total count, so it can miss cases where even-numbered tools remain and
odd-numbered tools are incorrectly removed. Update the assertion around
host.GetToolNames to verify the exact remaining tool names, not just len(got),
by comparing against the expected odd-numbered names after the removals.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b88132a1-a8c0-4a5f-b647-36b97f6f2ed5

📥 Commits

Reviewing files that changed from the base of the PR and between be71700 and b4ecef6.

📒 Files selected for processing (3)
  • README.md
  • pkg/kit/kit.go
  • pkg/kit/tools_test.go

Comment thread pkg/kit/kit.go
Comment thread pkg/kit/kit.go Outdated
Comment thread pkg/kit/kit.go Outdated
Comment thread pkg/kit/kit.go Outdated
Comment thread pkg/kit/tools_test.go
Comment thread README.md
ezynda3 added 2 commits June 25, 2026 21:19
Address CodeRabbit review on #75:
- Track runtime native tools separately from extension tools so
  ReloadExtensions no longer drops AddTools/SetExtraTools entries;
  recomposeExtraTools rebuilds extension + runtime sets together
- Snapshot the variadic slice in SetExtraTools to detach from the
  caller's backing array
- Make AddTools last-write-wins for duplicate names within one call
- Normalize (dedupe + sort) the RemoveTools missing-name error on the
  empty-set path
- Handle the RemoveTools error in the README example
- Make tool tests hermetic (SkipConfig/NoSkills/NoContextFiles) and
  assert exact remaining names in the concurrency test
- Add a Runtime native tools section to the SDK overview covering
  AddTools, RemoveTools, SetExtraTools, and GetExtraTools semantics
- Cross-link the custom-tools and ExtraTools option to the new section
@ezynda3 ezynda3 merged commit f6d08c7 into master Jun 25, 2026
3 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.

feat: expose runtime add/remove of native Go tools on *Kit (AddTools/RemoveTools/SetExtraTools)

1 participant