Skip to content

feat(chat): add per-message destination mentions#113

Merged
tcballard merged 2 commits into
mainfrom
codex/per-message-route-mentions
Jul 24, 2026
Merged

feat(chat): add per-message destination mentions#113
tcballard merged 2 commits into
mainfrom
codex/per-message-route-mentions

Conversation

@tcballard

Copy link
Copy Markdown
Contributor

Summary

Implements per-message destination overrides for native Wayfinder Chat.

Adds:

  • Leading @local, @hosted, @codex, canonical route, and unique friendly-alias resolution
  • A compact keyboard- and VoiceOver-accessible destination suggestion menu plus removable this-message chip
  • Requested-route persistence and retry behavior that preserves the original destination
  • Deterministic resolver, state, delivery, failure, retry, and legacy-decoding coverage

Scope

Included

  • One-message destination precedence over the existing session destination
  • Case-insensitive matching with canonical gateway route IDs retained internally
  • Exact configured-route matching and unique normalized friendly-name aliases
  • Ambiguous and unknown mentions preserved as literal prompt text
  • Explicit unavailable destinations rejected without Automatic fallback
  • Optional requested-route metadata on saved user messages
  • Requested destination shown discreetly in the existing routing-details popover

Excluded

  • Rust routing algorithm changes
  • Persistent task-type rules or semantic classification
  • Credential broker or ChatGPT authentication changes
  • Apple Foundation Models availability, signing, or default changes
  • A permanent routing inspector or replacement of the existing destination selector

Product / Architecture Decisions

  • Reuses the gateway's existing model contract: auto, prefer-local, prefer-hosted, or a configured canonical route name.
  • Keeps one deterministic Swift resolver for typed mentions and autocomplete candidates; it does not reproduce gateway routing policy.
  • Recognizes routing syntax only in a leading token. Unknown or ambiguous aliases remain user content.
  • Applies precedence as per-message override, then current session destination, then Automatic.
  • Stores the requested canonical route and display title on the user message so retry is independent of the currently selected session destination.
  • Adds only optional persisted fields, preserving decoding of existing conversation history.

User-Facing Contract

Native Chat

  • Typing @ at the beginning of a draft opens compact destination suggestions.
  • Up/Down Arrow changes the active suggestion; Return or Tab selects it; Escape dismisses it.
  • Selection removes the token and shows <destination> · this message while leaving the session destination visible.
  • Sending clears the one-message override without changing the session destination.

Gateway Request

The clean prompt is sent through the existing OpenAI-compatible chat request with the selected destination's canonical value in model.

Persistence

User turns optionally encode requestedGatewayRouteName and requestedDestinationTitle. Missing fields decode as nil.

CLI / JSON / Exit Codes

No CLI, public gateway JSON schema, or process exit-code behavior changes.

Verification

Ran

swift test --package-path macos/WayfinderMac

Covered

  • 190 Swift package tests passed with zero failures.
  • 16 focused tests cover local/hosted aliases, canonical routes, friendly aliases, unique and ambiguous Codex resolution, literal unknown mentions, autocomplete identity, token stripping, clean saved and delivered prompts, session preservation, next-message fallback, unavailable fail-closed behavior, original-destination retry, legacy conversation decoding, and existing pinned composer behavior.

Review Path

  1. ChatDestinationMentionResolver.swift for deterministic matching and ambiguity behavior
  2. AppState.swift and ChatModels.swift for precedence, persistence, and retry semantics
  3. ChatComposerView.swift and routing popover changes for native interaction and accessibility
  4. ChatDestinationMentionTests.swift for boundary and regression coverage

Notes For Reviewer

  • Persistent rules such as “coding → Codex” remain a separate Rust gateway design/PR so every client receives the same deterministic policy and explanation output.
  • The existing session destination selector remains authoritative whenever a message has no recognized one-message override.

…1.0]

Adds deterministic leading mention resolution, a keyboard-accessible composer picker and one-message chip, persisted requested-route metadata, and retry behavior that preserves the original destination.
…1.0]

Covers canonical and friendly aliases, ambiguity, clean delivery, session precedence, unavailable fail-closed behavior, retry intent, and backward-compatible conversation decoding.
@tcballard
tcballard force-pushed the codex/per-message-route-mentions branch from 971d60e to 4a5a42c Compare July 24, 2026 11:38
@tcballard
tcballard merged commit c713315 into main Jul 24, 2026
6 checks passed
@tcballard
tcballard deleted the codex/per-message-route-mentions branch July 24, 2026 11:47
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.

1 participant