Skip to content

Feedback, titles and message actions ​

A chat surface — a portal, an embedded widget, your own client — is what people actually talk to an agent through. It decides what to switch on; the control plane provides the pieces: the thumbs people give an answer, a title for each conversation, and the actions on a message — regenerate and edit.

This page documents the runtime's part of that: what a client can read and send, and what the platform records when a surface uses these features. The surface itself is documented with the module that provides it. The welcome text, the suggested first messages and the tools of an embedding page are not settings of the agent: a portal sets them for itself, per agent.

Feedback ​

A person can rate an answer helpful or not helpful. A thumbs down can carry reasons — inaccurate, incomplete, off_topic, too_long, unsafe, other — and a comment of up to 1000 characters.

  • One rating per person per answer. Rating again replaces it; withdrawing (a null rating) deletes it.
  • An answer is addressed by a stable message id (msg_ and 20 hex characters), derived from the session, its place in the transcript and its time, so rating never touches the transcript. It is the id of the message item a response returns.
  • When an answer is replaced (regenerate, edit), the ratings of the replaced messages stay and count; they are marked as removed (Answer replaced in Studio).

In Studio ​

  • Sessions → a session shows the ratings under the answer they belong to.
  • The agent's Feedback tab shows the counts, the share of helpful answers, why answers were not helpful, and the latest ratings with an Open in session link. It can be narrowed by period (Last N days), rating (All / Helpful / Not helpful), reason, and Only with a comment. The tab is not shown for connected (external) agents.
  • Counts and reasons are visible to everyone who can read the agent; the words people wrote, and who wrote them, only to those who can change it (canReadComments in the responses says which).

Dashboard routes ​

Route
GET /api/agents/{agentId}/feedbackLatest ratings, newest first: { items, total, canReadComments }. Query: days (1–365, default 30), rating, reason, hasComment, portalId, limit (default 25, at most 100), skip.
GET /api/agents/{agentId}/feedback/summaryCounts: up, down, total, positiveRate, withComment, reasons. Same filters.
GET /api/agents/{agentId}/sessions/{sessionId}/feedbackEvery rating of one session.

These authenticate with a browser session. Surfaces record feedback through the platform's recordMessageFeedback service function — it takes the session, the message, the person, the channel (portal, embed, …) and whether comments are allowed on that surface. A client with an API token sends a rating through the client API below.

From your own client (API) ​

A client that calls the agent through the API can send the same rating. The id of the message item in a response (output[].id) is the id to rate:

bash
curl -X PUT "$CONSOLE_URL/api/client/v1/agents/sessions/$SESSION_ID/messages/$MESSAGE_ID/feedback" \
  -H "Authorization: Bearer $COGNIPEER_API_TOKEN" -H "Content-Type: application/json" \
  -d '{ "rating": "down", "reasons": ["inaccurate"], "comment": "The date is wrong." }'
json
{
  "object": "agent.message.feedback",
  "session_id": "…",
  "message_id": "msg_c4059d953c4924553800",
  "rating": "down",
  "reasons": ["inaccurate"],
  "comment": "The date is wrong.",
  "created_at": "2026-10-12T13:35:27.087Z",
  "updated_at": "2026-10-12T13:35:27.087Z"
}
ratingup or down (required).
reasonsAny of the six reasons above. Kept with down.
commentFree text, up to 1000 characters. The API always accepts comments; a portal can turn them off for itself.

201 for a new rating, 200 when it replaced the person's earlier one. DELETE on the same path withdraws it ({ "deleted": true }).

Who can rate. Only the person the session belongs to: the token's owner, or the end user a delegating token acts for. Anyone else gets 403 not_session_owner. The rating is the same record the portal writes (marked channel: api), so it shows in the agent's Feedback tab and sends the same trace event, audit entry and webhook. The errors are the ones in the table below, plus 403 and the usual 401 / 404 for the token and the session.

Where it is announced ​

Recording or withdrawing a rating:

  • writes a feedback event to the trace of the turn that wrote the answer (so the trace in Observability shows it);
  • adds an audit entry (agent.message.feedback, or agent.message.feedback.withdraw) with no comment text;
  • sends the feedback.recorded webhook — ids, rating, reasons and whether there is a comment, never the comment itself.

Feedback errors ​

StatusCodeMeaning
400invalid_ratingrating must be "up", "down" or null.
400invalid_reasons, invalid_comment, comment_too_longA reason is not one of the known six, or the comment is not text or is over 1000 characters.
400comments_disabledThe surface does not take comments (Comments are turned off here.).
400not_an_answerOnly an assistant answer can be rated.
404session_not_found, message_not_foundNo such session, or the message is not in it.

Titles ​

generateConversationTitle asks a model for a title of at most six words, in the language the conversation is in (cut to 80 characters). The call is recorded like any other model call — a usage row tagged purpose: title, route agent.title — attributed to the person, and counted against the tenant's spend limits. generateAndStoreConversationTitle names a conversation once, after its first exchange, and leaves a title a person chose (metadata.titleSource: user). A model that is gone, a spend limit or a timeout means "no generated title": the conversation keeps the one it has. Which model writes titles — off, the agent's own, or a model key — is the surface's setting.

Cutting a session back, regenerating, editing ​

Three things a chat surface offers on top of "send a message":

  • truncateSessionAfterMessage keeps the messages up to an index and removes the rest. Requests still open on the removed messages are cancelled, the agent's carried state is dropped (the next turn rebuilds it from the transcript), the files the removed messages carried are remembered as already sent, the ratings of the removed messages are marked, and session.truncated is written to the event log.
  • rerunSessionTurn cuts the session back to just before a message and runs it again. Regenerate takes the latest answer, runs its user message again (tools included) and keeps the answer it replaced as previousVersions on the new message (newest last, at most 5). Edit takes a user message, drops everything after it and runs the new text, with the original files unless others are given. If the new turn cannot run at all, the transcript is put back.
  • All of it needs the conversation's run slot, exactly like sending a message: a session that is still answering is refused with 409 conversation_busy. Other refusals: 404 message_not_found, 409 not_latest_answer (only the latest answer can be regenerated), and 400 for not_a_user_message, not_an_assistant_message and empty_message.

These are service functions the surface calls — there is no plain client-API route for them.

What's new ​

Message feedback with its Studio tab, webhook event, audit trail and a client API route to send a rating, generated titles, and truncate / regenerate / edit with the session.truncated event are new in the October 2026 agent runtime release.

Studio · Pulse · Console · Agent SDK and more — the Cognipeer documentation hub