This document explains how chat history is handled between the macOS app and the sidecar.
CopilotForge now uses one Copilot SDK session per app chat thread.
High-level flow:
- Swift chat UI sends prompt with
chatID. - Sidecar maps that
chatIDto a deterministic SDKsessionId. - Sidecar uses
resumeSession(sessionId, ...)when available. - If resume fails, sidecar creates a new session with the same
sessionId. - Prompt is sent to that thread-bound session.
This prevents cross-thread context leakage and keeps chat context scoped to each app chat.
- Avoids manually replaying full message history every request.
- Uses SDK-native session persistence and lifecycle.
- Keeps context management stable as conversations grow.
- Reduces payload size and prompt duplication overhead.
Sidecar enables SDK infiniteSessions for compaction support.
Benefits:
- Large conversations are compacted automatically.
- Context-window pressure is handled by SDK internals.
- History continuity remains tied to session identity.
- Preferred key: app
chatID. - Fallback key: project path (for compatibility scenarios).
- Last fallback:
default.
The sidecar derives a deterministic sessionId from the key, e.g. copilotforge-<sanitized-key>.
- Switching model/project/tools for the same chat may recreate that chat’s in-memory session object, but it remains thread-scoped.
- Sidecar restart does not imply thread history loss when
resumeSessionsucceeds. - Local app message persistence remains in SwiftData for UI rendering and metadata.
-
Swift prompt pipeline:
mac-copilot/Features/Chat/Presentation/ChatViewModel.swiftmac-copilot/Features/Chat/Domain/UseCases/SendPromptUseCase.swiftmac-copilot/Features/Chat/Domain/Contracts/PromptStreamingRepository.swiftmac-copilot/Features/Chat/Data/CopilotPromptRepository.swiftmac-copilot/Features/Chat/Data/CopilotAPIService.swiftmac-copilot/Features/Chat/Data/CopilotPromptStreamClient.swift
-
Sidecar session management:
sidecar/src/index.tssidecar/src/copilot/copilot.ts