feat: add docker agent serve chat command (OpenAI-compatible API)#2510
Draft
dgageot wants to merge 1 commit intodocker:mainfrom
Draft
feat: add docker agent serve chat command (OpenAI-compatible API)#2510dgageot wants to merge 1 commit intodocker:mainfrom
docker agent serve chat command (OpenAI-compatible API)#2510dgageot wants to merge 1 commit intodocker:mainfrom
Conversation
Expose any docker-agent agent through an OpenAI-compatible HTTP
server, so tools that already speak the Chat Completions protocol
(Open WebUI, the official `openai` SDKs, ad-hoc curl scripts, etc.)
can drive an agent without any custom integration.
Endpoints:
GET /v1/models — lists exposed agents as OpenAI models
POST /v1/chat/completions — runs the agent; supports stream: true
(Server-Sent Events) and false
The team is loaded once at startup and shared across requests; each
chat completion gets a fresh session and runtime. Tool calls and
elicitation prompts are auto-handled (this is a non-interactive
endpoint). The `model` field can pin a specific agent in a multi-
agent team, or is ignored and the team's default agent runs.
Implementation notes:
- New `cmd/root/chat.go` cobra command (default 127.0.0.1:8083,
--agent / --listen flags) wired into `cmd/root/serve.go`.
- New `pkg/chatserver` package, split into:
- server.go — Run, router, HTTP handlers, sseStream, errors
- agent.go — agentPolicy, buildSession, runAgentLoop, sessionUsage
- types.go — request/response shapes
- Reuses `openai.Model` from github.com/openai/openai-go/v3 for
/v1/models. Other OpenAI SDK response types serialise too noisily
with stdlib `encoding/json` (the SDK relies on its internal
`apijson` package which we can't import), so request/response
shapes are hand-rolled for clean output.
- Defensive event handling in runAgentLoop: ToolsApproved=true and
NonInteractive=true mean the runtime never blocks for confirmation
in normal flow, but ElicitationRequestEvent must still be answered
or the runtime would hang on its dedicated channel.
Tests cover session-building, agent-policy, error-envelope shape,
and the three early-validation paths of /v1/chat/completions via
httptest. Validated with `mise lint` (0 issues), `mise test` (all
packages green), and a curl smoke test against examples/42.yaml.
Fixes docker#2502
Assisted-By: docker-agent
40d4ebc to
8711dac
Compare
trungutt
approved these changes
Apr 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2502.
Exposes any docker-agent agent through an OpenAI-compatible HTTP server, so any tool that already speaks the Chat Completions protocol (Open WebUI, the official
openaiSDKs, ad-hoc curl scripts, etc.) can drive an agent without a custom integration.Endpoints
GET/v1/modelsPOST/v1/chat/completionsstream: true(SSE) andfalseUsage
Design
ToolsApproved=trueandNonInteractive=true— there is no human in the loop.ElicitationRequestEventis still explicitly declined to avoid hanging on the runtime's elicitation channel.modelfield of the request can pin a specific agent in a multi-agent team. If it doesn't match an exposed agent (e.g. clients that hard-codegpt-4) we silently fall back to the default agent and echo the requested model name back, so clients matching on the model field stay happy.chat.completion.chunkformat and ends withdata: [DONE].Implementation
cmd/root/chat.go(default127.0.0.1:8083,--agent/--listenflags) wired intocmd/root/serve.go.pkg/chatserverpackage, split across:server.go—Run, router, HTTP handlers,sseStream, error envelopeagent.go—agentPolicy,buildSession,runAgentLoop,sessionUsagetypes.go— request/response shapesopenai.Modelfromgithub.com/openai/openai-go/v3for/v1/models. Other SDK response types serialise too noisily with stdlibencoding/json(the SDK relies on its internalapijsonpackage, which lives underinternal/), so the chat-completion shapes are hand-rolled for clean output.Tests
httptestfor/v1/modelsshape, the three early-validation paths of/v1/chat/completions(bad JSON, empty messages, history without user), andwriteError's status→type mapping.Validation
mise lint— 0 issuesmise test— all packages greenexamples/42.yaml:/v1/modelsreturns the agent, error paths return correct OpenAI-shaped envelopes.