Skip to content

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

Merged
sandy081 merged 2 commits into
mainfrom
sandy081/multi-chat-impl
Jun 10, 2026
Merged

feat(types): multi-chat sessions (ahp-chat: channel)#197
sandy081 merged 2 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

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 added a commit that referenced this pull request Jun 8, 2026
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.

@connor4312

connor4312 commented Jun 9, 2026

Copy link
Copy Markdown
Member

in case you missed before your last comment

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.

Looks like some conflicts came up but should be easily agent-resolvable

Squashed implementation of multiple chats per session plus Connor's
review feedback. Will be re-expanded/force-pushed after rebasing onto
latest main.
@sandy081 sandy081 force-pushed the sandy081/multi-chat-impl branch from 41ab532 to 2abd787 Compare June 9, 2026 22:48
The rebased tool-call metadata change reintroduced an explicit
`List<Annotation>` type on the annotationsRemoved reducer branch, which
resolved to `kotlin.Annotation` instead of the generated type and broke
`compileKotlin`. Drop the explicit annotation so the element type is
inferred from `state.annotations`, matching the sibling branches.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sandy081 sandy081 marked this pull request as ready for review June 10, 2026 07:53
@sandy081

Copy link
Copy Markdown
Member Author

Promoted to ready for review.

  • Rebased onto latest main (incl. reducers: propagate tool call action metadata #211 tool-call metadata).
  • Fixed a Kotlin compile break that the rebase reintroduced: an explicit List<Annotation> in the annotationsRemoved reducer branch resolved to kotlin.Annotation instead of the generated type; now inferred from state.annotations (b55919a).
  • Validated locally: npm test (typecheck + lint + release-metadata + changelog + 265 reducer/version tests, 100% reducer coverage), Kotlin ./gradlew build, and npm run generate shows no client drift.
  • All CI checks green.

Per your note, holding merge until the VS Code-side adoption PR is ready.

@sandy081 sandy081 merged commit eeb87cd into main Jun 10, 2026
8 checks passed
@sandy081 sandy081 deleted the sandy081/multi-chat-impl branch June 10, 2026 10:57
sandy081 added a commit that referenced this pull request Jun 10, 2026
Revert "feat(types): multi-chat sessions (ahp-chat: channel)" (#197)
joshmouch pushed a commit to joshmouch/agent-host-protocol that referenced this pull request Jun 10, 2026
…i-chat-impl"

This reverts commit eeb87cd, reversing
changes made to 4790353.
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.

3 participants