Skip to content

fix(cc): review comments and cleanup state machine#2

Merged
adhmenon merged 8 commits into
adhmenon:task-conferencefrom
arun3528:cleanup-statemachine
Jan 30, 2026
Merged

fix(cc): review comments and cleanup state machine#2
adhmenon merged 8 commits into
adhmenon:task-conferencefrom
arun3528:cleanup-statemachine

Conversation

@arun3528

@arun3528 arun3528 commented Jan 7, 2026

Copy link
Copy Markdown

COMPLETES #< INSERT LINK TO ISSUE >

This pull request addresses

< DESCRIBE THE CONTEXT OF THE ISSUE >

by making the following changes

< DESCRIBE YOUR CHANGES >

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 where tested

< ENUMERATE TESTS PERFORMED, WHETHER MANUAL OR AUTOMATED >

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.

@arun3528
arun3528 marked this pull request as ready for review January 7, 2026 12:20
@arun3528
arun3528 force-pushed the cleanup-statemachine branch from 0b9598a to 53ebb39 Compare January 12, 2026 11:00
@arun3528
arun3528 force-pushed the cleanup-statemachine branch from 53ebb39 to c63d7d7 Compare January 13, 2026 16:15
// Backend may send hold success without a preceding HOLD_INITIATED (e.g. remote hold)
// Backend may send hold success without a preceding HOLD_INITIATED (e.g. remote hold) for consult cases
// TODO: check if we need this state as we already have consulting and intermediate state
[TaskEvent.HOLD_SUCCESS]: {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

remove this , we have intermediate state for consult and conference

@Kesari3008 Kesari3008 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Guards and actions file needs some cleanup. It's not a blocker for this PR if we need to proceed with merging it with Adhwaith's PR but it is something would be needed as some of them aren't really required

data: WebSocketPayload;
};

type TaskWithStateMachine = ITask & {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Move this to types file and this is applicable for any other similar occurrences of defining tyopes and interfaces in the same file

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

its not. needed moved to task class

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I believe this comment is remaining to be discussed as I still feel we don't need to handle RONA, Failed, END and WRAPUP events here as state machine already has these transitions addressed. I even checked the handlers for these events and I see that apart from logging we are not doing much there

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

can you elaborate more on this ,

we just do when we get OUTBOUND on OFFERED state , and do the following

      [TaskEvent.OUTBOUND_FAILED]: {
        target: TaskState.TERMINATED,
        actions: ['updateTaskData', 'markEnded', 'emitTaskReject'],
      },

Comment thread packages/@webex/contact-center/src/services/task/TaskManager.ts
const payload = JSON.parse(event) as WebSocketMessage;

// Filter out keepalive messages
if (payload?.keepalive === 'true' || payload?.keepalive === true) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

There was a previous comment on this line that why do we need to check for string and boolean value here ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

i have seen it coming up as a string , for secruity if they end of changing to boolan both gets handled


// Some consult/conference events can arrive on a child interactionId while the task we track
// is keyed by the main/parent interactionId. Resolve to an existing task when possible.
const interactionId = message.data.interactionId;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What is the difference between the 3 interaction IDs here and task object ? I believe one would be the current task/interaction and other would be the associated task for consult or conference flows so why do we have 3 interactions/task being fetched here

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@adhmenon do you know why we have 3 intraction


// ============================================
// Recording Guards
recordingActive: ({context}: GuardParams): boolean => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't see these guards being used in state machine but in the methods: pauseRecording and resumeRecording. We can directly us context itself in those method in the conditions instead of creating new guards

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

removed

* This prevents all agents in a conference from becoming consultInitiator when one agent
* starts a new consult.
*/
setConsultInitiator: assign(({event}: TaskActionArgs) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If we already have consultInitiator being set in context, why do we need these actions: setConsultInitiator and determineConsultInitiator?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

this is what sets the values in the context ,
determineConsultInitiator is a helper becuase when a task update happend then also we need to check if there is initator or not that happens in deriveTaskDataUpdates

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Are these getting used ? We can remove them if not needed

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

no its not , removed it

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Won't this change now that we don't have OFFERED_CONSULT state

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

yep removed it

context;
const {recordingControlsAvailable, recordingInProgress} = context;

const isHeld = serverHold ?? state === TaskState.HELD;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same question here, why can't we use context to identify task states ? Do we really need to create so many conditions in this file ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

serverHold is from the context object .

state === TaskState.HELD is just a backup when conext is not set

@adhmenon adhmenon left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Tested changes locally and it works.
Approving.

EventObject
>;

type RecordingStateUpdate = Partial<

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This should be in types file

}),

setHoldInitiated: assign({}),
handleTransferInit: assign({}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We are still keeping these even when not used


// State categories for cleaner logic
const isOffered = state === TaskState.OFFERED || state === TaskState.OFFERED_CONSULT;
const isOffered = state === TaskState.OFFERED;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why do we even need this variable, just use the state

return;
}

const eventTaskData = Task.extractTaskDataFromEvent(event) as any;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I still see any being used in code

return;
}

const isAutoAnsweringFromEvent = eventTaskData?.isAutoAnswering;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why is this extra check required?

@arun3528
arun3528 force-pushed the cleanup-statemachine branch from a5f23da to f877286 Compare January 30, 2026 08:02
@arun3528

Copy link
Copy Markdown
Author

@Kesari3008 have update the PR with the review comments addredded , unit test are passing as well

@adhmenon
adhmenon merged commit fa8af3e into adhmenon:task-conference Jan 30, 2026
9 of 10 checks passed
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.

3 participants