microsoft / microsoft/agent-host-protocol

Persist per-chat read watermarks through turn IDs

Open
#401 0 comments 0 reactions 1 assignee View on GitHub

@connor4312 is already working on this.

Since Aug 14, 2026.

feature-request
Dominant language
TypeScript
Stars
344
Forks
122
Avg merge
14h 12m
Merged PRs (30d)
22

Description

Problem

AHP currently represents read state using the session-level SessionStatus.IsRead flag and session/isReadChanged action. This says whether a session is currently considered read, but it does not record how far a reader has read.

Consumers therefore cannot reliably answer:

Has reader X read turn Y or any later turn in this chat?

This is needed for durable workflows that should remain visible until the user has seen a particular agent response. The existing boolean cannot identify a chat or turn, and a timestamp is ambiguous for sessions with multiple independently progressing chats.

Proposal

Add a client-dispatchable session action:

interface SessionReadWatermarkChangedAction {
	type: 'session/readWatermarkChanged';

	/**
	 * Stable opaque identifier chosen by the client.
	 * VS Code initially uses the constant `vscode`.
	 */
	readerId: string;

	/** Chat whose content was read. */
	chat: URI;

	/** Last turn visible to this reader. */
	throughTurnId: string;
}

Persist the watermark in session state:

interface SessionState {
	// ...
	readWatermarks?: Record<
		string, // readerId
		Record<URI, string> // chat -> last read turn ID
	>;
}

readerId extensibility

readerId is deliberately client-determined rather than tied to the current per-connection AHP clientId.

Initially VS Code can always use the constant vscode, giving all VS Code windows one shared read position. The same protocol shape remains useful if clients later need more granular progress:

  • a different ID per client implementation, such as vscode, web, or cli;
  • a stable ID per device or installation;
  • a stable ID per user in a future multi-user host.

Defining authentication, identity, and visibility policy for those future IDs is outside the initial implementation. The protocol only treats readerId as an opaque namespace selected by the client.

Behavior

  • The host validates that chat belongs to the session and that throughTurnId exists in that chat.
  • A watermark advances monotonically according to the chat's turn order; stale updates are no-ops.
  • The host persists watermarks with the session.
  • Updated watermarks are broadcast through the existing action/state mechanism.
  • Multiple clients using the same readerId contribute to the same watermark.
  • New turns do not delete the watermark; they simply make that reader's stored position older than the latest turn.
  • Existing session/isReadChanged and SessionStatus.IsRead behavior remains available for compatibility. VS Code may derive its compatibility flag from whether the vscode watermark covers each relevant chat's latest turn.

Example

{
  "type": "session/readWatermarkChanged",
  "readerId": "vscode",
  "chat": "ahp-chat:/session-123/main",
  "throughTurnId": "turn-42"
}

A consumer can determine whether turn-40 has been read by locating both turns in the chat's ordered turn list and comparing their positions.

Acceptance criteria

  • Read watermarks survive host restart.
  • Watermarks are included in session snapshots.
  • Subscribers receive watermark updates.
  • A watermark cannot move backwards.
  • Invalid session/chat/turn references are rejected or ignored consistently with existing action validation.
  • Two clients using readerId: "vscode" share progress.
  • Different reader IDs retain independent progress.
  • Existing clients using session/isReadChanged continue to work.

Non-goals for the initial implementation

  • Defining user authentication or identity.
  • Choosing IDs for devices or users.
  • Read-receipt UI for collaborators.
  • Cross-reader permission policy.
  • Removing the existing IsRead compatibility flag.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.