@tutti-os/agent-gui 0.0.147 → 0.0.149
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -220,8 +220,9 @@ targets from presentation metadata.
|
|
|
220
220
|
|
|
221
221
|
Agent names, primary icons, optional conversation-mask icons, and optional
|
|
222
222
|
home-carousel artwork come from `agents[].name`, `agents[].iconUrl`,
|
|
223
|
-
`agents[].maskIconUrl`, and `agents[].heroImageUrl`.
|
|
224
|
-
|
|
223
|
+
`agents[].maskIconUrl`, and `agents[].heroImageUrl`. Hosts must pass fully
|
|
224
|
+
resolved presentation URLs from their authoritative directory. All identity
|
|
225
|
+
surfaces use `iconUrl`; conversation rows use `maskIconUrl` where present.
|
|
225
226
|
`owner.avatarUrl` is rendered separately as an ownership badge. Invalid entries
|
|
226
227
|
and duplicate `agentTargetId` values are discarded by
|
|
227
228
|
`normalizeAgentGUIAgents`, with the first occurrence preserving host order.
|
|
@@ -234,12 +235,10 @@ directly. With multiple agents, it shows `All` plus the host-ordered agent rail
|
|
|
234
235
|
and empty-home carousel. Hosts may customize the aggregate icon with
|
|
235
236
|
`allAgentsPresentation.iconUrl`.
|
|
236
237
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
keys return `null`; hosts should render a neutral icon rather than silently
|
|
242
|
-
substituting another provider's icon.
|
|
238
|
+
Daemon-owned system targets seed and refresh their `iconUrl` and `maskIconUrl`
|
|
239
|
+
from the target descriptor `iconKey`. AgentGUI consumers must not synthesize
|
|
240
|
+
built-in target icons from provider IDs or `iconKey`; stale or missing directory
|
|
241
|
+
presentation should be fixed in the source directory.
|
|
243
242
|
|
|
244
243
|
Hosts that need provider identity presentation may call
|
|
245
244
|
`resolveAgentGUIProviderIdentity(value)` from the narrow
|
|
@@ -176,6 +176,8 @@ interface WorkspaceAgentMessageCenterCardProps {
|
|
|
176
176
|
interactive?: boolean;
|
|
177
177
|
isSubmitting: boolean;
|
|
178
178
|
lazySummary?: boolean;
|
|
179
|
+
promptVariant?: "compact" | "full";
|
|
180
|
+
showSummaryWithPrompt?: boolean;
|
|
179
181
|
summaryAccessory?: ReactNode;
|
|
180
182
|
onLinkAction?: (action: WorkspaceLinkAction) => void;
|
|
181
183
|
onOpenChat: (input: {
|
|
@@ -471,14 +473,42 @@ declare function useEngineSelector<TState, TSelected>(engine: EngineStateStore<T
|
|
|
471
473
|
declare function buildWorkspaceAgentMessageCenterModelFromEngine(presentation: WorkspaceAgentMessageCenterPresentation, snapshot: Pick<AgentActivitySnapshot, "sessionMessagesById" | "workspaceId">, options?: BuildWorkspaceAgentMessageCenterOptions): WorkspaceAgentMessageCenterModel;
|
|
472
474
|
interface WorkspaceAgentMessageCenterPresentation {
|
|
473
475
|
consumers: readonly WorkspaceAgentConsumerSession[];
|
|
476
|
+
dismissedPlanTurnKeys: Readonly<Record<string, true>>;
|
|
474
477
|
promptStatusByKey: Readonly<Record<string, WorkspaceAgentMessageCenterPromptStatus>>;
|
|
475
478
|
}
|
|
476
479
|
declare function selectWorkspaceAgentMessageCenterPresentation(state: AgentSessionEngineState): WorkspaceAgentMessageCenterPresentation;
|
|
477
480
|
declare function workspaceAgentMessageCenterPresentationEqual(left: WorkspaceAgentMessageCenterPresentation, right: WorkspaceAgentMessageCenterPresentation): boolean;
|
|
481
|
+
type WorkspaceAgentAttentionTarget = {
|
|
482
|
+
kind: "interaction";
|
|
483
|
+
workspaceId: string;
|
|
484
|
+
agentSessionId: string;
|
|
485
|
+
turnId: string;
|
|
486
|
+
requestId: string;
|
|
487
|
+
} | {
|
|
488
|
+
kind: "plan-implementation";
|
|
489
|
+
workspaceId: string;
|
|
490
|
+
agentSessionId: string;
|
|
491
|
+
turnId: string;
|
|
492
|
+
requestId: string;
|
|
493
|
+
};
|
|
494
|
+
interface WorkspaceAgentAttentionItem {
|
|
495
|
+
item: WorkspaceAgentMessageCenterItem;
|
|
496
|
+
status: WorkspaceAgentMessageCenterPromptStatus;
|
|
497
|
+
target: WorkspaceAgentAttentionTarget;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Projects every canonical actionable target instead of collapsing a root
|
|
501
|
+
* conversation to its latest interaction. The display item keeps the root
|
|
502
|
+
* conversation identity for navigation while target keeps the exact child
|
|
503
|
+
* session/turn/request identity used by the command.
|
|
504
|
+
*/
|
|
505
|
+
declare function selectWorkspaceAgentAttentionItems(presentation: WorkspaceAgentMessageCenterPresentation, snapshot: Pick<AgentActivitySnapshot, "sessionMessagesById" | "workspaceId">, options?: BuildWorkspaceAgentMessageCenterOptions): WorkspaceAgentAttentionItem[];
|
|
506
|
+
declare function workspaceAgentAttentionItemsEqual(left: readonly WorkspaceAgentAttentionItem[], right: readonly WorkspaceAgentAttentionItem[]): boolean;
|
|
478
507
|
type WorkspaceAgentMessageCenterPromptStatus = "idle" | "responding" | "unknown" | "failed";
|
|
479
508
|
declare function workspaceAgentMessageCenterPromptStatus(presentation: WorkspaceAgentMessageCenterPresentation, item: Pick<WorkspaceAgentMessageCenterItem, "agentSessionId" | "pendingInteractionTarget" | "pendingPrompt">): WorkspaceAgentMessageCenterPromptStatus;
|
|
480
509
|
|
|
481
510
|
declare function stabilizeWorkspaceAgentMessageCenterModel(previous: WorkspaceAgentMessageCenterModel | null, next: WorkspaceAgentMessageCenterModel): WorkspaceAgentMessageCenterModel;
|
|
511
|
+
declare function workspaceAgentMessageCenterItemEqual(left: WorkspaceAgentMessageCenterItem, right: WorkspaceAgentMessageCenterItem): boolean;
|
|
482
512
|
|
|
483
513
|
declare const messageCenterFiltersStorageKey = "tutti.agent-message-center.filters";
|
|
484
514
|
interface MessageCenterFilterPreferences {
|
|
@@ -489,4 +519,4 @@ interface MessageCenterFilterPreferences {
|
|
|
489
519
|
declare function readMessageCenterFilterPreferences(): MessageCenterFilterPreferences;
|
|
490
520
|
declare function writeMessageCenterFilterPreferences(preferences: MessageCenterFilterPreferences): void;
|
|
491
521
|
|
|
492
|
-
export { AgentInteractivePromptSurface, AgentVerticalScrollArea, type BuildWorkspaceAgentMessageCenterOptions, type MessageCenterAgentUserStack, type MessageCenterFilterPreferences, type MessageCenterGroup, type MessageCenterGroupBy, MessageCenterGroupHeading, MessageCenterIdentityAvatarMark, MessageCenterIdentityAvatarStack, MessageCenterIdentityLabel, MessageCenterOpenChatButton, type MessageCenterProviderOption, type MessageCenterStatusFilter, type MessageCenterStatusOption, type MessageCenterStatusTone, MessageCenterSummary, type MessageCenterTranslate, PLAN_IMPLEMENTATION_ACTION_IMPLEMENT, PLAN_IMPLEMENTATION_PROMPT, type PromptToolDetail, type WorkspaceAgentMessageCenterAgentPresentation, WorkspaceAgentMessageCenterAttentionDeck, type WorkspaceAgentMessageCenterAttentionDeckProps, type WorkspaceAgentMessageCenterAttentionDeckRenderCardInput, WorkspaceAgentMessageCenterCard, type WorkspaceAgentMessageCenterCardProps, type WorkspaceAgentMessageCenterCounts, type WorkspaceAgentMessageCenterDigest, type WorkspaceAgentMessageCenterDigestPrimary, type WorkspaceAgentMessageCenterDigestPrimaryKind, type WorkspaceAgentMessageCenterIdentity, type WorkspaceAgentMessageCenterInteractionTarget, type WorkspaceAgentMessageCenterItem, type WorkspaceAgentMessageCenterModel, WorkspaceAgentMessageCenterPanel, type WorkspaceAgentMessageCenterPanelPresentation, type WorkspaceAgentMessageCenterPanelProps, type WorkspaceAgentMessageCenterPresentation, type WorkspaceAgentMessageCenterPromptStatus, WorkspaceAgentMessageCenterStack, MessageCenterViewMenu as WorkspaceAgentMessageCenterViewMenu, approvalOptionDisplayLabel, buildMessageCenterProviderOptions, buildMessageCenterStatusOptions, buildWorkspaceAgentInteractivePromptLabels, buildWorkspaceAgentMessageCenterModelFromEngine, dispatchAgentPlanPromptAction, getPromptToolDetails, groupMessageCenterItems, isInteractiveMessageCenterItem, isPromptRequestIdTitle, isRecentlyCompletedMessageCenterItem, isWaitingMessageCenterItem, itemMatchesViewFilters, managedAgentRoundedIconUrl, messageCenterAgentUserStackId, messageCenterFiltersStorageKey, messageCenterGroupLabel, messageCenterStackPreviewNodes, messageCenterStackPreviewText, messageCenterStackRenderId, messageCenterStackScrollSyncSegment, messageCenterStatusFilterValue, messageCenterStatusTone, messageCenterStatusToneClass, partitionMessageCenterItemsByAgentUser, readMessageCenterFilterPreferences, resolveMessageCenterNotificationAction, selectMessageCenterAttentionDeckItems, selectWorkspaceAgentMessageCenterPresentation, stabilizeWorkspaceAgentMessageCenterModel, statusFilterSummary, useEngineSelector, userAvatarPlaceholderUrl, workspaceAgentActivityStatusLabel, workspaceAgentMessageCenterPresentationEqual, workspaceAgentMessageCenterPromptStatus, writeMessageCenterFilterPreferences };
|
|
522
|
+
export { AgentInteractivePromptSurface, AgentVerticalScrollArea, type BuildWorkspaceAgentMessageCenterOptions, type MessageCenterAgentUserStack, type MessageCenterFilterPreferences, type MessageCenterGroup, type MessageCenterGroupBy, MessageCenterGroupHeading, MessageCenterIdentityAvatarMark, MessageCenterIdentityAvatarStack, MessageCenterIdentityLabel, MessageCenterOpenChatButton, type MessageCenterProviderOption, type MessageCenterStatusFilter, type MessageCenterStatusOption, type MessageCenterStatusTone, MessageCenterSummary, type MessageCenterTranslate, PLAN_IMPLEMENTATION_ACTION_IMPLEMENT, PLAN_IMPLEMENTATION_PROMPT, type PromptToolDetail, type WorkspaceAgentAttentionItem, type WorkspaceAgentAttentionTarget, type WorkspaceAgentMessageCenterAgentPresentation, WorkspaceAgentMessageCenterAttentionDeck, type WorkspaceAgentMessageCenterAttentionDeckProps, type WorkspaceAgentMessageCenterAttentionDeckRenderCardInput, WorkspaceAgentMessageCenterCard, type WorkspaceAgentMessageCenterCardProps, type WorkspaceAgentMessageCenterCounts, type WorkspaceAgentMessageCenterDigest, type WorkspaceAgentMessageCenterDigestPrimary, type WorkspaceAgentMessageCenterDigestPrimaryKind, type WorkspaceAgentMessageCenterIdentity, type WorkspaceAgentMessageCenterInteractionTarget, type WorkspaceAgentMessageCenterItem, type WorkspaceAgentMessageCenterModel, WorkspaceAgentMessageCenterPanel, type WorkspaceAgentMessageCenterPanelPresentation, type WorkspaceAgentMessageCenterPanelProps, type WorkspaceAgentMessageCenterPresentation, type WorkspaceAgentMessageCenterPromptStatus, WorkspaceAgentMessageCenterStack, MessageCenterViewMenu as WorkspaceAgentMessageCenterViewMenu, approvalOptionDisplayLabel, buildMessageCenterProviderOptions, buildMessageCenterStatusOptions, buildWorkspaceAgentInteractivePromptLabels, buildWorkspaceAgentMessageCenterModelFromEngine, dispatchAgentPlanPromptAction, getPromptToolDetails, groupMessageCenterItems, isInteractiveMessageCenterItem, isPromptRequestIdTitle, isRecentlyCompletedMessageCenterItem, isWaitingMessageCenterItem, itemMatchesViewFilters, managedAgentRoundedIconUrl, messageCenterAgentUserStackId, messageCenterFiltersStorageKey, messageCenterGroupLabel, messageCenterStackPreviewNodes, messageCenterStackPreviewText, messageCenterStackRenderId, messageCenterStackScrollSyncSegment, messageCenterStatusFilterValue, messageCenterStatusTone, messageCenterStatusToneClass, partitionMessageCenterItemsByAgentUser, readMessageCenterFilterPreferences, resolveMessageCenterNotificationAction, selectMessageCenterAttentionDeckItems, selectWorkspaceAgentAttentionItems, selectWorkspaceAgentMessageCenterPresentation, stabilizeWorkspaceAgentMessageCenterModel, statusFilterSummary, useEngineSelector, userAvatarPlaceholderUrl, workspaceAgentActivityStatusLabel, workspaceAgentAttentionItemsEqual, workspaceAgentMessageCenterItemEqual, workspaceAgentMessageCenterPresentationEqual, workspaceAgentMessageCenterPromptStatus, writeMessageCenterFilterPreferences };
|
|
@@ -5,7 +5,9 @@ import {
|
|
|
5
5
|
approvalOptionDisplayLabel,
|
|
6
6
|
dispatchAgentPlanPromptAction,
|
|
7
7
|
getPromptToolDetails,
|
|
8
|
-
isPromptRequestIdTitle
|
|
8
|
+
isPromptRequestIdTitle,
|
|
9
|
+
latestPlanTurnId,
|
|
10
|
+
planImplementationPromptFromPlanTurn
|
|
9
11
|
} from "../chunk-OEC2IIWG.js";
|
|
10
12
|
import {
|
|
11
13
|
useEngineSelector
|
|
@@ -1517,6 +1519,8 @@ var WorkspaceAgentMessageCenterCard = memo(
|
|
|
1517
1519
|
item,
|
|
1518
1520
|
isSubmitting,
|
|
1519
1521
|
lazySummary = false,
|
|
1522
|
+
promptVariant = "compact",
|
|
1523
|
+
showSummaryWithPrompt = true,
|
|
1520
1524
|
summaryAccessory,
|
|
1521
1525
|
onLinkAction,
|
|
1522
1526
|
onOpenChat,
|
|
@@ -1594,7 +1598,7 @@ var WorkspaceAgentMessageCenterCard = memo(
|
|
|
1594
1598
|
)
|
|
1595
1599
|
] })
|
|
1596
1600
|
] }),
|
|
1597
|
-
summary ? /* @__PURE__ */ jsx4(
|
|
1601
|
+
summary && (showSummaryWithPrompt || !prompt || !interactive) ? /* @__PURE__ */ jsx4(
|
|
1598
1602
|
MessageCenterSummary,
|
|
1599
1603
|
{
|
|
1600
1604
|
item,
|
|
@@ -1609,7 +1613,7 @@ var WorkspaceAgentMessageCenterCard = memo(
|
|
|
1609
1613
|
AgentInteractivePromptSurface,
|
|
1610
1614
|
{
|
|
1611
1615
|
embedded: true,
|
|
1612
|
-
variant:
|
|
1616
|
+
variant: promptVariant,
|
|
1613
1617
|
keyboardShortcuts: false,
|
|
1614
1618
|
prompt,
|
|
1615
1619
|
isSubmitting,
|
|
@@ -3450,8 +3454,155 @@ import {
|
|
|
3450
3454
|
selectEngineInteractionResponse,
|
|
3451
3455
|
selectPendingSubmitsForSession,
|
|
3452
3456
|
selectPlanDecisionForTurn,
|
|
3457
|
+
selectPlanTurnDismissed,
|
|
3453
3458
|
selectWorkspaceAgentRootConversationSessions
|
|
3454
3459
|
} from "@tutti-os/agent-activity-core";
|
|
3460
|
+
|
|
3461
|
+
// agent-message-center/workspaceAgentMessageCenterModelStability.ts
|
|
3462
|
+
function stabilizeWorkspaceAgentMessageCenterModel(previous, next) {
|
|
3463
|
+
if (!previous) {
|
|
3464
|
+
return next;
|
|
3465
|
+
}
|
|
3466
|
+
const previousItemsById = new Map(
|
|
3467
|
+
previous.items.map((item) => [item.id, item])
|
|
3468
|
+
);
|
|
3469
|
+
let itemsChanged = previous.items.length !== next.items.length;
|
|
3470
|
+
const items = next.items.map((nextItem, index) => {
|
|
3471
|
+
const previousItem = previousItemsById.get(nextItem.id);
|
|
3472
|
+
const stableItem = previousItem && workspaceAgentMessageCenterItemEqual(previousItem, nextItem) ? previousItem : nextItem;
|
|
3473
|
+
if (stableItem !== previous.items[index]) {
|
|
3474
|
+
itemsChanged = true;
|
|
3475
|
+
}
|
|
3476
|
+
return stableItem;
|
|
3477
|
+
});
|
|
3478
|
+
const stableItems = itemsChanged ? items : previous.items;
|
|
3479
|
+
const stableCounts = messageCenterCountsEqual(previous.counts, next.counts) ? previous.counts : next.counts;
|
|
3480
|
+
if (previous.waitingCount === next.waitingCount && stableItems === previous.items && stableCounts === previous.counts) {
|
|
3481
|
+
return previous;
|
|
3482
|
+
}
|
|
3483
|
+
return {
|
|
3484
|
+
...next,
|
|
3485
|
+
counts: stableCounts,
|
|
3486
|
+
items: stableItems
|
|
3487
|
+
};
|
|
3488
|
+
}
|
|
3489
|
+
function workspaceAgentMessageCenterItemEqual(left, right) {
|
|
3490
|
+
return left.id === right.id && left.agentSessionId === right.agentSessionId && left.agentTargetId === right.agentTargetId && left.agentName === right.agentName && left.agentAvatarUrl === right.agentAvatarUrl && left.provider === right.provider && left.userId === right.userId && left.title === right.title && left.imported === right.imported && left.cwd === right.cwd && left.status === right.status && left.lastAgentMessageSummary === right.lastAgentMessageSummary && left.lastAgentMessageAtUnixMs === right.lastAgentMessageAtUnixMs && messageCenterInteractionTargetEqual(
|
|
3491
|
+
left.pendingInteractionTarget,
|
|
3492
|
+
right.pendingInteractionTarget
|
|
3493
|
+
) && left.needsAttentionKind === right.needsAttentionKind && left.needsAttentionSummary === right.needsAttentionSummary && left.sortTimeUnixMs === right.sortTimeUnixMs && messageCenterIdentityEqual(left.identity, right.identity) && messageCenterDigestEqual(left.digest, right.digest) && messageCenterPromptEqual(left.pendingPrompt, right.pendingPrompt) && messageCenterTurnOutcomeEqual(
|
|
3494
|
+
left.latestTurnOutcome ?? null,
|
|
3495
|
+
right.latestTurnOutcome ?? null
|
|
3496
|
+
);
|
|
3497
|
+
}
|
|
3498
|
+
function messageCenterInteractionTargetEqual(left, right) {
|
|
3499
|
+
return left === right || left !== null && right !== null && left.agentSessionId === right.agentSessionId && left.turnId === right.turnId && left.requestId === right.requestId;
|
|
3500
|
+
}
|
|
3501
|
+
function messageCenterCountsEqual(left, right) {
|
|
3502
|
+
return left.all === right.all && left.working === right.working && left.waiting === right.waiting && left.completed === right.completed && left.failed === right.failed;
|
|
3503
|
+
}
|
|
3504
|
+
function messageCenterIdentityEqual(left, right) {
|
|
3505
|
+
if (left === right) {
|
|
3506
|
+
return true;
|
|
3507
|
+
}
|
|
3508
|
+
if (!left || !right) {
|
|
3509
|
+
return false;
|
|
3510
|
+
}
|
|
3511
|
+
return left.userName === right.userName && left.userAvatarUrl === right.userAvatarUrl && left.agentName === right.agentName && left.agentAvatarUrl === right.agentAvatarUrl;
|
|
3512
|
+
}
|
|
3513
|
+
function messageCenterDigestEqual(left, right) {
|
|
3514
|
+
return left.primary.kind === right.primary.kind && left.primary.summary === right.primary.summary && left.primary.occurredAtUnixMs === right.primary.occurredAtUnixMs;
|
|
3515
|
+
}
|
|
3516
|
+
function messageCenterTurnOutcomeEqual(left, right) {
|
|
3517
|
+
if (left === right) {
|
|
3518
|
+
return true;
|
|
3519
|
+
}
|
|
3520
|
+
if (!left || !right) {
|
|
3521
|
+
return false;
|
|
3522
|
+
}
|
|
3523
|
+
return left.notificationKey === right.notificationKey && left.status === right.status && left.turnId === right.turnId;
|
|
3524
|
+
}
|
|
3525
|
+
function messageCenterPromptEqual(left, right) {
|
|
3526
|
+
if (left === right) {
|
|
3527
|
+
return true;
|
|
3528
|
+
}
|
|
3529
|
+
if (!left || !right || left.kind !== right.kind) {
|
|
3530
|
+
return false;
|
|
3531
|
+
}
|
|
3532
|
+
switch (left.kind) {
|
|
3533
|
+
case "approval":
|
|
3534
|
+
return right.kind === "approval" && left.id === right.id && left.turnId === right.turnId && left.requestId === right.requestId && left.callId === right.callId && left.title === right.title && left.toolName === right.toolName && left.status === right.status && left.occurredAtUnixMs === right.occurredAtUnixMs && messageCenterJsonValueEqual(left.input, right.input) && messageCenterJsonValueEqual(
|
|
3535
|
+
left.output ?? null,
|
|
3536
|
+
right.output ?? null
|
|
3537
|
+
) && messageCenterApprovalOptionsEqual(left.options, right.options);
|
|
3538
|
+
case "ask-user":
|
|
3539
|
+
return right.kind === "ask-user" && left.requestId === right.requestId && left.title === right.title && messageCenterAskUserQuestionsEqual(left.questions, right.questions);
|
|
3540
|
+
case "exit-plan":
|
|
3541
|
+
return right.kind === "exit-plan" && left.requestId === right.requestId && left.title === right.title && left.keepPlanningOptionId === right.keepPlanningOptionId && messageCenterApprovalOptionsEqual(left.options, right.options);
|
|
3542
|
+
case "plan-implementation":
|
|
3543
|
+
return right.kind === "plan-implementation" && left.requestId === right.requestId && left.title === right.title;
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
function messageCenterApprovalOptionsEqual(left, right) {
|
|
3547
|
+
if (left.length !== right.length) {
|
|
3548
|
+
return false;
|
|
3549
|
+
}
|
|
3550
|
+
return left.every((option, index) => {
|
|
3551
|
+
const rightOption = right[index];
|
|
3552
|
+
return rightOption && option.id === rightOption.id && option.label === rightOption.label && option.kind === rightOption.kind && option.description === rightOption.description;
|
|
3553
|
+
});
|
|
3554
|
+
}
|
|
3555
|
+
function messageCenterAskUserQuestionsEqual(left, right) {
|
|
3556
|
+
if (left.length !== right.length) {
|
|
3557
|
+
return false;
|
|
3558
|
+
}
|
|
3559
|
+
return left.every((question, index) => {
|
|
3560
|
+
const rightQuestion = right[index];
|
|
3561
|
+
return rightQuestion && question.id === rightQuestion.id && question.header === rightQuestion.header && question.question === rightQuestion.question && question.multiSelect === rightQuestion.multiSelect && messageCenterAnswerEqual(
|
|
3562
|
+
question.answer ?? null,
|
|
3563
|
+
rightQuestion.answer ?? null
|
|
3564
|
+
) && question.options.length === rightQuestion.options.length && question.options.every((option, optionIndex) => {
|
|
3565
|
+
const rightOption = rightQuestion.options[optionIndex];
|
|
3566
|
+
return rightOption && option.label === rightOption.label && option.description === rightOption.description;
|
|
3567
|
+
});
|
|
3568
|
+
});
|
|
3569
|
+
}
|
|
3570
|
+
function messageCenterAnswerEqual(left, right) {
|
|
3571
|
+
if (left === right) {
|
|
3572
|
+
return true;
|
|
3573
|
+
}
|
|
3574
|
+
if (!Array.isArray(left) || !Array.isArray(right)) {
|
|
3575
|
+
return false;
|
|
3576
|
+
}
|
|
3577
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
3578
|
+
}
|
|
3579
|
+
function messageCenterJsonValueEqual(left, right) {
|
|
3580
|
+
if (left === right) {
|
|
3581
|
+
return true;
|
|
3582
|
+
}
|
|
3583
|
+
if (!left || !right || typeof left !== "object" || typeof right !== "object") {
|
|
3584
|
+
return false;
|
|
3585
|
+
}
|
|
3586
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
3587
|
+
if (!Array.isArray(left) || !Array.isArray(right)) {
|
|
3588
|
+
return false;
|
|
3589
|
+
}
|
|
3590
|
+
return left.length === right.length && left.every(
|
|
3591
|
+
(value, index) => messageCenterJsonValueEqual(value, right[index])
|
|
3592
|
+
);
|
|
3593
|
+
}
|
|
3594
|
+
const leftRecord = left;
|
|
3595
|
+
const rightRecord = right;
|
|
3596
|
+
const leftKeys = Object.keys(leftRecord);
|
|
3597
|
+
if (leftKeys.length !== Object.keys(rightRecord).length) {
|
|
3598
|
+
return false;
|
|
3599
|
+
}
|
|
3600
|
+
return leftKeys.every(
|
|
3601
|
+
(key) => messageCenterJsonValueEqual(leftRecord[key], rightRecord[key])
|
|
3602
|
+
);
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3605
|
+
// agent-message-center/workspaceAgentMessageCenterEngineModel.ts
|
|
3455
3606
|
function buildWorkspaceAgentMessageCenterModelFromEngine(presentation, snapshot, options = {}) {
|
|
3456
3607
|
const items = presentation.consumers.filter((consumer) => consumer.session.visible !== false).map((consumer) => {
|
|
3457
3608
|
const interaction = latestPendingInteraction(consumer);
|
|
@@ -3476,6 +3627,7 @@ function buildWorkspaceAgentMessageCenterModelFromEngine(presentation, snapshot,
|
|
|
3476
3627
|
function selectWorkspaceAgentMessageCenterPresentation(state) {
|
|
3477
3628
|
const consumers = selectWorkspaceAgentRootConversationSessions(state);
|
|
3478
3629
|
const promptStatusByKey = {};
|
|
3630
|
+
const dismissedPlanTurnKeys = {};
|
|
3479
3631
|
for (const consumer of consumers) {
|
|
3480
3632
|
const sessionId = consumer.session.agentSessionId;
|
|
3481
3633
|
for (const interaction of consumer.pendingInteractions) {
|
|
@@ -3495,6 +3647,9 @@ function selectWorkspaceAgentMessageCenterPresentation(state) {
|
|
|
3495
3647
|
}
|
|
3496
3648
|
const turnId = consumer.latestTurn?.turnId ?? "";
|
|
3497
3649
|
if (!turnId) continue;
|
|
3650
|
+
if (selectPlanTurnDismissed(state, sessionId, turnId)) {
|
|
3651
|
+
dismissedPlanTurnKeys[promptStatusKey(sessionId, turnId, turnId)] = true;
|
|
3652
|
+
}
|
|
3498
3653
|
const decision = selectPlanDecisionForTurn(state, sessionId, turnId);
|
|
3499
3654
|
if (decision) {
|
|
3500
3655
|
promptStatusByKey[promptStatusKey(sessionId, turnId, turnId)] = decision.status === "requested" ? "responding" : decision.status;
|
|
@@ -3516,17 +3671,128 @@ function selectWorkspaceAgentMessageCenterPresentation(state) {
|
|
|
3516
3671
|
}
|
|
3517
3672
|
return {
|
|
3518
3673
|
consumers,
|
|
3674
|
+
dismissedPlanTurnKeys,
|
|
3519
3675
|
promptStatusByKey
|
|
3520
3676
|
};
|
|
3521
3677
|
}
|
|
3522
3678
|
function workspaceAgentMessageCenterPresentationEqual(left, right) {
|
|
3523
|
-
return promptStatusMapsEqual(left.promptStatusByKey, right.promptStatusByKey) && left.consumers.length === right.consumers.length && left.consumers.every((item, index) => {
|
|
3679
|
+
return booleanMapsEqual(left.dismissedPlanTurnKeys, right.dismissedPlanTurnKeys) && promptStatusMapsEqual(left.promptStatusByKey, right.promptStatusByKey) && left.consumers.length === right.consumers.length && left.consumers.every((item, index) => {
|
|
3524
3680
|
const candidate = right.consumers[index];
|
|
3525
3681
|
return candidate !== void 0 && item.session === candidate.session && item.activeTurn === candidate.activeTurn && item.latestTurn === candidate.latestTurn && item.displayStatus === candidate.displayStatus && item.pendingInteractions.length === candidate.pendingInteractions.length && item.pendingInteractions.every(
|
|
3526
3682
|
(interaction, interactionIndex) => interaction === candidate.pendingInteractions[interactionIndex]
|
|
3527
3683
|
);
|
|
3528
3684
|
});
|
|
3529
3685
|
}
|
|
3686
|
+
function selectWorkspaceAgentAttentionItems(presentation, snapshot, options = {}) {
|
|
3687
|
+
const result = [];
|
|
3688
|
+
for (const consumer of presentation.consumers) {
|
|
3689
|
+
if (consumer.session.visible === false || consumer.session.workspaceId !== snapshot.workspaceId) {
|
|
3690
|
+
continue;
|
|
3691
|
+
}
|
|
3692
|
+
const messages = sessionMessages(snapshot.sessionMessagesById, consumer);
|
|
3693
|
+
for (const interaction of consumer.pendingInteractions) {
|
|
3694
|
+
const prompt2 = promptFromInteraction(interaction);
|
|
3695
|
+
if (!prompt2) continue;
|
|
3696
|
+
const target2 = {
|
|
3697
|
+
kind: "interaction",
|
|
3698
|
+
workspaceId: consumer.session.workspaceId,
|
|
3699
|
+
agentSessionId: interaction.agentSessionId,
|
|
3700
|
+
turnId: interaction.turnId,
|
|
3701
|
+
requestId: interaction.requestId
|
|
3702
|
+
};
|
|
3703
|
+
const item2 = buildWorkspaceAgentMessageCenterItem({
|
|
3704
|
+
session: consumer.session,
|
|
3705
|
+
latestTurn: consumer.latestTurn,
|
|
3706
|
+
messages,
|
|
3707
|
+
status: "waiting",
|
|
3708
|
+
needsAttention: needsAttentionFromInteraction(consumer, interaction),
|
|
3709
|
+
pendingInteractionTarget: interactionTarget(interaction),
|
|
3710
|
+
pendingPrompt: prompt2,
|
|
3711
|
+
latestTurnOutcome: null,
|
|
3712
|
+
options
|
|
3713
|
+
});
|
|
3714
|
+
item2.id = workspaceAgentAttentionKey(target2);
|
|
3715
|
+
item2.sortTimeUnixMs = interaction.createdAtUnixMs;
|
|
3716
|
+
result.push({
|
|
3717
|
+
item: item2,
|
|
3718
|
+
status: presentation.promptStatusByKey[promptStatusKey(
|
|
3719
|
+
interaction.agentSessionId,
|
|
3720
|
+
interaction.turnId,
|
|
3721
|
+
interaction.requestId
|
|
3722
|
+
)] ?? "idle",
|
|
3723
|
+
target: target2
|
|
3724
|
+
});
|
|
3725
|
+
}
|
|
3726
|
+
const latestTurn = consumer.latestTurn;
|
|
3727
|
+
if (latestTurn?.phase !== "settled" || latestTurn.outcome !== "completed" || consumer.session.capabilities?.planImplementation !== true || consumer.session.capabilities.planMode !== true || latestPlanTurnId(messages) !== latestTurn.turnId) {
|
|
3728
|
+
continue;
|
|
3729
|
+
}
|
|
3730
|
+
const target = {
|
|
3731
|
+
kind: "plan-implementation",
|
|
3732
|
+
workspaceId: consumer.session.workspaceId,
|
|
3733
|
+
agentSessionId: consumer.session.agentSessionId,
|
|
3734
|
+
turnId: latestTurn.turnId,
|
|
3735
|
+
requestId: latestTurn.turnId
|
|
3736
|
+
};
|
|
3737
|
+
const statusKey = promptStatusKey(
|
|
3738
|
+
target.agentSessionId,
|
|
3739
|
+
target.turnId,
|
|
3740
|
+
target.requestId
|
|
3741
|
+
);
|
|
3742
|
+
if (presentation.dismissedPlanTurnKeys[statusKey]) continue;
|
|
3743
|
+
const prompt = planImplementationPromptFromPlanTurn(
|
|
3744
|
+
latestTurn.turnId,
|
|
3745
|
+
consumer.session.title
|
|
3746
|
+
);
|
|
3747
|
+
const needsAttention = {
|
|
3748
|
+
id: `plan-implementation:${latestTurn.turnId}`,
|
|
3749
|
+
workspaceId: consumer.session.workspaceId,
|
|
3750
|
+
agentSessionId: consumer.session.agentSessionId,
|
|
3751
|
+
provider: consumer.session.provider,
|
|
3752
|
+
title: prompt.title,
|
|
3753
|
+
cwd: consumer.session.cwd,
|
|
3754
|
+
kind: "constraint",
|
|
3755
|
+
summary: prompt.title,
|
|
3756
|
+
occurredAtUnixMs: latestTurn.settledAtUnixMs ?? latestTurn.updatedAtUnixMs
|
|
3757
|
+
};
|
|
3758
|
+
const item = buildWorkspaceAgentMessageCenterItem({
|
|
3759
|
+
session: consumer.session,
|
|
3760
|
+
latestTurn,
|
|
3761
|
+
messages,
|
|
3762
|
+
status: "waiting",
|
|
3763
|
+
needsAttention,
|
|
3764
|
+
pendingInteractionTarget: null,
|
|
3765
|
+
pendingPrompt: prompt,
|
|
3766
|
+
latestTurnOutcome: null,
|
|
3767
|
+
options
|
|
3768
|
+
});
|
|
3769
|
+
item.id = workspaceAgentAttentionKey(target);
|
|
3770
|
+
item.sortTimeUnixMs = needsAttention.occurredAtUnixMs;
|
|
3771
|
+
result.push({
|
|
3772
|
+
item,
|
|
3773
|
+
status: presentation.promptStatusByKey[statusKey] ?? "idle",
|
|
3774
|
+
target
|
|
3775
|
+
});
|
|
3776
|
+
}
|
|
3777
|
+
return result;
|
|
3778
|
+
}
|
|
3779
|
+
function workspaceAgentAttentionItemsEqual(left, right) {
|
|
3780
|
+
return left.length === right.length && left.every((entry, index) => {
|
|
3781
|
+
const candidate = right[index];
|
|
3782
|
+
return candidate !== void 0 && entry.status === candidate.status && workspaceAgentAttentionTargetEqual(entry.target, candidate.target) && workspaceAgentMessageCenterItemEqual(entry.item, candidate.item);
|
|
3783
|
+
});
|
|
3784
|
+
}
|
|
3785
|
+
function workspaceAgentAttentionKey(target) {
|
|
3786
|
+
return [
|
|
3787
|
+
target.workspaceId,
|
|
3788
|
+
target.agentSessionId,
|
|
3789
|
+
target.turnId,
|
|
3790
|
+
target.requestId
|
|
3791
|
+
].join("\n");
|
|
3792
|
+
}
|
|
3793
|
+
function workspaceAgentAttentionTargetEqual(left, right) {
|
|
3794
|
+
return left.kind === right.kind && left.workspaceId === right.workspaceId && left.agentSessionId === right.agentSessionId && left.turnId === right.turnId && left.requestId === right.requestId;
|
|
3795
|
+
}
|
|
3530
3796
|
function workspaceAgentMessageCenterPromptStatus(presentation, item) {
|
|
3531
3797
|
const prompt = item.pendingPrompt;
|
|
3532
3798
|
if (!prompt) return "idle";
|
|
@@ -3548,6 +3814,10 @@ function promptStatusMapsEqual(left, right) {
|
|
|
3548
3814
|
const keys = Object.keys(left);
|
|
3549
3815
|
return keys.length === Object.keys(right).length && keys.every((key) => left[key] === right[key]);
|
|
3550
3816
|
}
|
|
3817
|
+
function booleanMapsEqual(left, right) {
|
|
3818
|
+
const keys = Object.keys(left);
|
|
3819
|
+
return keys.length === Object.keys(right).length && keys.every((key) => right[key] === true);
|
|
3820
|
+
}
|
|
3551
3821
|
function sessionMessages(sessionMessagesById, consumer) {
|
|
3552
3822
|
for (const id of [
|
|
3553
3823
|
consumer.session.agentSessionId,
|
|
@@ -3586,6 +3856,17 @@ function needsAttentionFromInteraction(consumer, interaction) {
|
|
|
3586
3856
|
}
|
|
3587
3857
|
function promptFromInteraction(interaction) {
|
|
3588
3858
|
const input = interaction.input ?? {};
|
|
3859
|
+
const normalizedToolName = (interaction.toolName ?? "").replace(/[_\s-]+/g, "").trim().toLowerCase();
|
|
3860
|
+
if (interaction.kind === "plan" || normalizedToolName === "exitplanmode" || isExitPlanSwitchModeInput(input)) {
|
|
3861
|
+
const keepPlanningOptionId = extractExitPlanKeepPlanningOptionId(input);
|
|
3862
|
+
return {
|
|
3863
|
+
kind: "exit-plan",
|
|
3864
|
+
requestId: interaction.requestId,
|
|
3865
|
+
title: interactionSummary(interaction),
|
|
3866
|
+
options: extractExitPlanModeOptions(input),
|
|
3867
|
+
...keepPlanningOptionId ? { keepPlanningOptionId } : {}
|
|
3868
|
+
};
|
|
3869
|
+
}
|
|
3589
3870
|
if (interaction.kind === "question") {
|
|
3590
3871
|
const questions = normalizeAskUserQuestions(input.questions);
|
|
3591
3872
|
return {
|
|
@@ -3614,7 +3895,8 @@ function promptFromInteraction(interaction) {
|
|
|
3614
3895
|
{
|
|
3615
3896
|
id,
|
|
3616
3897
|
label: textValue(option.label) ?? textValue(option.name) ?? id,
|
|
3617
|
-
kind: textValue(option.kind) ?? id
|
|
3898
|
+
kind: textValue(option.kind) ?? id,
|
|
3899
|
+
...textValue(option.description) ? { description: textValue(option.description) } : {}
|
|
3618
3900
|
}
|
|
3619
3901
|
] : [];
|
|
3620
3902
|
});
|
|
@@ -3664,150 +3946,6 @@ function arrayValue2(value) {
|
|
|
3664
3946
|
return Array.isArray(value) ? value : [];
|
|
3665
3947
|
}
|
|
3666
3948
|
|
|
3667
|
-
// agent-message-center/workspaceAgentMessageCenterModelStability.ts
|
|
3668
|
-
function stabilizeWorkspaceAgentMessageCenterModel(previous, next) {
|
|
3669
|
-
if (!previous) {
|
|
3670
|
-
return next;
|
|
3671
|
-
}
|
|
3672
|
-
const previousItemsById = new Map(
|
|
3673
|
-
previous.items.map((item) => [item.id, item])
|
|
3674
|
-
);
|
|
3675
|
-
let itemsChanged = previous.items.length !== next.items.length;
|
|
3676
|
-
const items = next.items.map((nextItem, index) => {
|
|
3677
|
-
const previousItem = previousItemsById.get(nextItem.id);
|
|
3678
|
-
const stableItem = previousItem && messageCenterItemsEqual(previousItem, nextItem) ? previousItem : nextItem;
|
|
3679
|
-
if (stableItem !== previous.items[index]) {
|
|
3680
|
-
itemsChanged = true;
|
|
3681
|
-
}
|
|
3682
|
-
return stableItem;
|
|
3683
|
-
});
|
|
3684
|
-
const stableItems = itemsChanged ? items : previous.items;
|
|
3685
|
-
const stableCounts = messageCenterCountsEqual(previous.counts, next.counts) ? previous.counts : next.counts;
|
|
3686
|
-
if (previous.waitingCount === next.waitingCount && stableItems === previous.items && stableCounts === previous.counts) {
|
|
3687
|
-
return previous;
|
|
3688
|
-
}
|
|
3689
|
-
return {
|
|
3690
|
-
...next,
|
|
3691
|
-
counts: stableCounts,
|
|
3692
|
-
items: stableItems
|
|
3693
|
-
};
|
|
3694
|
-
}
|
|
3695
|
-
function messageCenterItemsEqual(left, right) {
|
|
3696
|
-
return left.id === right.id && left.agentSessionId === right.agentSessionId && left.agentTargetId === right.agentTargetId && left.agentName === right.agentName && left.agentAvatarUrl === right.agentAvatarUrl && left.provider === right.provider && left.userId === right.userId && left.title === right.title && left.imported === right.imported && left.cwd === right.cwd && left.status === right.status && left.lastAgentMessageSummary === right.lastAgentMessageSummary && left.lastAgentMessageAtUnixMs === right.lastAgentMessageAtUnixMs && messageCenterInteractionTargetEqual(
|
|
3697
|
-
left.pendingInteractionTarget,
|
|
3698
|
-
right.pendingInteractionTarget
|
|
3699
|
-
) && left.needsAttentionKind === right.needsAttentionKind && left.needsAttentionSummary === right.needsAttentionSummary && left.sortTimeUnixMs === right.sortTimeUnixMs && messageCenterIdentityEqual(left.identity, right.identity) && messageCenterDigestEqual(left.digest, right.digest) && messageCenterPromptEqual(left.pendingPrompt, right.pendingPrompt) && messageCenterTurnOutcomeEqual(
|
|
3700
|
-
left.latestTurnOutcome ?? null,
|
|
3701
|
-
right.latestTurnOutcome ?? null
|
|
3702
|
-
);
|
|
3703
|
-
}
|
|
3704
|
-
function messageCenterInteractionTargetEqual(left, right) {
|
|
3705
|
-
return left === right || left !== null && right !== null && left.agentSessionId === right.agentSessionId && left.turnId === right.turnId && left.requestId === right.requestId;
|
|
3706
|
-
}
|
|
3707
|
-
function messageCenterCountsEqual(left, right) {
|
|
3708
|
-
return left.all === right.all && left.working === right.working && left.waiting === right.waiting && left.completed === right.completed && left.failed === right.failed;
|
|
3709
|
-
}
|
|
3710
|
-
function messageCenterIdentityEqual(left, right) {
|
|
3711
|
-
if (left === right) {
|
|
3712
|
-
return true;
|
|
3713
|
-
}
|
|
3714
|
-
if (!left || !right) {
|
|
3715
|
-
return false;
|
|
3716
|
-
}
|
|
3717
|
-
return left.userName === right.userName && left.userAvatarUrl === right.userAvatarUrl && left.agentName === right.agentName && left.agentAvatarUrl === right.agentAvatarUrl;
|
|
3718
|
-
}
|
|
3719
|
-
function messageCenterDigestEqual(left, right) {
|
|
3720
|
-
return left.primary.kind === right.primary.kind && left.primary.summary === right.primary.summary && left.primary.occurredAtUnixMs === right.primary.occurredAtUnixMs;
|
|
3721
|
-
}
|
|
3722
|
-
function messageCenterTurnOutcomeEqual(left, right) {
|
|
3723
|
-
if (left === right) {
|
|
3724
|
-
return true;
|
|
3725
|
-
}
|
|
3726
|
-
if (!left || !right) {
|
|
3727
|
-
return false;
|
|
3728
|
-
}
|
|
3729
|
-
return left.notificationKey === right.notificationKey && left.status === right.status && left.turnId === right.turnId;
|
|
3730
|
-
}
|
|
3731
|
-
function messageCenterPromptEqual(left, right) {
|
|
3732
|
-
if (left === right) {
|
|
3733
|
-
return true;
|
|
3734
|
-
}
|
|
3735
|
-
if (!left || !right || left.kind !== right.kind) {
|
|
3736
|
-
return false;
|
|
3737
|
-
}
|
|
3738
|
-
switch (left.kind) {
|
|
3739
|
-
case "approval":
|
|
3740
|
-
return right.kind === "approval" && left.id === right.id && left.turnId === right.turnId && left.requestId === right.requestId && left.callId === right.callId && left.title === right.title && left.toolName === right.toolName && left.status === right.status && left.occurredAtUnixMs === right.occurredAtUnixMs && messageCenterJsonValueEqual(left.input, right.input) && messageCenterJsonValueEqual(
|
|
3741
|
-
left.output ?? null,
|
|
3742
|
-
right.output ?? null
|
|
3743
|
-
) && messageCenterApprovalOptionsEqual(left.options, right.options);
|
|
3744
|
-
case "ask-user":
|
|
3745
|
-
return right.kind === "ask-user" && left.requestId === right.requestId && left.title === right.title && messageCenterAskUserQuestionsEqual(left.questions, right.questions);
|
|
3746
|
-
case "exit-plan":
|
|
3747
|
-
return right.kind === "exit-plan" && left.requestId === right.requestId && left.title === right.title && left.keepPlanningOptionId === right.keepPlanningOptionId && messageCenterApprovalOptionsEqual(left.options, right.options);
|
|
3748
|
-
case "plan-implementation":
|
|
3749
|
-
return right.kind === "plan-implementation" && left.requestId === right.requestId && left.title === right.title;
|
|
3750
|
-
}
|
|
3751
|
-
}
|
|
3752
|
-
function messageCenterApprovalOptionsEqual(left, right) {
|
|
3753
|
-
if (left.length !== right.length) {
|
|
3754
|
-
return false;
|
|
3755
|
-
}
|
|
3756
|
-
return left.every((option, index) => {
|
|
3757
|
-
const rightOption = right[index];
|
|
3758
|
-
return rightOption && option.id === rightOption.id && option.label === rightOption.label && option.kind === rightOption.kind && option.description === rightOption.description;
|
|
3759
|
-
});
|
|
3760
|
-
}
|
|
3761
|
-
function messageCenterAskUserQuestionsEqual(left, right) {
|
|
3762
|
-
if (left.length !== right.length) {
|
|
3763
|
-
return false;
|
|
3764
|
-
}
|
|
3765
|
-
return left.every((question, index) => {
|
|
3766
|
-
const rightQuestion = right[index];
|
|
3767
|
-
return rightQuestion && question.id === rightQuestion.id && question.header === rightQuestion.header && question.question === rightQuestion.question && question.multiSelect === rightQuestion.multiSelect && messageCenterAnswerEqual(
|
|
3768
|
-
question.answer ?? null,
|
|
3769
|
-
rightQuestion.answer ?? null
|
|
3770
|
-
) && question.options.length === rightQuestion.options.length && question.options.every((option, optionIndex) => {
|
|
3771
|
-
const rightOption = rightQuestion.options[optionIndex];
|
|
3772
|
-
return rightOption && option.label === rightOption.label && option.description === rightOption.description;
|
|
3773
|
-
});
|
|
3774
|
-
});
|
|
3775
|
-
}
|
|
3776
|
-
function messageCenterAnswerEqual(left, right) {
|
|
3777
|
-
if (left === right) {
|
|
3778
|
-
return true;
|
|
3779
|
-
}
|
|
3780
|
-
if (!Array.isArray(left) || !Array.isArray(right)) {
|
|
3781
|
-
return false;
|
|
3782
|
-
}
|
|
3783
|
-
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
3784
|
-
}
|
|
3785
|
-
function messageCenterJsonValueEqual(left, right) {
|
|
3786
|
-
if (left === right) {
|
|
3787
|
-
return true;
|
|
3788
|
-
}
|
|
3789
|
-
if (!left || !right || typeof left !== "object" || typeof right !== "object") {
|
|
3790
|
-
return false;
|
|
3791
|
-
}
|
|
3792
|
-
if (Array.isArray(left) || Array.isArray(right)) {
|
|
3793
|
-
if (!Array.isArray(left) || !Array.isArray(right)) {
|
|
3794
|
-
return false;
|
|
3795
|
-
}
|
|
3796
|
-
return left.length === right.length && left.every(
|
|
3797
|
-
(value, index) => messageCenterJsonValueEqual(value, right[index])
|
|
3798
|
-
);
|
|
3799
|
-
}
|
|
3800
|
-
const leftRecord = left;
|
|
3801
|
-
const rightRecord = right;
|
|
3802
|
-
const leftKeys = Object.keys(leftRecord);
|
|
3803
|
-
if (leftKeys.length !== Object.keys(rightRecord).length) {
|
|
3804
|
-
return false;
|
|
3805
|
-
}
|
|
3806
|
-
return leftKeys.every(
|
|
3807
|
-
(key) => messageCenterJsonValueEqual(leftRecord[key], rightRecord[key])
|
|
3808
|
-
);
|
|
3809
|
-
}
|
|
3810
|
-
|
|
3811
3949
|
// agent-message-center/workspaceAgentConsumerSelectors.ts
|
|
3812
3950
|
import {
|
|
3813
3951
|
selectWorkspaceAgentConsumerCounts,
|
|
@@ -3858,6 +3996,7 @@ export {
|
|
|
3858
3996
|
readMessageCenterFilterPreferences,
|
|
3859
3997
|
resolveMessageCenterNotificationAction,
|
|
3860
3998
|
selectMessageCenterAttentionDeckItems,
|
|
3999
|
+
selectWorkspaceAgentAttentionItems,
|
|
3861
4000
|
selectWorkspaceAgentConsumerCounts,
|
|
3862
4001
|
selectWorkspaceAgentConsumerSession,
|
|
3863
4002
|
selectWorkspaceAgentConsumerSessions,
|
|
@@ -3867,6 +4006,8 @@ export {
|
|
|
3867
4006
|
useEngineSelector,
|
|
3868
4007
|
userAvatarPlaceholderUrl,
|
|
3869
4008
|
workspaceAgentActivityStatusLabel,
|
|
4009
|
+
workspaceAgentAttentionItemsEqual,
|
|
4010
|
+
workspaceAgentMessageCenterItemEqual,
|
|
3870
4011
|
workspaceAgentMessageCenterPresentationEqual,
|
|
3871
4012
|
workspaceAgentMessageCenterPromptStatus,
|
|
3872
4013
|
writeMessageCenterFilterPreferences
|