Skip to content

fix(consult)L fix mute state in desktop consult#4978

Open
Shreyas281299 wants to merge 7 commits into
webex:task-refactorfrom
Shreyas281299:fix-mute-controls-consult
Open

fix(consult)L fix mute state in desktop consult#4978
Shreyas281299 wants to merge 7 commits into
webex:task-refactorfrom
Shreyas281299:fix-mute-controls-consult

Conversation

@Shreyas281299
Copy link
Copy Markdown
Contributor

@Shreyas281299 Shreyas281299 commented May 10, 2026

COMPLETES #N/A

This pull request addresses

During desktop consult flows, the UI was showing mute on the first (main) leg while the actual mute operation could affect a different leg, and the consult leg could expose mute even when the current agent did not control that media leg.

by making the following changes

  • Added consult-leg participant ownership detection in uiControlsComputer to identify whether the current agent is in the consult media leg.
  • Gated consult-leg mute visibility with ownership: when the agent does not own the consult media leg, mute is hidden for that leg.
  • Added/updated unit assertions in uiControlsComputer tests to lock this behavior for desktop consult scenarios.

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Tooling change
  • Internal code refactor

The following scenarios were tested

  • Updated unit test coverage for consult initiator controls to assert consult.mute is hidden when the current agent does not own the consult media leg.
  • Existing consult control assertions were revalidated for main/consult leg rendering behavior.
  • Automated test execution from this environment was blocked by a local Yarn runtime issue (fastqueue concurrency must be greater than 1), but tests are included in the PR changeset.

The GAI Coding Policy And Copyright Annotation Best Practices

  • GAI was not used (or, no additional notation is required)
  • Code was generated entirely by GAI
  • GAI was used to create a draft that was subsequently customized or modified
  • Coder created a draft manually that was non-substantively modified by GAI (e.g., refactoring was performed by GAI on manually written code)
  • Tool used for AI assistance (GitHub Copilot / Other - specify)
    • Github Copilot
    • Other - Please Specify
      • Cursor (Codex)
  • This PR is related to
    • Feature
    • Defect fix
    • Tech Debt
    • Automation

I certified that

  • I have read and followed contributing guidelines
  • I discussed changes with code owners prior to submitting this pull request
  • I have not skipped any automated checks
  • All existing and new tests passed
  • I have updated the documentation accordingly

Make sure to have followed the contributing guidelines before submitting.

@Shreyas281299 Shreyas281299 requested a review from a team as a code owner May 10, 2026 18:08
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 55ecbeaf0c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Boolean(interaction?.media?.[mainCallId]?.participants?.includes(selfAgentId as string));
const consultMedia = Object.values(interaction?.media ?? {}).find(
(media: any) =>
media?.mediaResourceId === taskData?.consultMediaResourceId || media?.mType === 'consult'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Select consult leg by ID before fallback media type

The consult leg lookup now uses mediaResourceId === consultMediaResourceId || mType === 'consult' in a single find, which can return the wrong media object when interaction.media contains multiple consult entries (for example, a stale earlier consult plus the current one). In that case, selfInConsultCall is computed from the stale leg and consult.mute is incorrectly hidden on the active consult leg. This regression appears whenever object insertion order places a non-current consult media first, so the lookup should prioritize exact consultMediaResourceId and only fall back to mType when no ID match exists.

Useful? React with 👍 / 👎.

(media: any) =>
media?.mediaResourceId === taskData?.consultMediaResourceId || media?.mType === 'consult'
) as {participants?: string[]} | undefined;
const selfInConsultCall =
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this guard exists: in desktop consult, the consult media leg can belong to another participant; hiding mute here prevents exposing a control that the current agent cannot safely apply to their own active media stream.

mute: (() => {
if (!isWebrtc) return DISABLED;
if (isWrappingUp) return DISABLED;
if (currentLeg === 'consult' && !selfInConsultCall) return DISABLED;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavioral intent: mute is explicitly disabled on consult leg when ownership check fails, avoiding cross-leg mute side effects observed in desktop consult flows.

expect(uiControls.main.end).toEqual({isVisible: true, isEnabled: false});

expect(uiControls.consult.hold).toEqual({isVisible: false, isEnabled: false});
expect(uiControls.consult.mute).toEqual({isVisible: false, isEnabled: false});
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regression coverage note: this assertion ensures consult leg does not surface mute when the current agent is not a participant in consult media, matching desktop consult ownership semantics.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0854c84a8b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +477 to +481
// Interaction terminated during consult (customer left) → WRAPPING_UP
guard: ({context, event}) => {
if (context.consultInitiator !== true) return false;
const taskData = getTaskDataFromEvent(event);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reorder consult-end guards to honor terminated consults

The new CONSULT_END wrap-up branch is placed after the existing consultCallHeld branch, but XState evaluates transition options in order and takes the first passing guard. When an initiator has switched back to the main leg (consultCallHeld === true) and the customer disconnects (interaction.isTerminated === true), the machine will still transition to CONNECTED via the earlier branch, so the new WRAPPING_UP path never runs and wrap-up/cleanup can be skipped for that ended interaction.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants