diff --git a/docs/features/api-server/index.md b/docs/features/api-server/index.md index 104451fc0..e73cee023 100644 --- a/docs/features/api-server/index.md +++ b/docs/features/api-server/index.md @@ -50,6 +50,7 @@ All endpoints are under the `/api` prefix. | `DELETE` | `/api/sessions/:id` | Delete a session | | `PATCH` | `/api/sessions/:id/title` | Update session title | | `PATCH` | `/api/sessions/:id/permissions` | Update session permissions | +| `POST` | `/api/sessions/:id/fork` | Fork a session at a user message — creates a new session with messages `[0, message_index)` of the parent (see [Session Forking](#session-forking)) | | `POST` | `/api/sessions/:id/resume` | Resume a paused session (after tool confirmation) | | `POST` | `/api/sessions/:id/tools/toggle` | Toggle auto-approve (YOLO) mode | | `POST` | `/api/sessions/:id/elicitation` | Respond to an MCP tool elicitation request | @@ -179,6 +180,13 @@ docker agent serve api | [flags] | `--record` | (none) | Record AI API interactions to cassette file | | `--mcp-oauth-redirect-uri` | (none) | Public HTTPS URL advertised as the OAuth `redirect_uri` for unmanaged MCP OAuth flows. When set, docker-agent drives PKCE and code exchange in-process and sends the full authorize URL to the client via elicitation. See [Remote MCP]({{ '/features/remote-mcp/' | relative_url }}) for details. | +
+
Live profiling (advanced) +
+

For production diagnostics, set the CAGENT_PPROF_ADDR environment variable (or the hidden --pprof-addr flag) to a TCP address such as 127.0.0.1:6060. docker-agent will start a Go pprof HTTP server at /debug/pprof/, which you can query with go tool pprof. Use a loopback address — a non-loopback binding logs a security warning. This flag is intentionally hidden from --help.

+ +
+
Multi-agent configs
@@ -293,6 +301,35 @@ runtime is attached and ready to accept follow-ups, then return its status, or `503` on timeout. This is session-scoped, unlike `GET /api/ready`, which fires as soon as any session is ready. +## Session Forking + +`POST /api/sessions/:id/fork` creates a new session whose history is a copy of the parent up to (but **excluding**) a specified user message. This lets a client "branch" a conversation — e.g. rewind to an earlier question and try a different prompt — without losing the shared history that came before. + +**Request body:** + +```json +{ "message_index": 2 } +``` + +`message_index` is a **0-based index** into the flat, user-visible message list (the same shape `GET /api/sessions/:id` returns in `messages`). The fork includes messages `[0, message_index)` — the message at `message_index` is **excluded**, so clients can prefill it into their chat input for the user to edit and resubmit. + +**Example:** + +```bash +# Fork a session before message index 4 (the user message the user wants to rewrite) +$ curl -X POST http://localhost:8080/api/sessions/$SID/fork \ + -H 'Content-Type: application/json' \ + -d '{"message_index": 4}' +# Returns: api.SessionResponse for the new forked session +# New session title: " (fork 1)", "(fork 2)", etc. +``` + +**Validation:** + +- `message_index` must point to a **user-role message**; pointing at an assistant turn returns `400 Bad Request`. +- Out-of-range indices return `400 Bad Request`. +- An index that falls inside a sub-session returns `400 Bad Request`. A sub-session is a nested session created when a multi-agent config delegates work to a child agent; its messages are embedded within the parent session's message list and cannot be used as a fork boundary. + ## Idempotent follow-ups `POST /api/sessions/:id/followup` accepts an optional `Idempotency-Key` diff --git a/docs/features/cli/index.md b/docs/features/cli/index.md index 40773f2e5..3eb538661 100644 --- a/docs/features/cli/index.md +++ b/docs/features/cli/index.md @@ -219,6 +219,8 @@ $ docker agent serve api || [flags] | `--record [path]` | (none) | Record AI API interactions to a cassette file. | | `--mcp-oauth-redirect-uri ` | (none) | OAuth redirect URI for the unmanaged MCP OAuth flow in server mode. When set, the runtime drives PKCE and code exchange in-process and sends the full authorize URL to the client via elicitation. See [Remote MCP]({{ '/features/remote-mcp/' | relative_url }}) for details. | +> **Diagnostics:** Set `CAGENT_PPROF_ADDR=127.0.0.1:6060` (or `--pprof-addr`, a hidden flag) to start a live Go pprof server at `/debug/pprof/`. Use a loopback address; a non-loopback binding logs a security warning. + All [runtime configuration flags](#runtime-configuration-flags) (`--working-dir`, `--env-from-file`, `--models-gateway`, `--hook-*`, …) are also accepted. ```bash diff --git a/docs/guides/go-sdk/index.md b/docs/guides/go-sdk/index.md index 25b93e913..de86dd013 100644 --- a/docs/guides/go-sdk/index.md +++ b/docs/guides/go-sdk/index.md @@ -177,6 +177,46 @@ registry := teamloader.NewToolsetRegistry(creators) Pass the custom registry via `teamloader.WithToolsetRegistry(registry)` when calling `teamloader.Load`. Note that `teamloader.Load()` does not return an error for unknown toolset types — the failure is recorded as a load-time warning and can be retrieved with `agent.DrainWarnings()`; it is also surfaced via logging and TUI notifications. +## Registering Custom Built-in Themes + +When embedding docker-agent, you can contribute your own built-in themes via `styles.RegisterBuiltinThemes`. Registered themes integrate seamlessly with the existing theme picker, `/theme` command, and `settings.theme` config key — they behave exactly like docker-agent's own bundled themes. + +```go +import ( + "embed" + + "github.com/docker/docker-agent/pkg/tui/styles" +) + +//go:embed themes/*.yaml +var brandThemes embed.FS + +// Call at startup, before applying any persisted theme: +if err := styles.RegisterBuiltinThemes(brandThemes); err != nil { + return err +} +``` + +Each theme file lives at `themes/.yaml` inside the embedded filesystem and is a **partial override** — only the colors you want to change are required; everything else falls back to `DefaultTheme()`. + +```yaml +# themes/brand.yaml +name: Brand +colors: + accent: "#FF6A00" + background: "#1A0F0A" +``` + +If `name:` is omitted, docker-agent uses the filename stem as the display name in the theme picker (e.g. `brand` from `themes/brand.yaml`). + +To replace docker-agent's default theme entirely, ship the file as `themes/default.yaml` — it masks the bundled default while inheriting any colors you don't set. + +**Semantics:** + +- Registered sources take precedence over bundled themes; a registered ref overrides a bundled theme of the same name. +- Among multiple registered sources, last-registered wins on a collision. +- `RegisterBuiltinThemes` validates eagerly (nil fs, missing `themes/` dir) so errors surface at registration time, not at picker time. + ## MCP OAuth Token Persistence By default, MCP OAuth tokens are stored in-memory only and are not persisted across process restarts. The CLI registers a keyring-backed store automatically at startup; when embedding docker-agent as a library you must do this yourself if you want tokens to survive restarts. diff --git a/docs/providers/dmr/index.md b/docs/providers/dmr/index.md index 97555d011..48afd99f4 100644 --- a/docs/providers/dmr/index.md +++ b/docs/providers/dmr/index.md @@ -12,6 +12,8 @@ _Run AI models locally with Docker — no API keys, no costs, full data privacy. Docker Model Runner (DMR) lets you run open-source AI models directly on your machine. Models run in Docker, so there's no API key needed and no data leaves your computer. +docker-agent automatically discovers models you have already pulled from DMR. When no model is explicitly configured, auto-selection prefers a locally-installed model (choosing the model specified via the `model:` key in the agent YAML if it is already pulled locally, or otherwise the first available non-embedding model) rather than always defaulting to `ai/qwen3:latest` and triggering a pull prompt. +
No API key needed