feat: merge hidden-user turns and move message metadata to turn footer
- Remove assistant message headers; show provider icon, model, agent, thinking variant, duration and time in the turn footer (metadata left, hover-revealed actions right) - Merge turns started by hidden user messages (subagent nudges) into the previous turn so Activity, footer and spacing stay continuous - Treat compaction summary text (info.summary) as justification activity in sorted mode and skip it when picking the turn summary - Interleave activity segments with standalone tool rows so Agent Task sits chronologically between activity sections
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import type { Message, Part } from '@opencode-ai/sdk/v2';
|
||||
|
||||
import { deriveMessageRole } from './messageRole';
|
||||
import { filterVisibleParts, normalizeParts } from './partUtils';
|
||||
import { normalizeUserDisplayParts } from './normalizeUserDisplayParts';
|
||||
|
||||
/**
|
||||
* A user message is hidden when none of its parts survive display
|
||||
* normalization (e.g. synthetic subagent-completion nudges). Turns separated
|
||||
* only by such messages should render as one continuous flow.
|
||||
*/
|
||||
// Streaming recomputes turn projections often; cache by parts reference so
|
||||
// unchanged messages resolve without re-running display normalization.
|
||||
const hiddenByPartsPlanMode = new WeakMap<Part[], boolean>();
|
||||
const hiddenByPartsNoPlanMode = new WeakMap<Part[], boolean>();
|
||||
|
||||
export const isHiddenUserMessage = (
|
||||
entry: { info: Message; parts: Part[] } | null | undefined,
|
||||
options: { planModeEnabled: boolean }
|
||||
): boolean => {
|
||||
if (!entry) return false;
|
||||
if (!deriveMessageRole(entry.info).isUser) return false;
|
||||
|
||||
const cache = options.planModeEnabled ? hiddenByPartsPlanMode : hiddenByPartsNoPlanMode;
|
||||
const cached = cache.get(entry.parts);
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const parts = normalizeUserDisplayParts(normalizeParts(entry.parts), { planModeEnabled: options.planModeEnabled });
|
||||
const hidden = filterVisibleParts(parts, { includeReasoning: true }).length === 0;
|
||||
cache.set(entry.parts, hidden);
|
||||
return hidden;
|
||||
};
|
||||
Reference in New Issue
Block a user