Stable identity, stale-event rejection, and scoped notifications - #154
Closed
IeuanWalker wants to merge 10 commits into
Closed
Stable identity, stale-event rejection, and scoped notifications#154IeuanWalker wants to merge 10 commits into
IeuanWalker wants to merge 10 commits into
Conversation
Contributor
There was a problem hiding this comment.
⚠️ Not ready to approve
The new conversation snapshot helpers re-lock a System.Threading.Lock that is already held in multiple call sites, which can lead to self-deadlock and should be corrected before merging.
Pull request overview
This PR refactors session state to separate lifecycle/run-state from UI-visible “blocking” statuses, centralizes pending-interaction bookkeeping, and introduces reusable session-status presentation for the UI so status rendering is consistent across header and session list.
Changes:
- Introduces grouped session state (
Lifecycle,Conversation,Ui,PendingInteractions) and projects a UI-facingDisplayStatusfrom run state + pending interactions. - Adds
SessionInteractionCoordinatorand updates permission/user-input/elicitation features to use it for consistent cross-type pending interaction behavior. - Updates UI components to use the new state surfaces and consolidates status rendering via
SessionStatusBadge+SessionStatusPresentation, plus adds targeted unit tests for the new primitives.
File summaries
| File | Description |
|---|---|
| Tests/Cockpit.UnitTests/Features/UserInputRequests/UserInputFeatureTests.cs | Updates tests to validate run-state vs display-status behavior and new pending-interaction storage. |
| Tests/Cockpit.UnitTests/Features/Update/UpdateFeatureTests.cs | Updates “active session” checks to use lifecycle run state. |
| Tests/Cockpit.UnitTests/Features/Sessions/SessionUiStateTests.cs | Adds tests for per-session UI-scoped state forwarding and isolation. |
| Tests/Cockpit.UnitTests/Features/Sessions/SessionStatusBehaviourTests.cs | Adds tests for status presentation and concurrent interaction-type status transitions. |
| Tests/Cockpit.UnitTests/Features/Sessions/SessionListFeatureTests.cs | Updates session creation in tests to use lifecycle run state. |
| Tests/Cockpit.UnitTests/Features/Sessions/SessionLifecycleStateTests.cs | Adds tests for lifecycle transitions, stale transition rejection, and reset semantics. |
| Tests/Cockpit.UnitTests/Features/Sessions/SessionInteractionCoordinatorTests.cs | Adds tests for coordinator behavior (duplicates, notifications, resolution order, run-state reveal). |
| Tests/Cockpit.UnitTests/Features/Sessions/SessionConversationStateTests.cs | Adds tests for snapshot stability, message replacement/capacity behavior, and compatibility surface. |
| Tests/Cockpit.UnitTests/Features/SessionEvents/SessionEventProcessorTests.cs | Updates tests to set lifecycle run state rather than UI status. |
| Tests/Cockpit.UnitTests/Features/SessionEvents/Handlers/SessionShutdownHandlerTests.cs | Updates shutdown handler tests to set lifecycle run state. |
| Tests/Cockpit.UnitTests/Features/SessionEvents/Handlers/SessionIdleHandlerTests.cs | Updates idle handler tests to set lifecycle run state. |
| Tests/Cockpit.UnitTests/Features/Permissions/PermissionFeatureTests.cs | Updates tests for new lifecycle run-state property and revised comments. |
| Tests/Cockpit.UnitTests/Features/Models/ModelFeatureTests.cs | Updates tests to use lifecycle run state. |
| Tests/Cockpit.UnitTests/Features/ElicitationRequests/ElicitationFeatureTests.cs | Updates tests to use interaction coordinator + lifecycle run state and new pending-interaction store. |
| Tests/Cockpit.UnitTests/Features/Agents/AgentFeatureTests.cs | Updates tests to use lifecycle run state. |
| Tests/Cockpit.Benchmarks/SessionLoadingBenchmarks.cs | Updates benchmark session creation to use lifecycle run state. |
| src/Cockpit/MauiProgram.cs | Registers SessionInteractionCoordinator in DI. |
| src/Cockpit/Features/UserInputRequests/UserInputFeature.cs | Routes session bookkeeping through SessionInteractionCoordinator instead of direct status/history mutation. |
| src/Cockpit/Features/Updates/UpdateFeature.cs | Treats “active session” as lifecycle run-state running (not blocked UI status). |
| src/Cockpit/Features/Sessions/SessionFeature.SdkConfiguration.cs | Extracts system-message customization helpers into a dedicated partial file. |
| src/Cockpit/Features/Sessions/SessionFeature.Replay.cs | Extracts replay helper into a dedicated partial file and updates to conversation snapshot API. |
| src/Cockpit/Features/Sessions/SessionFeature.Reconnect.cs | Uses lifecycle SDK state transitions and clears pending interaction bookkeeping via coordinator on reconnect. |
| src/Cockpit/Features/Sessions/SessionFeature.Messages.cs | Uses lifecycle change-version capture/clear and conversation snapshot publishing for message sends/retries. |
| src/Cockpit/Features/Sessions/SessionFeature.Loading.cs | Reworks session load to use lifecycle transition tokens and conversation state APIs; adds context replay isolation. |
| src/Cockpit/Features/Sessions/SessionFeature.Lifecycle.cs | Removes large blocks moved to new partial files; updates remaining lifecycle-related logic to use Lifecycle. |
| src/Cockpit/Features/Sessions/SessionFeature.Eviction.cs | Uses lifecycle reset + conversation clearing and coordinator bookkeeping clear during eviction. |
| src/Cockpit/Features/Sessions/SessionFeature.Discovery.cs | Extracts existing-session discovery/metadata materialization into a dedicated partial file. |
| src/Cockpit/Features/Sessions/SessionFeature.cs | Updates event processing and “working” detection to use conversation/lifecycle grouped state. |
| src/Cockpit/Features/Sessions/SessionFeature.Creation.cs | Extracts session creation into a dedicated partial file and initializes lifecycle state. |
| src/Cockpit/Features/Sessions/Models/SessionUiState.cs | Adds a dedicated container for UI-owned, transient per-session state. |
| src/Cockpit/Features/Sessions/Models/SessionStatusEnum.cs | Re-documents status as UI-facing projection rather than lifecycle. |
| src/Cockpit/Features/Sessions/Models/SessionModel.UiCompatibility.cs | Adds compatibility properties mapping legacy callers to Ui. |
| src/Cockpit/Features/Sessions/Models/SessionModel.LifecycleCompatibility.cs | Adds compatibility properties mapping legacy callers to Lifecycle. |
| src/Cockpit/Features/Sessions/Models/SessionModel.cs | Converts SessionModel to partial and introduces grouped state + computed DisplayStatus. |
| src/Cockpit/Features/Sessions/Models/SessionModel.ConversationCompatibility.cs | Adds compatibility properties mapping legacy callers to Conversation. |
| src/Cockpit/Features/Sessions/Models/SessionLifecycleState.cs | Introduces lifecycle state object with versioned transitions and pending-change capture/clear. |
| src/Cockpit/Features/Sessions/Models/SessionConversationState.cs | Introduces conversation state object with published immutable message snapshots. |
| src/Cockpit/Features/Sessions/Models/AgentRunStateEnum.cs | Adds lifecycle run-state enum independent of pending interactions. |
| src/Cockpit/Features/Sessions/Interactions/SessionInteractionCoordinator.cs | Adds coordinator for consistent pending interaction bookkeeping and display-status overlay. |
| src/Cockpit/Features/Sessions/Interactions/PendingInteractionState.cs | Adds per-session pending interaction collections + display status storage. |
| src/Cockpit/Features/SessionEvents/SessionEventProcessor.cs | Writes lifecycle run state instead of UI status in reconnect-continuation handling. |
| src/Cockpit/Features/SessionEvents/Handlers/UserMessageHandler.cs | Writes lifecycle run state on user message handling. |
| src/Cockpit/Features/SessionEvents/Handlers/ThinkingExhaustedContinuationHandler.cs | Writes lifecycle run state on continuation handling. |
| src/Cockpit/Features/SessionEvents/Handlers/SessionIdleHandler.cs | Writes lifecycle run state on idle transitions and reads suppression flag from lifecycle. |
| src/Cockpit/Features/SessionEvents/Handlers/SessionErrorHandler.cs | Writes lifecycle run state on error transitions. |
| src/Cockpit/Features/SessionEvents/Handlers/AssistantTurnStartHandler.cs | Writes lifecycle run state on turn start. |
| src/Cockpit/Features/Permissions/PermissionFeature.cs | Routes pending permission bookkeeping through coordinator; reads YOLO from Ui. |
| src/Cockpit/Features/Models/ModelFeature.Persistence.cs | Marks model-change via lifecycle pending-change versioning instead of boolean flags. |
| src/Cockpit/Features/ElicitationRequests/ElicitationFeature.cs | Routes pending elicitation bookkeeping through coordinator. |
| src/Cockpit/Components/Pages/SessionsPanel/SessionListItem.razor.css | Removes now-redundant per-item status color rules (moved to badge component). |
| src/Cockpit/Components/Pages/SessionsPanel/SessionListItem.razor.cs | Removes status-class helper (replaced by shared badge component). |
| src/Cockpit/Components/Pages/SessionsPanel/SessionListItem.razor | Uses SessionStatusBadge and lifecycle SDK state for loading overlay. |
| src/Cockpit/Components/Pages/ContextPanel/TokenUsagePanel.razor.cs | Uses lifecycle run state for compaction disable/tooltip logic. |
| src/Cockpit/Components/Pages/ChatPanel/UserInputRequest/UserInputRequestPanel.razor.cs | Reads/writes user response text from Ui and pulls requests from PendingInteractions. |
| src/Cockpit/Components/Pages/ChatPanel/Permissions/PermissionRequestPanel.razor.cs | Pulls permission requests from PendingInteractions. |
| src/Cockpit/Components/Pages/ChatPanel/InputArea/SessionModeControl.razor.cs | Marks agent-mode change via lifecycle versioning. |
| src/Cockpit/Components/Pages/ChatPanel/InputArea/SessionModeControl.razor | Disables mode changes using DisplayStatus + pending permission interactions. |
| src/Cockpit/Components/Pages/ChatPanel/InputArea/ModelControl.razor.cs | Marks model changes via lifecycle versioning. |
| src/Cockpit/Components/Pages/ChatPanel/InputArea/ModelControl.razor | Disables model/reasoning changes using DisplayStatus and pending permissions. |
| src/Cockpit/Components/Pages/ChatPanel/InputArea/ChatInputArea.razor.cs | Uses Ui for draft/attachments/YOLO and PendingInteractions for input disablement. |
| src/Cockpit/Components/Pages/ChatPanel/InputArea/ChatInputArea.razor | Uses PendingInteractions and Ui.IsYolo for UI gating and button state. |
| src/Cockpit/Components/Pages/ChatPanel/InputArea/AttachmentsControl.razor.cs | Reads/writes attachments from Ui.PendingAttachments with Ui.PendingAttachmentsLock. |
| src/Cockpit/Components/Pages/ChatPanel/InputArea/AgentControl.razor.cs | Marks agent changes via lifecycle versioning. |
| src/Cockpit/Components/Pages/ChatPanel/InputArea/AgentControl.razor | Disables agent changes using DisplayStatus + pending permissions. |
| src/Cockpit/Components/Pages/ChatPanel/ElicitationRequest/ElicitationRequestPanel.razor.cs | Pulls elicitation requests from PendingInteractions. |
| src/Cockpit/Components/Pages/ChatPanel/ChatPanel.razor.cs | Tracks message counts using conversation snapshots and toggles terminal state via Ui. |
| src/Cockpit/Components/Pages/ChatPanel/ChatPanel.razor | Uses SessionStatusBadge for header status and Ui.IsTerminalOpen for terminal toggle. |
| src/Cockpit/Components/Pages/ChatPanel/ChatMessages.razor.cs | Uses conversation snapshots to decide initial scroll behavior. |
| src/Cockpit/Components/Pages/ChatPanel/ChatMessages.razor | Renders from conversation snapshot rather than mutable message list. |
| src/Cockpit/Components/Controls/SessionStatusVariant.cs | Adds display variants for the shared status badge. |
| src/Cockpit/Components/Controls/SessionStatusPresentation.cs | Centralizes status-to-text/class mapping for consistent UI rendering. |
| src/Cockpit/Components/Controls/SessionStatusBadge.razor.css | Consolidates header/list status styling into the badge component. |
| src/Cockpit/Components/Controls/SessionStatusBadge.razor | Adds shared component for session status display in header and session list. |
Review details
- Files reviewed: 73/73 changed files
- Comments generated: 1
- Review effort level: Low
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
Comment on lines
+22
to
+32
| /// <summary> | ||
| /// Publishes the current mutable message collection as an immutable render snapshot. | ||
| /// Existing callers may already hold <see cref="SyncRoot"/>; the lock is re-entrant. | ||
| /// </summary> | ||
| internal void PublishMessagesSnapshot() | ||
| { | ||
| lock(SyncRoot) | ||
| { | ||
| MessagesSnapshot = [.. _messages]; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.