Files
kit/examples/sdk/README.md
T
Ed Zynda 7a04bdfeba feat(kit): isolate viper config per Kit instance + add NewAgent (#42)
* feat(kit): isolate viper config per Kit instance + add NewAgent (#40)

- Give each kit.New()/NewAgent() call an isolated *viper.Viper store so
  multiple Kit instances in one process no longer clobber each other's
  config; runtime mutators (SetModel, SetThinkingLevel) touch only the
  owning instance, making subagent spawning and multi-Kit embedding
  race-free
- Thread the per-instance store through internal/config, internal/models
  (ProviderConfig.ConfigStore), internal/kitsetup, and the extension
  runner, with a nil -> process-global fallback so the CLI is unaffected
- Share the global store when Options.CLI != nil to preserve cobra flag
  bindings (also opted in for internal/acpserver)
- Remove viperInitMu; preserve the tri-state IsSet precedence contract
  and sdkDefaultMaxTokens floor
- Add ergonomic NewAgent + functional options (WithModel, WithStreaming,
  Ephemeral, etc.); NewAgent defaults streaming on, opt out via
  WithStreaming(false). New(ctx, *Options) behavior is unchanged
- Add config-isolation regression test and NewAgent/option coverage;
  document NewAgent and per-instance isolation in README

Fixes #40

* docs(sdk): document NewAgent options and per-instance config isolation

- Add "Functional options (NewAgent)" and "Per-instance config isolation"
  sections to the docs site SDK overview, with an options table and a
  "when to use which" constructor comparison
- Cross-reference NewAgent from the SDK options page and correct the now
  per-instance ProviderAPIKey precedence wording
- Document NewAgent + With* helpers and config isolation in pkg/kit/README
  and list NewAgent/Option in the API reference
- Show the NewAgent constructor in the SDK examples getting-started snippet

* fix(kit): correct config loading and isolate ACP sessions

- Isolate each ACP session's config store instead of sharing the global
  viper, preventing per-session SetModel/SetThinkingLevel races; seed the
  root-command flag values (model, thinking-level, provider URL/key) so
  `kit acp -m <model>` is still honored
- Run initConfig for isolated SDK stores by gating on opts.CLI instead of
  v.GetString("model"), which setSDKDefaults always populates and thus
  skipped .kit.yml / KIT_* loading for SDK callers
- Configure KIT_* env overrides unconditionally in initConfig so passing an
  explicit config file no longer disables environment variable support
- Wrap config unmarshal/validate errors with %w to preserve the error chain

* fix(kit): make Options.Streaming a *bool to honor unset

- Change Options.Streaming from bool to *bool so a zero-valued Options no
  longer forces stream=false; New only sets the key when non-nil, letting
  streaming resolve through the precedence chain (env -> config -> default
  true). This also fixes the CLI path, which never set the field
- Mirror the existing sampling-parameter pointer pattern instead of adding
  a separate StreamingSet sentinel, keeping Options internally consistent
- Update WithStreaming/NewAgent, subagent, and ACP callers to the pointer
  form; add regression tests for the nil-default and explicit opt-out paths
- Update SDK docs (README, pkg/kit/README, options page) with the ptrBool
  helper and *bool semantics

* fix(kit): inherit parent provider config in subagents

- Copy the parent's effective provider/runtime config (API key, URL,
  TLS, thinking level, max-tokens, samplers) onto child Options in
  Kit.Subagent. After the per-instance viper isolation, the child's
  isolated store only re-loaded .kit.yml / KIT_*, silently dropping
  config the parent set via programmatic Options or runtime setters
  like SetThinkingLevel
- Preserve the IsSet tri-state for max-tokens and samplers so per-model
  defaults still apply on the child when the parent left them unset
- Add TestInheritProviderConfig covering propagation, unset keys, and
  nil-safety
2026-06-02 14:41:35 +03:00

1.5 KiB

SDK Examples

These examples demonstrate how to use the Kit SDK (pkg/kit) to build agents programmatically in Go.

Examples

basic

Shows core SDK usage: creating a Kit instance, sending prompts, overriding the model, subscribing to events (tool calls, streaming), and session management.

go run ./examples/sdk/basic

scripting

A minimal script-friendly wrapper that takes a prompt from the command line and prints the response — useful for piping and automation.

go run ./examples/sdk/scripting "Explain what this repo does"

crypto-monitor

A background agent that checks Bitcoin and Ethereum prices every 30 minutes and sends desktop notifications via notify-send (dbus). Demonstrates using the SDK for a long-running autonomous task with a single tool.

go run ./examples/sdk/crypto-monitor

# Override the check interval:
CRYPTO_INTERVAL=5m go run ./examples/sdk/crypto-monitor

Getting Started

import kit "github.com/mark3labs/kit/pkg/kit"

host, err := kit.New(ctx, nil)        // uses ~/.kit.yml defaults
defer host.Close()

response, err := host.Prompt(ctx, "Hello!")

Or use the functional-options constructor for quick setups (streaming defaults on):

host, err := kit.NewAgent(ctx,
    kit.WithModel("anthropic/claude-sonnet-4-5-20250929"),
    kit.WithSystemPrompt("You are a helpful assistant."),
    kit.Ephemeral(),
)

See the SDK README for the full API reference.