Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import type { AgentGUIConversationFilter } from "./agentGuiConversationFilter";
|
|
|
|
export const AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE = 5;
|
|
|
|
export type AgentGUIConversationRailRevealReason = "created" | "external-open";
|
|
|
|
export interface AgentGUIConversationRailRevealRequest {
|
|
agentSessionId: string;
|
|
reason: AgentGUIConversationRailRevealReason;
|
|
revision: number;
|
|
}
|
|
|
|
export interface AgentGUIConversationRailScopedViewState {
|
|
collapsedSectionIds: ReadonlySet<string>;
|
|
visibleItemLimitBySectionId: ReadonlyMap<string, number>;
|
|
}
|
|
|
|
export type AgentGUIConversationRailViewState = ReadonlyMap<
|
|
string,
|
|
AgentGUIConversationRailScopedViewState
|
|
>;
|
|
|
|
export type AgentGUIConversationRailViewStateAction =
|
|
| { scopeKey: string; sectionId: string; type: "section-collapsed-toggled" }
|
|
| {
|
|
limit: number;
|
|
scopeKey: string;
|
|
sectionId: string;
|
|
type: "section-visible-limit-set";
|
|
};
|
|
|
|
const EMPTY_SCOPED_RAIL_VIEW_STATE: AgentGUIConversationRailScopedViewState = {
|
|
collapsedSectionIds: new Set(),
|
|
visibleItemLimitBySectionId: new Map()
|
|
};
|
|
|
|
export function agentGUIConversationRailViewScopeKey(input: {
|
|
conversationFilter: AgentGUIConversationFilter;
|
|
workspaceId: string;
|
|
}): string {
|
|
const filterScope =
|
|
input.conversationFilter.kind === "agentTarget"
|
|
? `agentTarget:${input.conversationFilter.agentTargetId.trim()}`
|
|
: "all";
|
|
return `${input.workspaceId.trim()}:${filterScope}`;
|
|
}
|
|
|
|
export function agentGUIConversationRailScopedViewState(
|
|
state: AgentGUIConversationRailViewState,
|
|
scopeKey: string
|
|
): AgentGUIConversationRailScopedViewState {
|
|
return state.get(scopeKey) ?? EMPTY_SCOPED_RAIL_VIEW_STATE;
|
|
}
|
|
|
|
export function reduceAgentGUIConversationRailViewState(
|
|
state: AgentGUIConversationRailViewState,
|
|
action: AgentGUIConversationRailViewStateAction
|
|
): AgentGUIConversationRailViewState {
|
|
const current = agentGUIConversationRailScopedViewState(
|
|
state,
|
|
action.scopeKey
|
|
);
|
|
if (action.type === "section-collapsed-toggled") {
|
|
const collapsedSectionIds = new Set(current.collapsedSectionIds);
|
|
if (collapsedSectionIds.has(action.sectionId)) {
|
|
collapsedSectionIds.delete(action.sectionId);
|
|
} else {
|
|
collapsedSectionIds.add(action.sectionId);
|
|
}
|
|
const next = new Map(state);
|
|
next.set(action.scopeKey, { ...current, collapsedSectionIds });
|
|
return next;
|
|
}
|
|
const limit = Math.max(
|
|
AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE,
|
|
Math.floor(action.limit)
|
|
);
|
|
if (
|
|
(current.visibleItemLimitBySectionId.get(action.sectionId) ??
|
|
AGENT_GUI_CONVERSATION_RAIL_SECTION_PAGE_SIZE) === limit
|
|
) {
|
|
return state;
|
|
}
|
|
const visibleItemLimitBySectionId = new Map(
|
|
current.visibleItemLimitBySectionId
|
|
);
|
|
visibleItemLimitBySectionId.set(action.sectionId, limit);
|
|
const next = new Map(state);
|
|
next.set(action.scopeKey, { ...current, visibleItemLimitBySectionId });
|
|
return next;
|
|
}
|