microsoft / microsoft/agent-host-protocol
Proposal: ChatSummary message preview for catalog rendering without subscribing
@connor4312 is already working on this.
Since Jun 26, 2026.
- Dominant language
- TypeScript
- Stars
- 348
- Forks
- 122
- Avg merge
- 14h 12m
- Merged PRs (30d)
- 22
Description
Summary
Add an optional, short, server-truncated last-message preview to the catalog representation of a chat (ChatSummary) so a client can render a conversation list — the newest line of each thread — without subscribing to every chat channel. This mirrors the existing precedent of ChangesSummary (#191) and the session-level inputNeeded aggregate (#265): surface a cheap rollup on the catalog so constrained clients avoid the heavy per-chat subscription.
Motivation
A session with many chats (sub-agent fan-out, parallel threads, an agent team) renders in a UI as a list, each row showing the thread's latest activity. Today ChatSummary carries title, status, activity?, and modifiedAt — but no content peek. To show "…the last thing said in this thread," a client must subscribe to the chat and pull its ChatState (the full turn history). For a list of N chats that is N subscriptions and N histories to render N preview lines.
The catalog is meant to be the cheap layer that lets a client decide what to drill into; a preview keeps it cheap. activity does not fill this role: it is the in-progress status verb ("Editing files…"), not message content, and it is absent when the chat is idle — which is exactly when a "last message" preview is most useful.
Why this belongs in AHP (not a per-host _meta convention)
The catalog/summary split is already an AHP concept, and AHP already places derived rollups on summaries for precisely this reason:
ChangesSummaryonSessionSummary— "a quick at-a-glance view of the session's footprint… without requiring the client to subscribe to a changeset."AnnotationsSummaryonSessionSummary— counts surfaced "so badge UI can render… without subscribing."SessionState.inputNeeded(#265) — outstanding input surfaced on the session channel so a client can act "without subscribing to each chat."
A last-message preview is the same shape of thing and should be modeled the same, native way — not as a per-host metadata convention that every client has to special-case to render a basic chat list.
Proposed shape (illustrative — open to bikeshedding)
export interface ChatSummary {
// ...existing fields...
/**
* Optional short preview of the most recent message/response in the chat,
* for list rendering. Server-truncated; clients MUST treat it as lossy and
* MUST NOT parse it for structure. Absent ⇒ no preview available (e.g. an
* empty chat, or a host that chooses not to surface content into the catalog).
*/
preview?: MessagePreview;
}
export interface MessagePreview {
/** Who produced the previewed content. Reuses the MessageKind vocabulary. */
role: MessageKind; // 'user' | 'agent' | 'tool' | 'systemNotification'
/** Plain-text, server-truncated snippet (no markdown-structure guarantee). */
text: string;
/** Optional timestamp of the previewed message/response (ISO-8601). */
at?: string;
}
- Optional and additive — old peers ignore it.
- Small by contract — it rides in session/chat lists and in
root/sessionSummaryChanged-style notifications, the same place the existing "producers SHOULD keep the payload small" guidance already applies toSessionSummary._meta. - Reuses
MessageKindrather than inventing a fresh role enum. - Privacy-aware — a preview lifts conversation content into the catalog/list layer. A host that treats the catalog as lower-trust than the chat channel MAY omit it; absence is always valid.
Relationship to existing / in-flight work
- #187 / #264 restructure where
SessionSummarylives and its timestamp representation; this is an additive field on the chat catalog entry and is orthogonal — it should slot into whicheverChatSummaryshape #264 settles on. - #191 (
ChangesSummary) and #265 (inputNeeded) are the direct precedents this follows. - Pairs naturally with the bounded-snapshot proposal (subscribe
view): windowing makes subscribing to a chat cheap; preview makes not subscribing — just listing — cheap.
Open questions
- Bubble to
SessionSummary? Should a session's most-recently-active chat preview also surface onSessionSummaryso a session list (not just a chat list within one session) can show a line? Likely yes, sourced from the session's default/most-recent chat. - Part kind. Include a tiny discriminator (text vs tool-result vs reasoning) so a UI can render
🔧 ran testsvs a text snippet, or keep it pure text for v1? - Length contract. Leave truncation length entirely to the host (recommended), or suggest a soft cap so list rows are visually consistent across hosts?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.