mirror of
https://github.com/mark3labs/kit.git
synced 2026-06-14 03:30:26 +00:00
399 lines
18 KiB
HTML
399 lines
18 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>SDK Options | Kit</title>
|
|
<meta name="description" content="Configuration options for the Kit Go SDK.">
|
|
<link rel="canonical" href="/sdk/options">
|
|
<link rel="stylesheet" href="/assets/index-Di_r5hA0.css">
|
|
<script type="module" src="/assets/index-BbQ_p9l4.js"></script>
|
|
<script type="application/ld+json">{"@context":"https://schema.org","@type":"TechArticle","headline":"SDK Options","description":"Configuration options for the Kit Go SDK.","url":"https://go-kit.dev/sdk/options","isPartOf":{"@type":"WebSite","name":"Kit","url":"https://go-kit.dev"}}</script>
|
|
</head>
|
|
<body>
|
|
<div id="tome-root"></div>
|
|
<div data-pagefind-body style="display:none"><h1>SDK Options</h1>
|
|
# SDK Options
|
|
|
|
Pass an `Options` struct to `kit.New()` to configure the Kit instance.
|
|
|
|
::: tip
|
|
For simple setups, `kit.NewAgent(ctx, ...Option)` provides functional-options
|
|
helpers (`WithModel`, `WithStreaming`, `Ephemeral`, ...) over the same `Options`
|
|
struct. See [Functional options](/sdk/overview#functional-options-newagent).
|
|
:::
|
|
|
|
Each `kit.New` / `kit.NewAgent` call owns an isolated configuration store, so
|
|
these options never leak between Kit instances in the same process. See
|
|
[Per-instance config isolation](/sdk/overview#per-instance-config-isolation).
|
|
|
|
## Full options reference
|
|
|
|
```go
|
|
host, err := kit.New(ctx, &kit.Options{
|
|
// Model
|
|
Model: "ollama/llama3",
|
|
SystemPrompt: "You are a helpful bot",
|
|
ConfigFile: "/path/to/config.yml",
|
|
|
|
// Behavior
|
|
MaxSteps: 10,
|
|
Streaming: ptrBool(true), // *bool: nil = unset (default true), &false = off
|
|
Quiet: true,
|
|
Debug: true,
|
|
|
|
// Generation parameters (override env/config/per-model defaults)
|
|
MaxTokens: 16384, // 0 = auto-resolve; non-zero suppresses right-sizing
|
|
ThinkingLevel: "medium", // "off", "none", "minimal", "low", "medium", "high"
|
|
Temperature: ptrFloat32(0.2), // pointer so explicit 0.0 != unset
|
|
TopP: nil, // nil = provider/per-model default
|
|
TopK: nil,
|
|
FrequencyPenalty: nil,
|
|
PresencePenalty: nil,
|
|
|
|
// Provider configuration
|
|
ProviderAPIKey: "sk-...", // "" = use config / provider env var
|
|
ProviderURL: "https://proxy.internal/v1", // "" = provider default endpoint
|
|
TLSSkipVerify: false, // only effective when true
|
|
|
|
// Session
|
|
SessionPath: "./session.jsonl",
|
|
SessionDir: "/custom/sessions/",
|
|
Continue: true,
|
|
NoSession: true,
|
|
|
|
// Tools
|
|
Tools: []kit.Tool{...}, // Replace default tool set entirely
|
|
ExtraTools: []kit.Tool{...}, // Add tools alongside defaults
|
|
DisableCoreTools: true, // Use no core tools (0 tools, for chat-only)
|
|
|
|
// Configuration
|
|
SkipConfig: true, // Skip .kit.yml files (viper defaults + env vars still apply)
|
|
|
|
// Compaction
|
|
AutoCompact: true,
|
|
|
|
// Skills
|
|
Skills: []string{"/path/to/skill.md"},
|
|
SkillsDir: "/path/to/skills/",
|
|
NoSkills: true,
|
|
|
|
// Feature toggles
|
|
NoExtensions: true, // disable Yaegi extension loading
|
|
NoContextFiles: true, // disable automatic AGENTS.md loading
|
|
|
|
// Session (advanced)
|
|
SessionManager: myCustomSession, // custom SessionManager implementation
|
|
|
|
// MCP OAuth — both opt-in. Leave MCPAuthHandler nil to disable
|
|
// OAuth entirely (remote MCP 401s bubble up as errors). CLI apps
|
|
// pass kit.NewCLIMCPAuthHandler(); custom UX embedders implement
|
|
// MCPAuthHandler or configure DefaultMCPAuthHandler + OnAuthURL.
|
|
MCPAuthHandler: authHandler, // nil = OAuth disabled
|
|
MCPTokenStoreFactory: func(serverURL string) (kit.MCPTokenStore, error) {
|
|
return myStore(serverURL), nil
|
|
},
|
|
|
|
// In-Process MCP Servers
|
|
InProcessMCPServers: map[string]*kit.MCPServer{
|
|
"docs": mcpSrv, // *server.MCPServer from mcp-go
|
|
},
|
|
})
|
|
```
|
|
|
|
## Options fields
|
|
|
|
### Core
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------|------|---------|-------------|
|
|
| `Model` | `string` | config default | Model string (provider/model format) |
|
|
| `SystemPrompt` | `string` | — | System prompt text or file path |
|
|
| `ConfigFile` | `string` | `~/.kit.yml` | Path to config file |
|
|
| `MaxSteps` | `int` | `0` | Max agent steps (0 = unlimited) |
|
|
| `Streaming` | `*bool` | `nil` | Enable streaming output. `nil` leaves it to the precedence chain (env → config → default `true`); `&true`/`&false` forces it. Pointer so unset is distinct from explicit `false`. |
|
|
| `Quiet` | `bool` | `false` | Suppress output |
|
|
| `Debug` | `bool` | `false` | Enable debug logging |
|
|
|
|
### Generation parameters
|
|
|
|
These fields override the corresponding values from `.kit.yml` / `KIT_*`
|
|
environment variables. Leaving a field at its zero/nil value lets the
|
|
precedence chain resolve a value (`KIT_*` env → config file → per-model
|
|
defaults from `modelSettings`/`customModels` → an 8192 SDK floor for
|
|
`MaxTokens` (matching the CLI `--max-tokens` default) and provider-level
|
|
defaults for samplers).
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------|------|---------|-------------|
|
|
| `MaxTokens` | `int` | auto-resolved | Max output tokens per response. `0` = auto-resolve; non-zero suppresses automatic right-sizing (same semantics as `--max-tokens`). |
|
|
| `ThinkingLevel` | `string` | auto-resolved | Reasoning effort: `"off"`, `"none"`, `"minimal"`, `"low"`, `"medium"`, `"high"`. `""` falls through to config/env/per-model/`"off"`. |
|
|
| `Temperature` | `*float32` | — | Sampling randomness. Pointer type so explicit `0.0` is distinguishable from "unset". |
|
|
| `TopP` | `*float32` | — | Nucleus sampling cutoff. `nil` leaves provider/per-model default. |
|
|
| `TopK` | `*int32` | — | Top-K sampling limit. `nil` leaves provider/per-model default. |
|
|
| `FrequencyPenalty` | `*float32` | — | OpenAI-family frequency penalty. `nil` leaves provider default. |
|
|
| `PresencePenalty` | `*float32` | — | OpenAI-family presence penalty. `nil` leaves provider default. |
|
|
|
|
Pointer-typed fields (`Streaming` and the samplers) are populated via tiny helpers:
|
|
|
|
```go
|
|
func ptrBool(v bool) *bool { return &v }
|
|
func ptrFloat32(v float32) *float32 { return &v }
|
|
```
|
|
|
|
These fields eliminate the need for `viper.Set()` calls before `kit.New()`
|
|
when embedding Kit as a library.
|
|
|
|
### Provider configuration
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------|------|---------|-------------|
|
|
| `ProviderAPIKey` | `string` | — | API key used to authenticate with the provider. `""` falls back to config / provider-specific env var (e.g. `ANTHROPIC_API_KEY`). When set, it takes precedence over config and env values on this instance's store. |
|
|
| `ProviderURL` | `string` | — | Override the provider endpoint (e.g. LiteLLM, vLLM, Azure OpenAI, internal proxy). `""` = provider default. |
|
|
| `TLSSkipVerify` | `bool` | `false` | Disable TLS certificate verification on the provider HTTP client. Only effective when `true`; to force-disable, use config file or env var instead. For self-signed dev certs only. |
|
|
|
|
### Session
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------|------|---------|-------------|
|
|
| `SessionPath` | `string` | — | Open a specific session file |
|
|
| `SessionDir` | `string` | — | Base directory for session discovery |
|
|
| `Continue` | `bool` | `false` | Resume most recent session |
|
|
| `NoSession` | `bool` | `false` | Ephemeral mode (no persistence) |
|
|
| `SessionManager` | `SessionManager` | — | Custom session backend (advanced) |
|
|
|
|
### Tools & extensions
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------|------|---------|-------------|
|
|
| `Tools` | `[]Tool` | — | Replace the entire default tool set |
|
|
| `ExtraTools` | `[]Tool` | — | Additional tools alongside core/MCP/extension tools |
|
|
| `DisableCoreTools` | `bool` | `false` | Use no core tools (0 tools, for chat-only) |
|
|
| `NoExtensions` | `bool` | `false` | Disable Yaegi extension loading |
|
|
| `NoContextFiles` | `bool` | `false` | Disable automatic AGENTS.md loading |
|
|
|
|
### Skills & configuration
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------|------|---------|-------------|
|
|
| `SkipConfig` | `bool` | `false` | Skip `.kit.yml` file loading (viper defaults + env vars still apply) |
|
|
| `Skills` | `[]string` | — | Explicit skill files/dirs to load |
|
|
| `SkillsDir` | `string` | — | Override default skills directory |
|
|
| `NoSkills` | `bool` | `false` | Disable skill loading entirely |
|
|
|
|
These fields only control the **initial** skill and context-file set picked
|
|
up by `New()`. To add, remove, or replace skills and `AGENTS.md`-style
|
|
context files at runtime (e.g. per user or per session), use the
|
|
`AddSkill` / `LoadAndAddSkill` / `RemoveSkill` / `SetSkills` and
|
|
`AddContextFile` / `AddContextFileContent` / `RemoveContextFile` /
|
|
`SetContextFiles` methods on `*kit.Kit`. See
|
|
[Runtime skills and context files](/sdk/overview#runtime-skills-and-context-files).
|
|
|
|
### Compaction & MCP
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------|------|---------|-------------|
|
|
| `AutoCompact` | `bool` | `false` | Auto-compact when near context limit |
|
|
| `CompactionOptions` | `*CompactionOptions` | — | Configuration for auto-compaction |
|
|
| `MCPAuthHandler` | `MCPAuthHandler` | — | OAuth handler for remote MCP servers. `nil` disables OAuth (servers returning 401 fail with the authorization-required error). See [MCP OAuth](#mcp-oauth-authorization) below. |
|
|
| `MCPTokenStoreFactory` | `func` | — | Custom OAuth token storage for MCP servers (default: JSON file in `$XDG_CONFIG_HOME/.kit/mcp_tokens.json`). |
|
|
| `InProcessMCPServers` | `map[string]*MCPServer` | — | In-process mcp-go servers (no subprocess) |
|
|
| `MCPTaskMode` | `map[string]MCPTaskMode` | — | Per-server override for task-augmented `tools/call`. Keys are server names; missing entries fall back to the `tasksMode` field of the matching `MCPServerConfig`. See [MCP Tasks](#mcp-tasks). |
|
|
| `MCPTaskTimeout` | `time.Duration` | `15m` | Maximum wall-clock to wait for a task to reach a terminal state. Independent of any per-call context deadline. |
|
|
| `MCPTaskTTL` | `time.Duration` | — | TTL hint sent in `TaskParams` for every task-augmented call. Zero omits the field and lets the server pick. |
|
|
| `MCPTaskPollInterval` | `time.Duration` | `1s` | Fallback interval between `tasks/get` requests when the server does not suggest one. |
|
|
| `MCPTaskMaxPollInterval` | `time.Duration` | `5s` | Cap on the polling interval (a server-supplied `pollInterval` can otherwise grow without bound). |
|
|
| `MCPTaskProgress` | `MCPTaskProgressHandler` | — | Optional callback invoked once when a task is accepted and on every observed status transition. The final invocation always carries a terminal status. |
|
|
|
|
## MCP OAuth Authorization
|
|
|
|
When a remote MCP server (SSE or Streamable HTTP) requires OAuth, Kit runs
|
|
the full authorization flow (dynamic client registration → PKCE → user
|
|
consent → token exchange → token persistence) but delegates the **user-facing
|
|
step** — displaying the authorization URL and receiving the callback — to
|
|
an `MCPAuthHandler`.
|
|
|
|
The SDK is deliberately inert when `MCPAuthHandler` is `nil`: it does **not**
|
|
auto-construct a default handler, bind a local TCP port, or open a browser.
|
|
This keeps library, daemon, and web-app embedders free of surprise I/O.
|
|
Consumers opt in by passing a handler explicitly.
|
|
|
|
| Building block | When to use |
|
|
|---|---|
|
|
| `MCPAuthHandler = nil` (default) | OAuth disabled. Remote MCP servers requiring auth fail with a clear error. Correct for libraries, daemons, and web apps. |
|
|
| `kit.NewCLIMCPAuthHandler()` | CLI/TUI apps. Opens the system browser, prints status to stderr (or via `NotifyFunc`), runs a localhost callback server. Used by the `kit` binary. |
|
|
| `kit.NewDefaultMCPAuthHandler()` + `OnAuthURL` | Custom UX. Use the SDK's port reservation and callback server; plug in your own presentation via the `OnAuthURL(serverName, authURL)` closure. |
|
|
| Implement `kit.MCPAuthHandler` directly | Full control. No localhost binding — e.g. return the URL from an HTTP endpoint and have the consumer POST the callback URL back. |
|
|
|
|
**CLI-style embedder:**
|
|
|
|
```go
|
|
authHandler, err := kit.NewCLIMCPAuthHandler()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer authHandler.Close() // release the reserved port
|
|
|
|
host, _ := kit.New(ctx, &kit.Options{
|
|
MCPAuthHandler: authHandler,
|
|
})
|
|
```
|
|
|
|
**Custom UX embedder (TUI modal, QR code, web redirect, etc.):**
|
|
|
|
```go
|
|
authHandler, _ := kit.NewDefaultMCPAuthHandler()
|
|
authHandler.OnAuthURL = func(serverName, authURL string) {
|
|
// No browser or terminal assumptions — render however you like.
|
|
myUI.ShowAuthPrompt(serverName, authURL)
|
|
}
|
|
defer authHandler.Close()
|
|
|
|
host, _ := kit.New(ctx, &kit.Options{
|
|
MCPAuthHandler: authHandler,
|
|
})
|
|
```
|
|
|
|
**Fully custom handler (no local port binding at all):**
|
|
|
|
```go
|
|
type WebAuthHandler struct {
|
|
redirectURI string
|
|
callbacks chan string
|
|
}
|
|
|
|
func (h *WebAuthHandler) RedirectURI() string { return h.redirectURI }
|
|
|
|
func (h *WebAuthHandler) HandleAuth(ctx context.Context, serverName, authURL string) (string, error) {
|
|
// Push the URL to the user's existing browser session via your web app,
|
|
// then block on the callback that your HTTP handler pushes onto the channel.
|
|
h.pushToUserSession(serverName, authURL)
|
|
select {
|
|
case callbackURL := <-h.callbacks:
|
|
return callbackURL, nil
|
|
case <-ctx.Done():
|
|
return "", ctx.Err()
|
|
}
|
|
}
|
|
```
|
|
|
|
::: warning
|
|
`DefaultMCPAuthHandler` with no `OnAuthURL` set will silently drop the
|
|
authorization URL and hang until the 2-minute callback timeout fires. Always
|
|
set `OnAuthURL`, or use a higher-level wrapper like `CLIMCPAuthHandler`.
|
|
:::
|
|
|
|
## MCP Tasks
|
|
|
|
The [MCP Tasks utility](https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/tasks)
|
|
turns a synchronous `tools/call` into a pollable async job: the server
|
|
returns a `taskId` with status `working` immediately, and the client polls
|
|
`tasks/get` / `tasks/result` until the task reaches a terminal state.
|
|
|
|
Kit advertises task support during `initialize` and, by default, augments
|
|
`tools/call` with task metadata only when the server advertises
|
|
`tasks/toolCalls` capability — so any existing MCP server keeps its previous
|
|
synchronous behaviour bit-for-bit. Long-running tools (builds, deployments,
|
|
batch jobs, sub-agent runs) get HTTP/SSE timeout-resistance and clean
|
|
cancellation "for free" once both sides opt in.
|
|
|
|
### Per-server mode
|
|
|
|
```go
|
|
import "time"
|
|
|
|
host, _ := kit.New(ctx, &kit.Options{
|
|
MCPTaskMode: map[string]kit.MCPTaskMode{
|
|
"build-server": kit.MCPTaskModeAlways, // force task-augmented calls
|
|
"chat-server": kit.MCPTaskModeNever, // force synchronous calls
|
|
// any server not in the map honours its `tasksMode` config field
|
|
// (default "auto")
|
|
},
|
|
})
|
|
```
|
|
|
|
| Mode | Behaviour |
|
|
|---|---|
|
|
| `MCPTaskModeAuto` (default) | Augment `tools/call` with `TaskParams` only when the server advertised `tasks/toolCalls`. |
|
|
| `MCPTaskModeNever` | Always issue `tools/call` synchronously, ignoring server capability. |
|
|
| `MCPTaskModeAlways` | Always opt in, even when the server didn't advertise the capability. The server may still respond synchronously. |
|
|
|
|
### Progress callbacks
|
|
|
|
```go
|
|
host, _ := kit.New(ctx, &kit.Options{
|
|
MCPTaskTimeout: 15 * time.Minute, // total wall-clock cap
|
|
MCPTaskTTL: 30 * time.Minute, // server retention hint
|
|
MCPTaskProgress: func(p kit.MCPTaskProgress) {
|
|
log.Printf("%s/%s: %s %s", p.Server, p.TaskID, p.Status, p.Message)
|
|
},
|
|
})
|
|
```
|
|
|
|
The handler fires once when a task is accepted and again on every observed
|
|
status transition. The final call always carries a terminal status
|
|
(`MCPTaskStatusCompleted`, `MCPTaskStatusFailed`, or `MCPTaskStatusCancelled`).
|
|
Do not block in the handler — dispatch long work on a goroutine.
|
|
|
|
### Inspecting and cancelling tasks
|
|
|
|
```go
|
|
tasks, _ := host.ListMCPTasks(ctx, "build-server")
|
|
for _, t := range tasks {
|
|
fmt.Printf("%s: %s (%s)\n", t.TaskID, t.Status, t.StatusMessage)
|
|
}
|
|
|
|
t, _ := host.GetMCPTask(ctx, "build-server", taskID)
|
|
if !t.Status.IsTerminal() {
|
|
_, _ = host.CancelMCPTask(ctx, "build-server", taskID)
|
|
}
|
|
```
|
|
|
|
`Kit.ListMCPTasks`, `Kit.GetMCPTask`, and `Kit.CancelMCPTask` work against any
|
|
loaded MCP server that advertises the corresponding capability.
|
|
`MCPTaskStatus.IsTerminal()` is the canonical check for completion.
|
|
|
|
Context cancellation also works end-to-end: cancelling the `ctx` passed to a
|
|
tool execution triggers a best-effort `tasks/cancel` before the call returns.
|
|
|
|
## Precedence
|
|
|
|
For any given generation or provider field, the effective value is resolved
|
|
in this order (highest priority first):
|
|
|
|
1. `Options.X` (SDK caller)
|
|
2. `KIT_X` environment variable
|
|
3. `.kit.yml` (project-local then `~/.kit.yml`)
|
|
4. Per-model defaults (`modelSettings[provider/model]` or `customModels[...].params`)
|
|
5. Provider-level defaults (e.g. Anthropic's own temperature default)
|
|
6. SDK last-resort floor (currently: `MaxTokens = 8192`, matching the CLI `--max-tokens` default)
|
|
|
|
Sampling params that remain `nil` after the SDK resolution step are left out
|
|
of the provider call entirely, so the LLM library applies its own default.
|
|
|
|
## Tool configuration
|
|
|
|
**`Tools`** replaces ALL default tools (core + MCP + extension). **`ExtraTools`** adds tools alongside the defaults. Use `Tools` to restrict capabilities; use `ExtraTools` to extend them.
|
|
|
|
Create custom tools with `kit.NewTool` — no external dependencies needed:
|
|
|
|
```go
|
|
type LookupInput struct {
|
|
ID string `json:"id" description:"Record ID to look up"`
|
|
}
|
|
|
|
lookupTool := kit.NewTool("lookup", "Look up a record by ID",
|
|
func(ctx context.Context, input LookupInput) (kit.ToolOutput, error) {
|
|
record := db.Find(input.ID)
|
|
return kit.TextResult(record.String()), nil
|
|
},
|
|
)
|
|
|
|
host, _ := kit.New(ctx, &kit.Options{
|
|
ExtraTools: []kit.Tool{lookupTool},
|
|
})
|
|
```
|
|
|
|
See [Overview](/sdk/overview#custom-tools) for full custom tool documentation.</div>
|
|
</body>
|
|
</html> |