Skip to content

feat(types): multi-chat sessions (ahp-chat: channel)#197

Draft
sandy081 wants to merge 15 commits into
mainfrom
sandy081/multi-chat-impl
Draft

feat(types): multi-chat sessions (ahp-chat: channel)#197
sandy081 wants to merge 15 commits into
mainfrom
sandy081/multi-chat-impl

Conversation

@sandy081

@sandy081 sandy081 commented Jun 5, 2026

Copy link
Copy Markdown
Member

Implements the multi-chat sessions proposal (design discussion, approved).

Splits the AHP session model: a session becomes a shared coordination scope (workspace, project, model/agent defaults, tools, config), and a session can hold multiple chats, each its own independently subscribable conversation over the shared scope.

What ships in this PR (Phase 1: protocol types)

  • New ahp-chat: channel. types/channels-chat/{state,commands,actions,reducer}.ts.
  • ChatState carries the turn / input / pending-message state today living on SessionState.
  • ChatSummary with optional per-chat model / agent overrides and an origin?: ChatOrigin provenance field.
  • ChatOrigin discriminated union: User / Fork / Tool (per-call discussion with @connor4312Tool carries { chat, toolCallId } so tool-spawned chats reference their spawning tool call).
  • SessionState changes:
    • Removed: turns, activeTurn, steeringMessage, queuedMessages, inputRequests.
    • Added: chats: ChatSummary[], defaultChat?: URI (UI input-routing hint — not a hierarchy marker).
  • New commands: createChat (with optional ChatForkSource { chat, turnId }), disposeChat.
  • Retargeted commands: fetchTurns / completions now take an ahp-chat: channel URI.
  • Reducer split: turn / input / pending-message handling moved to the chat reducer; session reducer gains chats[] / defaultChat handling.
  • Version bump: PROTOCOL_VERSION 0.3.00.4.0 (allowed pre-1.0 per versioning.md).
  • CHANGELOGs: root + every client.

Subsequent phases (will land in follow-up commits on this branch)

  • Phase 2: regenerate JSON schema.
  • Phase 3: per-client codegen + manual updates (rust / kotlin / swift / typescript / go).
  • Phase 4: docs (chat-channel reference, session↔chat relationship, URI scheme) + integration tests.
  • Phase 5: address surviving open implementation questions from the proposal; finalize release notes.

Verification

  • npm run test passes: 241/241, 100% branch coverage on types/reducers.ts.

Notes for reviewers

  • Proposal lives at docs/proposals/multi-chat-sessions.md on PR docs: add multi-chat sessions proposal #184; design discussion is captured there.
  • Doc updates (chat-channel reference, session↔chat docs) intentionally deferred to Phase 4 so this PR stays a clean type-shape diff.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

sandy081 and others added 7 commits June 5, 2026 15:39
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Go generator was missing the ChatToolCallApproved/Denied/Confirmed
discriminated union variants and the ChatAction top-level union from its
explicit-skip list, causing exhaustiveness warnings during codegen.
Kotlin regeneration picked up trivial drift in State.generated.kt.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread types/channels-chat/state.ts
Comment thread types/channels-session/actions.ts Outdated
Comment thread types/channels-chat/state.ts Outdated
Comment thread types/channels-session/state.ts
Comment thread types/channels-chat/state.ts
sandy081 and others added 8 commits June 7, 2026 21:59
Adds the user-facing documentation for the new `ahp-chat:` channel
introduced by the multi-chat session split: chat-channel.md
specification page and updates the per-client CHANGELOG entries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mming

- New generateChatChannelPage in scripts/generate-markdown.ts emits the
  ahp-chat:/ reference page from types/channels-chat/{state,actions,commands}.ts.
- Session spec doc slimmed: turn lifecycle moves to chat-channel.md;
  fetchTurns/completions removed from session command table; validation
  table reduced to session-scoped actions only; new 'Chat aggregation'
  section spelling out how SessionSummary.status/activity/modifiedAt
  derive from chats.
- Sidebar: add 'Chat Channel' entries to both /specification/ and
  /reference/ sidebars.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update the Rust generator to split session-scoped and chat-scoped
protocol surfaces: rename `SessionInput*` types to `ChatInput*`, add
`ChatState`/`ChatSummary`/`ChatOrigin` state types and chat commands,
partition the action map into `session/*` and `chat/*`, and add a
merged chat tool-call-confirmed helper.

Split the reducer into a slimmed session reducer (lifecycle, metadata,
customizations, chats catalogue) and a new `apply_action_to_chat`
chat reducer (turn lifecycle, tool calls, input requests, pending
messages). Track chat state in `MultiHostStateMirror` and update
fixtures/tests for the new state shapes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
# Conflicts:
#	CHANGELOG.md
#	clients/go/CHANGELOG.md
#	clients/go/ahptypes/version.generated.go
#	clients/go/examples/reducers_demo/main.go
#	clients/go/release-metadata.json
#	clients/kotlin/CHANGELOG.md
#	clients/kotlin/release-metadata.json
#	clients/kotlin/src/main/kotlin/com/microsoft/agenthostprotocol/generated/Version.generated.kt
#	clients/rust/CHANGELOG.md
#	clients/rust/crates/ahp-types/src/version.rs
#	clients/rust/release-metadata.json
#	clients/swift/AgentHostProtocol/Sources/AgentHostProtocol/Generated/Version.generated.swift
#	clients/swift/CHANGELOG.md
#	clients/swift/release-metadata.json
#	clients/typescript/CHANGELOG.md
#	clients/typescript/release-metadata.json
#	types/version/registry.ts
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Addresses connor4312's five inline review comments on PR #197:

1. Denormalize ChatSummary into ChatState - flatten the summary nesting
   so ChatState exposes resource/title/status/activity/modifiedAt/origin
   directly. ChatSummary stays as the lightweight session-catalog view.

2. Add upsert/partial semantics for chat catalog mutations: replace
   SessionChatsChangedAction (full-replacement) with three targeted
   actions: SessionChatAddedAction (upsert by summary.resource),
   SessionChatRemovedAction (clears defaultChat if removed),
   SessionChatUpdatedAction (Partial<ChatSummary> merge).

3. Change modifiedAt from epoch millis (number) to ISO-8601 string on
   both ChatSummary and ChatState. Reducers emit
   new Date(Date.now()).toISOString() so existing Date.now mocks remain
   deterministic.

4. Document SessionSummary aggregate derivation rules - status promotion
   (InputNeeded > InProgress > Idle), activity, modifiedAt as max of
   chat modifiedAts, workingDirectory as the default-chat fallback.

5. Add optional workingDirectory to ChatState/ChatSummary so harnesses
   can support agent-swarm worktree patterns where cooperating chats
   pin to different working directories.

Codegen + clients:
- Fix Rust/Kotlin/Swift generators to emit Partial<T> structs that are
  referenced only from actions (previously only notification-side
  partials were emitted).
- Regenerate all clients (Rust, Kotlin, Swift, TypeScript, Go).
- Port hand-written reducers in Rust, Go, Kotlin, Swift to match the
  new action shape and ISO timestamps.
- Migrate all 87 chat reducer fixtures to the flat ChatState shape with
  ISO modifiedAt; replace 3 old chatsChanged fixtures with 6 fixtures
  covering chatAdded upsert, chatRemoved + defaultChat clearing, and
  chatUpdated partial merge (plus no-op cases).

Docs: update chat-channel.md and session-channel.md with the
denormalized shape, per-chat workingDirectory, catalog mutation
actions, and the full session aggregation rules.

Changelogs: updated root + all 5 client CHANGELOGs under Unreleased.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@connor4312 connor4312 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this overall is looking good. Feel free to promote to 'ready for review' when you're happy with it. We should avoid merging until we have a PR ready on the VS Code side of things too, just so we don't block other people getting stuff into AHP main while adoption happens.

@sandy081

sandy081 commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

@connor4312 thanks for the review — all five points are addressed in 41ab532 and the threads are resolved.

Summary of changes:

  1. Denormalized ChatSummary into ChatStateChatState is now flat (resource/title/status/activity/modifiedAt/origin/workingDirectory live directly on it). ChatSummary remains the standalone lightweight session-catalog view, no longer embedded.

  2. Upsert + partial update semantics — replaced SessionChatsChangedAction with three targeted actions mirroring the session pattern: SessionChatAddedAction (upsert by summary.resource), SessionChatRemovedAction (clears defaultChat when needed), and SessionChatUpdatedAction carrying Partial<ChatSummary>. Fixtures 170–175 cover the new semantics including no-ops.

  3. ISO-8601 modifiedAt — now a timestamp string on both ChatSummary and ChatState.

  4. SessionSummary derivation documented — status promotion (InputNeeded > InProgress > Idle), activity from the primary chat, modifiedAt as max across chats, workingDirectory from the default chat. Also expanded in the spec docs.

  5. Per-chat workingDirectory — added as optional on ChatState/ChatSummary (inherits session default when unset) to model the agent-swarm worktree pattern.

Codegen/clients: fixed the Rust/Kotlin/Swift generators to emit Partial<T> structs referenced only from actions, regenerated all clients, and ported the hand-written reducers in Rust/Go/Kotlin/Swift. TS (248 ✓, 100% coverage), Rust (cargo test ✓), and Go (go test ✓) all pass; Swift swift build ✓. All six CHANGELOGs updated under Unreleased.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants