Skip to content

refactor(sdk): drop unreachable kit.AgentConfig surface#67

Merged
ezynda3 merged 3 commits into
masterfrom
refactor/drop-agentconfig
Jun 18, 2026
Merged

refactor(sdk): drop unreachable kit.AgentConfig surface#67
ezynda3 merged 3 commits into
masterfrom
refactor/drop-agentconfig

Conversation

@ezynda3

@ezynda3 ezynda3 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Removes the public kit.AgentConfig type and its unreachable conversion helper, replacing the one missing capability it carried (custom debug logger) with a proper Options field + WithDebugLogger functional option. After this PR internal/agent.AgentConfig is purely internal and can be refactored without breaking the SDK contract.

Supersedes and closes #66.

Background

kit.AgentConfig (pkg/kit/types.go) was documented as the "low-level / advanced consumer" path for agent construction. Its conversion helper, toInternal(), was unexported. Neither kit.New(*Options) nor kit.NewAgent(...Option) accepts an AgentConfig, so no SDK consumer outside pkg/kit could populate or use it in any way.

The only call sites were:

  • pkg/kit/agent_config_internal_test.go — the dedicated same-package test exercising toInternal() directly.
  • pkg/kit/types_test.go — two regression tests verifying the struct can be populated without importing charm.land/fantasy.

Both rely entirely on same-package access. From the outside the type, the converter, the godoc cross-references in mcp_tasks.go / DebugLogger, and the README entry have no consumer-visible function — but they do enlarge the SDK's stability contract: every AgentConfig field is a public shape the internal agent layer can't refactor freely.

Changes (commit 1 — feat: WithDebugLogger)

The companion commit adds Options.DebugLogger + WithDebugLogger so the last functional capability AgentConfig was documented to enable — installing a custom debug logger — is reachable through the supported construction path.

  • pkg/kit/kit.go: new Options.DebugLogger DebugLogger field. When non-nil it is used directly and the Debug bool is ignored; the supplied logger's IsDebugEnabled() controls whether downstream code emits messages.
  • pkg/kit/options.go: new WithDebugLogger(l DebugLogger) Option.
  • internal/kitsetup/setup.go: new AgentSetupOptions.DebugLogger; SetupAgent's logger selection switches on it so a caller-supplied logger wins unconditionally; otherwise the existing Debug + UseBufferedLogger branch picks the built-in implementation. No behaviour change when nil.
  • pkg/kit/viper_isolation_test.go: TestWithDebugLoggerPlumbing + TestWithDebugLoggerNilClears.
  • pkg/kit/README.md: helper inventory updated.

Changes (commit 2 — refactor: remove AgentConfig)

With debug-logger wiring in place, the public type is removed:

  • pkg/kit/types.go: drop the AgentConfig struct and toInternal() method. Drop the now-unused internal/agent and internal/tools imports. DebugLogger's godoc rewritten to point at Options.DebugLogger / WithDebugLogger.
  • pkg/kit/agent_config_internal_test.go: deleted (208 LOC). It exercised toInternal() directly; with the method gone the test has no subject.
  • pkg/kit/types_test.go:
    • TestAgentConfigNoFantasyImportTestOptionsNoFantasyImport, rewritten against Options (SystemPrompt, MaxSteps, Streaming, Tools, ExtraTools, DisableCoreTools, OnMCPServerLoaded).
    • TestAgentConfigToolWrapperSignatureTestToolSliceSignature. The original asserted ToolWrapper field semantics; that capability migrates to the hook system (OnBeforeToolCall / OnAfterToolResult), already covered by hooks_test.go, so the assertion is dropped with a pointer in the godoc. The new test still pins that []kit.Tool is the user-visible slice type for every tool-related SDK surface — the no-fantasy-import contract the original guarded.
  • pkg/kit/mcp_tasks.go: MCPTaskConfig godoc updated to stop referencing AgentConfig. The type itself stays — it is still emitted through Options.MCPTask* fields and used as the engine-facing config type.
  • pkg/kit/README.md: kit.AgentConfig removed from the type inventory.

internal/agent.AgentConfig is untouched and remains the internal construction shape. With the public type gone the internal one can evolve freely without breaking the SDK contract.

Net surface impact

  • Removed: kit.AgentConfig (struct + 14 fields) — no external consumer existed.
  • Added: Options.DebugLogger, kit.WithDebugLogger.
  • Renamed (test only, same regression coverage): TestAgentConfigNoFantasyImportTestOptionsNoFantasyImport; TestAgentConfigToolWrapperSignatureTestToolSliceSignature.
  • Diff: +44 / −362 across 5 files (commit 2) + the additive WithDebugLogger commit.

Migration

There is no real-world migration because no consumer can currently reach AgentConfig from outside pkg/kit. Hypothetical reachers (e.g. forks that vendored their own constructor) map cleanly onto Options:

Old (AgentConfig) New (Options)
ModelConfig Model + ProviderAPIKey / ProviderURL / sampling params
MCPConfig MCPConfig
SystemPrompt SystemPrompt (or WithSystemPrompt)
MaxSteps MaxSteps
StreamingEnabled Streaming *bool (or WithStreaming)
AuthHandler MCPAuthHandler
TokenStoreFactory MCPTokenStoreFactory
CoreTools Tools (or WithTools)
DisableCoreTools DisableCoreTools
ExtraTools ExtraTools (or WithExtraTools)
ToolWrapper Kit.OnBeforeToolCall / Kit.OnAfterToolResult (hook system)
OnMCPServerLoaded OnMCPServerLoaded
DebugLogger DebugLogger (or WithDebugLogger) — added in this PR
MCPTaskConfig MCPTaskMode / MCPTaskTimeout / MCPTaskTTL / MCPTaskPollInterval / MCPTaskMaxPollInterval / MCPTaskProgress

Verification

  • go build ./pkg/... ./internal/... ./cmd/... — clean
  • go vet ./pkg/... ./internal/... ./cmd/... — clean
  • go test -race -timeout 300s ./... — all packages pass

Notes

  • kit.DebugLogger and tools.DebugLogger are structurally identical (LogDebug(string) / IsDebugEnabled() bool), so the SDK value flows into the internal field without a conversion.
  • The kit.Tool alias to fantasy.AgentTool is unchanged. It complies with the AGENTS.md no-dependency-name-leakage rule (the alias is kit.Tool; the dependency name appears nowhere in identifiers or godoc).
  • Closes feat(sdk): add Options.DebugLogger and WithDebugLogger option #66.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added WithDebugLogger option to supply custom debug loggers, allowing users to route engine and MCP debug output into their own logging infrastructure. Custom loggers take precedence over the built-in Debug flag.
  • Documentation

    • Updated SDK documentation to reflect the new DebugLogger option and interface, including usage examples and implementation guidance for custom loggers.

Today the SDK exposes a DebugLogger interface (pkg/kit/types.go) but no
public path to install one — the only consumer of the field is the
unexported kit.AgentConfig.toInternal() method, which itself is not
reachable from outside the package. As a result, embedders that want to
forward Kit's low-level engine + MCP tool plumbing debug output into
their own logging system (slog, zap, charm/log, an in-app TUI panel,
etc.) have no option but the on/off Debug bool, which always installs
the built-in SimpleDebugLogger / BufferedDebugLogger.

This change closes that gap on the supported Options / functional-option
construction path:

- pkg/kit/kit.go: add Options.DebugLogger DebugLogger. When non-nil it
  is used directly and the Debug bool is ignored; the supplied logger's
  IsDebugEnabled() controls whether downstream code emits messages.
- pkg/kit/options.go: add WithDebugLogger(l DebugLogger) Option.
- internal/kitsetup/setup.go: add AgentSetupOptions.DebugLogger and
  switch SetupAgent's logger selection so the caller-supplied logger
  wins unconditionally; otherwise the existing Debug + UseBufferedLogger
  branch picks the built-in implementation. No behaviour change when
  DebugLogger is nil.
- pkg/kit/kit.go: wire opts.DebugLogger into setupOpts so the New()
  path threads it through.
- pkg/kit/viper_isolation_test.go: add TestWithDebugLoggerPlumbing and
  TestWithDebugLoggerNilClears covering the option-to-field contract
  and later-options-override semantics consistent with the other With*
  helpers.
- pkg/kit/README.md: list WithDebugLogger in the helper inventory.

Notes:
- kit.DebugLogger and tools.DebugLogger are structurally identical
  (LogDebug(string) / IsDebugEnabled() bool), so the SDK value flows
  into the internal field without a conversion.
- This is purely additive on the SDK surface and does not touch
  kit.AgentConfig — that field already carried a DebugLogger, but the
  AgentConfig path is unreachable from outside the package today.
@mark-iii-labs-huly

Copy link
Copy Markdown

Connected to Huly®: KIT-68

kit.AgentConfig (pkg/kit/types.go) and its toInternal converter were
exposed as the documented "low-level / advanced consumer" path for
agent construction, but the converter was unexported and not wired
into any public constructor — neither New(*Options) nor NewAgent(...Option)
accept an AgentConfig. The only call sites were the dedicated
agent_config_internal_test.go (same-package internal test) and two
fantasy-import regression tests in types_test.go.

Net effect today: no SDK consumer outside pkg/kit can populate or use
kit.AgentConfig in any way. The type, the converter, the dedicated
test file, and a chain of godoc cross-references all exist purely for
their own sake — they don't enlarge what consumers can do, but they
do enlarge the SDK's stability contract (every field becomes a public
shape the internal agent layer can't refactor freely).

The companion PR added Options.DebugLogger + WithDebugLogger so the
last functional capability AgentConfig was documented to enable —
installing a custom debug logger — is reachable through the supported
construction path. With that wired, AgentConfig has no remaining
purpose.

Changes:

- pkg/kit/types.go: remove the AgentConfig struct and its toInternal()
  method. Drop the now-unused internal/agent and internal/tools
  imports. Update the DebugLogger godoc to point at Options.DebugLogger
  and WithDebugLogger instead of AgentConfig.
- pkg/kit/agent_config_internal_test.go: deleted (208 LOC). It exercised
  the unexported toInternal() method directly; with the method gone
  the test has no subject.
- pkg/kit/types_test.go: rename TestAgentConfigNoFantasyImport to
  TestOptionsNoFantasyImport and rewrite it against Options
  (SystemPrompt, MaxSteps, Streaming, Tools, ExtraTools,
  DisableCoreTools, OnMCPServerLoaded). The original test also asserted
  ToolWrapper field semantics; that capability migrates to the hook
  system (OnBeforeToolCall / OnAfterToolResult), already covered by
  hooks_test.go, so the assertion is dropped with a pointer in the
  godoc. TestAgentConfigToolWrapperSignature replaced by
  TestToolSliceSignature, which still pins that []kit.Tool is the
  user-visible slice type for every tool-related SDK surface — the
  no-fantasy-import contract the original test guarded.
- pkg/kit/mcp_tasks.go: update the MCPTaskConfig godoc to stop
  referencing AgentConfig. MCPTaskConfig stays — it is still emitted
  through Options.MCPTask* fields and used as the engine-facing
  config type.
- pkg/kit/README.md: drop the kit.AgentConfig line from the type
  inventory.

internal/agent.AgentConfig is untouched and remains the internal
construction shape. With the public type gone the internal one can
evolve freely without breaking the SDK contract.

Verification:
- go build ./pkg/... ./internal/... ./cmd/... — clean
- go vet ./pkg/... ./internal/... ./cmd/... — clean
- go test -race -timeout 300s ./... — all packages pass
@ezynda3 ezynda3 force-pushed the refactor/drop-agentconfig branch from 2efc28d to 276c787 Compare June 18, 2026 10:45
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0543f18c-bb0d-456d-b422-635ab554df56

📥 Commits

Reviewing files that changed from the base of the PR and between 888c6c7 and 0bbccbb.

📒 Files selected for processing (12)
  • README.md
  • internal/kitsetup/setup.go
  • pkg/kit/README.md
  • pkg/kit/agent_config_internal_test.go
  • pkg/kit/kit.go
  • pkg/kit/mcp_tasks.go
  • pkg/kit/options.go
  • pkg/kit/types.go
  • pkg/kit/types_test.go
  • pkg/kit/viper_isolation_test.go
  • www/pages/sdk/options.md
  • www/pages/sdk/overview.md
💤 Files with no reviewable changes (1)
  • pkg/kit/agent_config_internal_test.go

📝 Walkthrough

Walkthrough

Adds Options.DebugLogger field and WithDebugLogger functional option to the kit SDK. The logger is wired through New() into AgentSetupOptions and takes unconditional precedence over the Debug bool in SetupAgent. Removes MCPTaskConfig.toToolsConfig() adapter and the agent_config_internal_test.go file. Tests and documentation are updated throughout.

Changes

WithDebugLogger option end-to-end

Layer / File(s) Summary
Public Options.DebugLogger field and WithDebugLogger option
pkg/kit/types.go, pkg/kit/kit.go, pkg/kit/options.go
DebugLogger import block updated; Options struct gains a DebugLogger field with precedence docs; WithDebugLogger(l DebugLogger) Option is introduced as a new functional option.
AgentSetupOptions.DebugLogger and SetupAgent precedence
internal/kitsetup/setup.go, pkg/kit/kit.go
AgentSetupOptions gains a DebugLogger field; SetupAgent's logger selection becomes a switch that uses the caller-supplied logger unconditionally when non-nil, otherwise falls back to the debugEnabled/buffered branch; New() threads opts.DebugLogger into setupOpts.
MCPTaskConfig.toToolsConfig() removal and AgentConfig test deletion
pkg/kit/mcp_tasks.go, pkg/kit/agent_config_internal_test.go
MCPTaskConfig.toToolsConfig() adapter method deleted; doc comment updated. agent_config_internal_test.go removed entirely, taking TestAgentConfigToInternal and its fakeAuthHandler/fakeDebugLogger helpers with it.
Option plumbing tests and types_test.go rewrite
pkg/kit/viper_isolation_test.go, pkg/kit/types_test.go
TestWithDebugLoggerPlumbing and TestWithDebugLoggerNilClears added; TestAgentConfigNoFantasyImport replaced with TestOptionsNoFantasyImport; TestToolSliceSignature added.
README and www documentation
README.md, pkg/kit/README.md, www/pages/sdk/options.md, www/pages/sdk/overview.md
WithDebugLogger added to option inventories; DebugLogger field added to Options example; Debug precedence clarified; kit.AgentConfig removed from re-exported types; new "Custom debug logger" section with slog forwarding example added.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • mark3labs/kit#32: Introduced AgentConfig.toInternal() DebugLogger propagation coverage in agent_config_internal_test.go, which this PR deletes entirely.
  • mark3labs/kit#42: Modified the same AgentSetupOptions struct and SetupAgent function in internal/kitsetup/setup.go, making its debugEnabled logic directly adjacent to the new DebugLogger precedence switch added here.

Poem

🐰 A logger was lost in the Options abyss,
No path to install it — something was amiss!
Now WithDebugLogger hops into the chain,
And SetupAgent switches with elegant gain.
The rabbit says: route your logs, don't despair,
Debug flows freely — slog, zap, or thin air! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main objective of this PR: removing the unreachable kit.AgentConfig surface from the SDK. This is confirmed as the primary focus in the PR summary.
Linked Issues check ✅ Passed The PR successfully implements the core requirements from issue #66: adds Options.DebugLogger field, implements WithDebugLogger option, wires the logger through setup layers, adds test coverage, and updates documentation.
Out of Scope Changes check ✅ Passed The PR includes removal of kit.AgentConfig and agent_config_internal_test.go beyond the stated scope of issue #66, but this aligns with the explicit PR objective to 'drop unreachable kit.AgentConfig surface'.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/drop-agentconfig

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 and usage tips.

- README.md: add WithDebugLogger to the functional-options helper list
- pkg/kit/README.md: expand the Debug row and add a DebugLogger row in
  the Options field summary
- www/pages/sdk/overview.md: add WithDebugLogger to the helpers table
  with a note that it overrides WithDebug when set
- www/pages/sdk/options.md: surface DebugLogger in the example, expand
  the Debug field description, add a DebugLogger row to the Core
  fields table, and add a "Custom debug logger" section with the
  interface signature and a log/slog adapter example
@ezynda3

ezynda3 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ezynda3 ezynda3 merged commit bd56f4a into master Jun 18, 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.

1 participant