From 7d288317b2896f7d7b98251ba98b68df96766f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20H=C3=A9ritier?= Date: Sat, 20 Jun 2026 04:04:34 +0000 Subject: [PATCH 1/6] =?UTF-8?q?docs:=20update=20docs=20for=20PR=20#3178=20?= =?UTF-8?q?=E2=80=94=20max=20effort=20tier=20in=20Shift+Tab=20thinking=20c?= =?UTF-8?q?ycle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #3178 fixed the Shift+Tab thinking level cycle to offer the 'max' effort tier on Claude models that support it. Changes: - docs/guides/thinking/index.md: Replace the flat effort-level table with a per-model capability matrix. Correct the Shift+Tab cycle description to include 'max' for Opus 4.7+, Fable 5, Mythos 5; and document that Sonnet 4.6 and Opus 4.6 cycle to 'max' but not 'xhigh'. Update the adaptive-thinking heading and callout to mention Sonnet 4.6. - docs/providers/anthropic/index.md: Change 'Claude Opus 4.6+ only' to 'Claude Opus 4.6+, Sonnet 4.6' in the adaptive/effort-based section; update the coercion note to include Sonnet 4.6. Source: https://github.com/docker/docker-agent/pull/3178 --- docs/guides/thinking/index.md | 27 ++++++++++++++------------- docs/providers/anthropic/index.md | 4 ++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/guides/thinking/index.md b/docs/guides/thinking/index.md index 88308caab..af18b9d48 100644 --- a/docs/guides/thinking/index.md +++ b/docs/guides/thinking/index.md @@ -84,9 +84,9 @@ models: docker-agent auto-adjusts `max_tokens` when you set a thinking budget but leave `max_tokens` at its default. If you set `max_tokens` explicitly, it must be greater than `thinking_budget`. -### Adaptive thinking (Claude Opus 4.6+) +### Adaptive thinking (Opus 4.6+ and Sonnet 4.6) -Newer Claude models support adaptive thinking, where the model decides how much to think. **Claude Opus 4.6, 4.7 and 4.8 only support adaptive thinking** — they reject token-based budgets. Use `adaptive`, `adaptive/`, or a bare effort level — on Anthropic, a bare effort level like `high` is shorthand for adaptive thinking at that effort: +Newer Claude models support adaptive thinking, where the model decides how much to think. **Claude Opus 4.6, 4.7, 4.8, and Sonnet 4.6 only support adaptive thinking** — they reject token-based budgets. Use `adaptive`, `adaptive/`, or a bare effort level — on Anthropic, a bare effort level like `high` is shorthand for adaptive thinking at that effort: ```yaml models: @@ -106,21 +106,22 @@ models: thinking_budget: adaptive/max # adaptive/low | adaptive/medium | adaptive/high | adaptive/xhigh | adaptive/max ``` -**Adaptive effort levels:** +**Adaptive effort levels and per-model support:** -| Level | Description | -| --------- | ------------------------------------------------- | -| `minimal` | Treated as `low` (bare form only). | -| `low` | Minimal thinking; fastest adaptive mode. | -| `medium` | Moderate effort. | -| `high` | Thorough reasoning; default for `adaptive`. | -| `xhigh` | Very high effort (newer models, e.g. Opus 4.7+). | -| `max` | Maximum effort. | +| Level | Opus 4.5 | Sonnet 4.5 / Haiku | Sonnet 4.6 | Opus 4.6 | Opus 4.7 / 4.8 | Fable 5 / Mythos 5 | +| --------- | :------: | :----------------: | :--------: | :------: | :------------: | :----------------: | +| `low` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| `medium` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| `high` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| `xhigh` | — | — | — | — | ✓ | ✓ | +| `max` | — | — | ✓ | ✓ | ✓ | ✓ | + +`minimal` is treated as `low` (bare form only). `high` is the default when `adaptive` is used without an effort level.
Effort strings require adaptive-capable models
-

Every string effort value on Anthropic is sent as adaptive thinking (output_config.effort), which only newer Claude models (Opus 4.6+) accept. For older models like Sonnet 4.5, use an integer token budget instead. Conversely, models that only support adaptive thinking (Opus 4.6, 4.7, 4.8) automatically have token budgets coerced to adaptive (a warning is logged).

+

Every string effort value on Anthropic is sent as adaptive thinking (output_config.effort), which only newer Claude models (Opus 4.6+, Sonnet 4.6) accept. For older models like Sonnet 4.5, use an integer token budget instead. Conversely, models that only support adaptive thinking (Opus 4.6, 4.7, 4.8, Sonnet 4.6) automatically have token budgets coerced to adaptive (a warning is logged).

### Disabling thinking @@ -332,7 +333,7 @@ models: While running in the TUI, press **Shift+Tab** to cycle the thinking effort level for the current model without editing your YAML config: -- The level steps through the model's supported range (model-specific), wrapping around — for example `none → minimal → low → medium → high → none` on OpenAI gpt-5/o-series, `none → minimal → low → medium → high → xhigh → none` on gpt-5.2+, `none → low → medium → high → max → none` on Anthropic Opus 4.6, and `none → low → medium → high → xhigh → none` on Anthropic Opus 4.7+. For older Anthropic models (e.g. Sonnet 4.5) that only accept token budgets, effort-string cycling has no effect — use an integer `thinking_budget` in your YAML config instead. +- The level steps through the model's supported range (model-specific), wrapping around — for example `none → minimal → low → medium → high → none` on OpenAI gpt-5/o-series, `none → minimal → low → medium → high → xhigh → none` on gpt-5.2+, `none → low → medium → high → max → none` on Anthropic Opus 4.6 and Sonnet 4.6, and `none → low → medium → high → xhigh → max → none` on Anthropic Opus 4.7+, Fable 5, and Mythos 5. For older Anthropic models (e.g. Sonnet 4.5) that only accept token budgets, effort-string cycling has no effect — use an integer `thinking_budget` in your YAML config instead. - The current level is shown in the sidebar next to the model name (e.g. `openai/gpt-5 • high`). - This applies as a session override — it is **not** saved to the config file. The next session starts from the level defined in your YAML. - For models that don't support reasoning, and for remote runtimes, Shift+Tab is a no-op and an informational message is displayed. diff --git a/docs/providers/anthropic/index.md b/docs/providers/anthropic/index.md index c018d1e14..df0575c6b 100644 --- a/docs/providers/anthropic/index.md +++ b/docs/providers/anthropic/index.md @@ -116,7 +116,7 @@ models: thinking_budget: 16384 # must be < max_tokens ``` -**Adaptive / effort-based** (Claude Opus 4.6+ only — every string value is sent as adaptive thinking via `output_config.effort`): +**Adaptive / effort-based** (Claude Opus 4.6+, Sonnet 4.6 — every string value is sent as adaptive thinking via `output_config.effort`): ```yaml models: @@ -131,7 +131,7 @@ models: thinking_budget: high # low | medium | high | xhigh | max (same as adaptive/) ``` -On models that reject token-based thinking (Opus 4.6, 4.7, 4.8), an integer budget is automatically coerced to `adaptive` with a logged warning. See the [Thinking / Reasoning guide]({{ '/guides/thinking/' | relative_url }}) for the full cross-provider reference. +On models that reject token-based thinking (Opus 4.6, 4.7, 4.8, Sonnet 4.6), an integer budget is automatically coerced to `adaptive` with a logged warning. See the [Thinking / Reasoning guide]({{ '/guides/thinking/' | relative_url }}) for the full cross-provider reference. ## Interleaved Thinking From 1d0dc12be7327d75b31d2b7d342562d18d2e5d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20H=C3=A9ritier?= Date: Sat, 20 Jun 2026 04:05:32 +0000 Subject: [PATCH 2/6] =?UTF-8?q?docs:=20update=20docs=20for=20PR=20#3171,?= =?UTF-8?q?=20#3174,=20#3176=20=E2=80=94=20embeddedchat,=20RAG=20opt-in,?= =?UTF-8?q?=20optional=20providers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PR #3171 (pkg/embeddedchat): Add 'Headless Embedded Chat' section to docs/guides/go-sdk/index.md documenting the Config, Session, Event types and the Send/Confirm/Restart/Close API with worked examples. - PR #3174 (RAG opt-in): Add 'RAG Toolset (cgo-free builds)' section explaining that pkg/rag must be blank-imported to register the toolset, allowing embedders to omit it and avoid the cgo dependency. - PR #3176 (optional providers): Add 'Optional Provider Build Tags' section listing docker_agent_no_{openai,anthropic,google,bedrock} tags with the major dependency each removes and the Anthropic+Google note. - Add pkg/embeddedchat row to the Core Packages table. Sources: https://github.com/docker/docker-agent/pull/3171 https://github.com/docker/docker-agent/pull/3174 https://github.com/docker/docker-agent/pull/3176 --- docs/guides/go-sdk/index.md | 118 ++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/docs/guides/go-sdk/index.md b/docs/guides/go-sdk/index.md index 9f3afbf14..938c69117 100644 --- a/docs/guides/go-sdk/index.md +++ b/docs/guides/go-sdk/index.md @@ -31,6 +31,7 @@ docker-agent can be used as a Go library, allowing you to build AI agents direct | `pkg/model/provider/*` | Model provider clients | | `pkg/config/latest` | Configuration types | | `pkg/environment` | Environment and secrets | +| `pkg/embeddedchat` | Headless chat session for embedding the agent runtime in a custom UI | | `pkg/tui/components/toolconfirm` | Tool-confirmation policy: `Decision` enum, `BuildPermissionPattern`, key bindings, and rejection-reason presets. Share this instead of copying the permission-pattern logic. | | `pkg/tui/service` | `StaticSessionState` — a `SessionStateReader` with conservative fixed values, for rendering message/tool views outside the full TUI app. Replaces hand-rolled nine-method stubs. | | `pkg/tui/animation` | `Stopper` / `StopView` — animation lifecycle contract. Call `StopAnimation` on views removed from the UI to prevent leaked tick subscriptions. | @@ -45,6 +46,123 @@ When building custom UIs on top of docker-agent's TUI primitives, four packages - **`pkg/tui/animation`** — implement `animation.Stopper` on any view that owns a tick-based animation. Call `StopAnimation` whenever a view is removed from the UI hierarchy to prevent leaked `time.Tick` subscriptions from firing against a dead view. - **`pkg/tui/components/transcript`** — embed the transcript view for displaying conversation history. Use the `Messages()` method to read the current slice of transcript messages (treat as read-only — mutations desync renders). This is useful for host-side tests asserting on chat history, and for persistence layers that need to snapshot conversation state. +## Headless Embedded Chat (`pkg/embeddedchat`) + +`pkg/embeddedchat` is a thin wrapper around the docker-agent runtime that lets you drive an agent from your own UI instead of running docker-agent's Bubble Tea application. It handles runtime construction, event projection, and conversation state, exposing a simple `Send` / `Confirm` / `Restart` / `Close` API. + +### Creating a session + +```go +import ( + "context" + + dagentcfg "github.com/docker/docker-agent/pkg/config" + "github.com/docker/docker-agent/pkg/embeddedchat" +) + +chat, err := embeddedchat.New(ctx, embeddedchat.Config{ + // AgentSource can be a file path, raw YAML bytes, or an OCI reference. + AgentSource: dagentcfg.BytesSource([]byte(agentYAML)), +}) +if err != nil { + return err +} +defer chat.Close() +``` + +### Sending a message and reading events + +`Send` appends the user message to the conversation and returns a channel of `Event` values. Drain the channel until it closes. + +```go +events, err := chat.Send(ctx, "Hello! What can you do?") +if err != nil { + return err +} + +var response strings.Builder +for ev := range events { + switch { + case ev.Text != "": + response.WriteString(ev.Text) + case ev.Tool != nil && ev.Tool.NeedsConfirmation: + // Approve or reject the pending tool call. + chat.Confirm(ctx, dagentruntime.ResumeApproveSession()) + case ev.Tool != nil && ev.Tool.Finished: + fmt.Printf("[tool %s finished]\n", ev.Tool.Def.Name) + case ev.Err != nil: + fmt.Printf("error: %v\n", ev.Err) + case ev.Done: + fmt.Println("\n[turn complete]") + } +} +fmt.Print(response.String()) +``` + +### Restarting the conversation + +To start a fresh conversation without recreating the runtime: + +```go +if err := chat.Restart(); err != nil { + return err +} +``` + +### Event types + +| Field | When set | +| -------------- | ------------------------------------------------------------------------ | +| `Text` | Assistant text delta; accumulate into a string for the full reply. | +| `Tool` | A tool call started, needs confirmation, or finished. | +| `Tool.NeedsConfirmation` | Runtime is blocked until `Confirm` is called. | +| `Tool.Finished` | Tool call completed; `Tool.IsError` is true if it errored. | +| `Err` | A user-facing runtime error; no further content events follow. | +| `Done` | Clean end of turn; no more events. | +| `RuntimeEvent` | The original `runtime.Event` for callers that need the full stream. | + +For advanced use (custom elicitation, raw event inspection), call `chat.Runtime()` to access the underlying `runtime.Runtime` directly. + +## Optional Provider Build Tags + +By default docker-agent includes all four cloud providers (OpenAI, Anthropic, Google, Amazon Bedrock). When embedding docker-agent in your own binary you can compile out unneeded providers — together with their transitive SDK dependencies — to reduce binary size. + +Each provider is gated by a negative build tag prefixed `docker_agent_` to avoid collisions with your own project's tags: + +| Build tag | Provider dropped | Major dependency removed | +| ---------------------------- | ------------------------ | ------------------------------------------------- | +| `docker_agent_no_openai` | OpenAI | `github.com/openai/openai-go` | +| `docker_agent_no_anthropic` | Anthropic | `github.com/anthropics/anthropic-sdk-go` (partial — see note) | +| `docker_agent_no_google` | Google / Vertex AI | `google.golang.org/genai`, Vertex auth stack, and indirectly the Anthropic and OpenAI SDKs via Vertex Model Garden | +| `docker_agent_no_bedrock` | Amazon Bedrock | `github.com/aws/aws-sdk-go-v2` stack (the largest provider dependency tree) | + +To build without Bedrock and OpenAI: + +```bash +go build -tags 'docker_agent_no_bedrock docker_agent_no_openai' ./... +``` + +Requesting a model whose provider was compiled out fails at construction time with a clear `"not compiled into this build"` error. The `dmr` (Docker Model Runner) provider and the rule-based router are always compiled in. + +
+
Anthropic + Google dependency
+

The Google provider's Vertex Model Garden support also imports the Anthropic SDK, so the Anthropic dependency is only fully removed when both docker_agent_no_anthropic and docker_agent_no_google are set.

+
+ +## RAG Toolset (cgo-free builds) + +The RAG toolset (`type: rag`) uses a tree-sitter code parser that requires cgo. When building without cgo — or when you want to drop the cgo dependency entirely — do not import the `pkg/rag` package in your binary. + +By default the RAG toolset is **opt-in**: it is only linked when you blank-import its package: + +```go +import ( + _ "github.com/docker/docker-agent/pkg/rag" // register RAG toolset +) +``` + +Without this import, a config that declares `type: rag` fails with a "toolset type not registered" error at startup. If your application does not use RAG, simply omit the blank import; the rest of docker-agent works without cgo. + ## Basic Example Create a simple agent and run it: From eb688eb47bccf9f86196fd5ebbff1be095478f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20H=C3=A9ritier?= Date: Sat, 20 Jun 2026 04:05:50 +0000 Subject: [PATCH 3/6] =?UTF-8?q?docs:=20update=20docs=20for=20PR=20#3181=20?= =?UTF-8?q?=E2=80=94=20lean=20TUI=20user=20config=20setting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an Unreleased section to CHANGELOG.md for PR #3181, which landed after the v1.83.0 cut and adds settings.lean to the user config file. The TUI feature page already documents the setting; this commit records the change in the changelog. Source: https://github.com/docker/docker-agent/pull/3181 --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe336d935..d187613ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. +## [Unreleased] + +## What's New + +- Adds `settings.lean: true` user config option (`~/.config/cagent/config.yaml`) to make the lean TUI the default interface for all interactive runs, without needing to pass `--lean` each time + +### Pull Requests + +- [#3181](https://github.com/docker/docker-agent/pull/3181) - feat(tui): add lean user config setting + ## [v1.83.0] - 2026-06-19 This release adds an opt-in sudo askpass flow for shell commands, a headless embedded chat session API, and several bug fixes for cost accounting, session handling, and custom provider model resolution. From 41e32b58f8619e565717e396dc9303e091e1e6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20H=C3=A9ritier?= Date: Sat, 20 Jun 2026 04:10:03 +0000 Subject: [PATCH 4/6] docs: fix review findings in go-sdk and thinking guide - go-sdk: fix embeddedchat example to use dagentcfg.NewBytesSource (was erroneously named BytesSource with wrong arity); add missing dagentruntime import; check error return from chat.Confirm - thinking: split 'Fable 5 / Mythos 5' column into separate 'Mythos 5' and 'Mythos preview' columns; Mythos preview only supports max (not xhigh), matching pkg/modelinfo/thinking_levels.go --- docs/guides/go-sdk/index.md | 8 ++++++-- docs/guides/thinking/index.md | 14 +++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/guides/go-sdk/index.md b/docs/guides/go-sdk/index.md index 938c69117..da988d419 100644 --- a/docs/guides/go-sdk/index.md +++ b/docs/guides/go-sdk/index.md @@ -55,14 +55,16 @@ When building custom UIs on top of docker-agent's TUI primitives, four packages ```go import ( "context" + "strings" dagentcfg "github.com/docker/docker-agent/pkg/config" + dagentruntime "github.com/docker/docker-agent/pkg/runtime" "github.com/docker/docker-agent/pkg/embeddedchat" ) chat, err := embeddedchat.New(ctx, embeddedchat.Config{ // AgentSource can be a file path, raw YAML bytes, or an OCI reference. - AgentSource: dagentcfg.BytesSource([]byte(agentYAML)), + AgentSource: dagentcfg.NewBytesSource("agent", []byte(agentYAML)), }) if err != nil { return err @@ -87,7 +89,9 @@ for ev := range events { response.WriteString(ev.Text) case ev.Tool != nil && ev.Tool.NeedsConfirmation: // Approve or reject the pending tool call. - chat.Confirm(ctx, dagentruntime.ResumeApproveSession()) + if err := chat.Confirm(ctx, dagentruntime.ResumeApproveSession()); err != nil { + return err + } case ev.Tool != nil && ev.Tool.Finished: fmt.Printf("[tool %s finished]\n", ev.Tool.Def.Name) case ev.Err != nil: diff --git a/docs/guides/thinking/index.md b/docs/guides/thinking/index.md index af18b9d48..f1b2ec2da 100644 --- a/docs/guides/thinking/index.md +++ b/docs/guides/thinking/index.md @@ -108,13 +108,13 @@ models: **Adaptive effort levels and per-model support:** -| Level | Opus 4.5 | Sonnet 4.5 / Haiku | Sonnet 4.6 | Opus 4.6 | Opus 4.7 / 4.8 | Fable 5 / Mythos 5 | -| --------- | :------: | :----------------: | :--------: | :------: | :------------: | :----------------: | -| `low` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| `medium` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| `high` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| `xhigh` | — | — | — | — | ✓ | ✓ | -| `max` | — | — | ✓ | ✓ | ✓ | ✓ | +| Level | Opus 4.5 | Sonnet 4.5 / Haiku | Sonnet 4.6 | Opus 4.6 | Opus 4.7 / 4.8 | Fable 5 | Mythos 5 | Mythos preview | +| --------- | :------: | :----------------: | :--------: | :------: | :------------: | :-----: | :------: | :------------: | +| `low` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| `medium` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| `high` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| `xhigh` | — | — | — | — | ✓ | ✓ | ✓ | — | +| `max` | — | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | `minimal` is treated as `low` (bare form only). `high` is the default when `adaptive` is used without an effort level. From f5fd612df561c349cabab779161c4a8db9d13fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20H=C3=A9ritier?= Date: Sat, 20 Jun 2026 04:16:00 +0000 Subject: [PATCH 5/6] docs: add missing fmt import to embeddedchat code example --- docs/guides/go-sdk/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/guides/go-sdk/index.md b/docs/guides/go-sdk/index.md index da988d419..1e47caedd 100644 --- a/docs/guides/go-sdk/index.md +++ b/docs/guides/go-sdk/index.md @@ -55,6 +55,7 @@ When building custom UIs on top of docker-agent's TUI primitives, four packages ```go import ( "context" + "fmt" "strings" dagentcfg "github.com/docker/docker-agent/pkg/config" From 847f9608d51c151a94bb64c554b51a900e406c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20H=C3=A9ritier?= Date: Sat, 20 Jun 2026 04:31:01 +0000 Subject: [PATCH 6/6] =?UTF-8?q?docs:=20fix=20go-sdk=20examples=20=E2=80=94?= =?UTF-8?q?=20correct=20ResumeApprove=20scope=20and=20RAG=20import=20path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace ResumeApproveSession() with ResumeApprove() in the embeddedchat confirmation example; the former blanket-approves all future tool calls for the session, the latter approves only the currently pending call. - Fix RAG blank-import path: pkg/rag is the cgo library and has no init() that registers the toolset; the registration init() lives in pkg/tools/builtin/rag/register.go, so the correct import is _ "github.com/docker/docker-agent/pkg/tools/builtin/rag". --- docs/guides/go-sdk/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guides/go-sdk/index.md b/docs/guides/go-sdk/index.md index 1e47caedd..6ac81e40b 100644 --- a/docs/guides/go-sdk/index.md +++ b/docs/guides/go-sdk/index.md @@ -89,8 +89,8 @@ for ev := range events { case ev.Text != "": response.WriteString(ev.Text) case ev.Tool != nil && ev.Tool.NeedsConfirmation: - // Approve or reject the pending tool call. - if err := chat.Confirm(ctx, dagentruntime.ResumeApproveSession()); err != nil { + // Approve the pending tool call (use ResumeApproveSession to allow all). + if err := chat.Confirm(ctx, dagentruntime.ResumeApprove()); err != nil { return err } case ev.Tool != nil && ev.Tool.Finished: @@ -162,7 +162,7 @@ By default the RAG toolset is **opt-in**: it is only linked when you blank-impor ```go import ( - _ "github.com/docker/docker-agent/pkg/rag" // register RAG toolset + _ "github.com/docker/docker-agent/pkg/tools/builtin/rag" // register RAG toolset ) ```