Append the next user message to an existing task and kick off its next turn.
Phase 1 multi-turn model is task-centric: subsequent user inputs
extend the same task_id rather than creating a new task or a
new conversation_id. This endpoint:
task_id exists and belongs to the
key-bound agent (404 task_not_found otherwise).body.agent_id matches the key-bound agent
(404 agent_not_found otherwise).task_busy if the task is
currently RUNNING — the SDK client should poll
GET /v1/chat/tasks/{id} until status leaves RUNNING and
retry.task_chat_messages, updates task.input to record
this turn’s input, and kicks off the next background turn
via the same helper POST uses.Args:
task_id: Path parameter; the target task’s primary key.
request: Validated :class:AppendMessageRequest. message.content
is guaranteed non-empty by Pydantic.
authed: (Agent, AgentApiKey) from the auth dependency.
db: SQLAlchemy session.
Returns:
:class:AppendMessageResponse with the task identity and an
accepted_at timestamp.
Raises:
V1ApiError 401: missing / invalid / revoked key.
V1ApiError 404: task not found OR not owned by the agent OR
body.agent_id doesn’t match the bound agent.
V1ApiError 409: task_busy — task currently RUNNING.
500: any other unexpected error (V1 envelope via global handler).
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body for POST /v1/chat/tasks/{task_id}/messages.
Same shape as :class:CreateTaskRequest minus the lack of a
metadata field by default -- callers append a new user
message to an existing task. agent_id is required again
(consistent with the SDK contract: every write carries the
agent_id explicitly for forward-compat with multi-agent keys).
Successful Response
POST /v1/chat/tasks/{task_id}/messages -> 202 Accepted response.
The new user message has been persisted and the next turn queued for background execution; callers poll the same way they would after the initial POST /v1/chat/tasks.
Existing task primary key.
Agent the task is bound to.
Initial status of the new turn, 'running' in the 202 response (the atomic claim inside POST commits the status flip before the response is sent).
UTC timestamp when the server accepted the message and scheduled background execution. Not the message's stored created_at (which may differ slightly due to DB clock).