Skip to content

feat(cc-store): add AI summary lifecycle - #748

Open
rsarika wants to merge 15 commits into
webex:nextfrom
rsarika:codex/ai-summary-store
Open

rsarika wants to merge 15 commits into
webex:nextfrom
rsarika:codex/ai-summary-store

Conversation

@rsarika

@rsarika rsarika commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds AI summary state, SDK event handling, feedback and response flows to the existing Contact Center store for consult/transfer, receiving-agent and post-call summaries.

  • Stores SDK AISummary in entry.content and SDK AISummaryResponse in entry.response, grouped by interaction and summary role. Requests, receiver events and edit/copy/feedback actions access the record directly and replace it inside runInAction; senders forward it without a response composer or duplicate counter/feedback fields. Result handling, logging and status notification live in the owning flow. Empty responses supply the required SDK fields when no summary has arrived.
  • Matches Agent Desktop by sending only edited structured sections, preserving cleared values, removing reverted edits and using SDK summary text for receiver feedback. Incoming SDK metadata and optional display fields are retained.
  • Checks task.aiSummaryCapabilities directly for summary requests and responses, matching suggested responses without an additional media-type restriction. task:featureEnablement refreshes the current task after the SDK updates those flags, including late enablement and later disabling. The store keeps no separate capability map or enablement helper.
  • Guards overlapping requests, pairs task listener cleanup and requires the original task when submitting a response after wrap-up.
  • Keeps the lifecycle selector and its tests in the existing store event files. Includes typed fixtures, regression tests, store documentation and a lockfile that supports immutable installs.

Stack

This is PR 1 of 3. This cleanup is scoped to store PR #748.
Component PR #749 and widget integration PR #750 need to consume the SDK fields in entry.content and entry.response, including entry.response.feedback and the SDK copy/edit counts. Widget enablement checks should read task.aiSummaryCapabilities directly in place of the removed isAISummaryEnabled helper. Their presentation and UI lifecycle props remain in those PRs; SDK-backed fixtures include conversationId.

Verification

  • Repository pre-commit checks under Node 24: yarn test:unit passed (91 suites, 1,834 tests passed, 7 skipped) and yarn test:styles passed with 6 existing warnings.
  • yarn install --immutable
  • yarn build:dev (all widget packages)
  • yarn workspace samples-cc-react-app build (sample TypeScript check)
  • yarn workspace @webex/cc-store test:unit --runInBand: 330 passed, 3 skipped.
  • Changed store, sample and fixture source files pass lint; git diff --check is clean.

SDK dependency

Uses published @webex/contact-center 3.12.0-next.148 for the store, React sample and the sample's transitive Webex SDK. The vendored SDK archive is removed. Three scoped resolutions map unavailable transitive versions to their published predecessors: Device next.55 to next.54, Metrics next.56 to next.55, and Mercury next.62 to next.61. Remove these resolutions once the referenced versions are published. The React sample uses the SDK-supported User requested logout reason on page unload.

@rsarika
rsarika requested a review from a team as a code owner October 9, 2026 05:29
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T08:46:02.312232Z 5d4e1ad New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff0880bccc

ℹ️ 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 thread yarn.lock Outdated
resolution: "@webex/contact-center@file:./vendor/contact-center-cc-summaries.tgz#./vendor/contact-center-cc-summaries.tgz::hash=66e859&locator=webex-widgets%40workspace%3A."
dependencies:
"@types/platform": "npm:1.3.4"
"@webex/calling": "npm:3.12.0-next.98"

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 Regenerate the vendored SDK's transitive lock entries

The new tarball stanza names @webex/calling@3.12.0-next.98 and six exact plugin versions, but yarn.lock contains no package records for any of those descriptors; local Yarn 4.5.1 already reports that the calling package is absent. In the checked .github/workflows/pull-request.yml Install Dependencies step, bare yarn runs on CI, and yarn install --help says --immutable “defaults to true on CI” and aborts if the lockfile would be modified, so a clean PR/deploy checkout cannot reach the build or tests. Regenerate and commit the complete lockfile for the vendored package.

AGENTS.md reference: AGENTS.md:L80-L81

Useful? React with 👍 / 👎.

Comment thread package.json Outdated
"@momentum-design/components": "0.133.23",
"@momentum-design/icons": "0.17.0"
"@momentum-design/icons": "0.17.0",
"@webex/contact-center": "file:./vendor/contact-center-cc-summaries.tgz"

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 Depend on a published SDK with the summary surface

This root-only resolution makes the private monorepo build against 3.12.0-cc-summaries.15f3da706d84, but the checked .github/workflows/deploy.yml publishes the workspace's own manifest, where @webex/cc-store still depends on @webex/contact-center@3.12.0-next.133. The added store spec explicitly says release requires a published SDK containing these APIs, so external TypeScript consumers receive declarations importing missing AISummary* exports and the supported host-supplied Webex path receives task objects without the new methods/events. Update the workspace dependency to a compatible published SDK, or block publishing this package until one exists.

AGENTS.md reference: AGENTS.md:L55-L57

Useful? React with 👍 / 👎.

/** Sends the final post-call response once; it is never retried. */
sendPostCallSummaryResponse = async (
response: AISummaryResponse,
task: ITask = this.currentTask

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Retain the summarized task for post-call submission

When a consumer follows the documented flow of freezing the response before wrap-up and sending it afterward, handleTaskRemove has already cleared or promoted currentTask; omitting the optional task argument here therefore either dereferences null (reported as response-failed) or sends the frozen response through a different task whose SDK context targets another interaction. Retain the original task/context with the response or make that task required so the default public path cannot lose or misroute the post-call result.

Useful? React with 👍 / 👎.

this.logAISummaryFailure('request', error);
result = 'failed';
}
if (this.getAISummaryEntry(role, task)?.status === 'loading') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Tokenize overlapping AI summary requests

When requests A and B overlap and A rejects after B has set this shared entry to loading (the vendored SDK's requestAndWaitForRtd can still reject from A's send acknowledgement after its RTD waiter was replaced), this status-only check treats A's failure as current and changes B's entry to error; any later B settlement is then discarded because the status is no longer loading. The existing latest-request test only rejects A after B is already ready, so track and compare a per-request generation/token here instead.

AGENTS.md reference: AGENTS.md:L102-L102

Useful? React with 👍 / 👎.

Use SDK summary types directly and send only changed structured sections. Guard superseded request results, pair task listener cleanup, and require the original task for post-call submission. Repair the lockfile for immutable installs.
@aws-amplify-us-east-2

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-748.d1b38q61t1z947.amplifyapp.com

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8a3b2944b

ℹ️ 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".

this.store.realTimeAssist = next;
});
}
if (taskId && this.store.aiSummaries[taskId]) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clean up summaries for ended background tasks

When two interactions are active and the non-current task ends, its TASK_END handler only schedules refreshTaskList; since the current task is still present, that method takes its setCurrentTask branch and never calls handleTaskRemove for the ended task. Consequently this deletion (and the listener teardown just above it) never runs, so aiSummaries[taskId] and aiSummaryReceivedListeners[taskId] survive until logout and retain stale summary state and task listeners for the whole agent session. Prune summary entries and listeners for every ID removed from the refreshed task list, not only the current task.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Failed to sample tokens
ℹ️ 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".

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c75883b7c5

ℹ️ 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".

const {sections, summaryText} = entry?.content ?? {};
let summary: AISummaryResponse['summary'] = summaryText ?? '';
// Receivers report SDK text. Editable summaries report only changed sections, like Desktop.
if (role !== 'receiver' && sections) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve text edits for mixed summary payloads

When an SDK payload contains both sections and summaryText (the new typedSections and structured fixtures do), the public editAISummary(..., 'summaryText', ...) succeeds and marks the entry edited, but this branch unconditionally replaces the outgoing summary with section deltas; if no section changed it sends {} while numberOfTimesEdited is 1. A component choosing the text field therefore silently drops the agent's edited content, so composition must follow the edited/displayed representation or the mutation API must reject that edit.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Failed to sample tokens
ℹ️ 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".

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 79b8573d80

ℹ️ 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 thread package.json Outdated
"@momentum-design/components": "0.133.23",
"@momentum-design/icons": "0.17.0"
"@momentum-design/icons": "0.17.0",
"@webex/contact-center": "file:./vendor/contact-center-cc-summaries.tgz"

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 Rebuild the vendored SDK before resolving it

When a receiving-agent summary carries the original conversation ID while the receiving task has its own interaction ID (the consult/transfer lineage covered by the SDK's included tests), this resolution loads the archive's main (dist/webex.js), whose dist/services/task/TaskManager.js still looks up only taskCollection[conversationId] and later flushes by task.data.interactionId; the archive's newer src/services/task/TaskManager.ts routes by interaction.mainInteractionId, but that source was not compiled into dist. Consequently TASK_MID_CALL_SUMMARY_RECEIVED is never emitted for those tasks, so the new store listener cannot populate the receiver summary. Rebuild and repack the archive from its included source before making it workspace-wide.

AGENTS.md reference: AGENTS.md:L56-L57

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 199f875fd0

ℹ️ 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 thread package.json Outdated
"@momentum-design/components": "0.133.23",
"@momentum-design/icons": "0.17.0"
"@momentum-design/icons": "0.17.0",
"@webex/contact-center": "file:./vendor/contact-center-cc-summaries.tgz"

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 Redact summaries from the vendored SDK log

When a submitted mid/post-call summary contains customer details, this resolution executes an archive whose dist/services/task/Task.js puts response.summary in eventMetaData, while dist/services/ApiAiAssistant.js logs that whole object through LoggerProxy.info('Sending event', ...) and LoggerProxy JSON-serializes it. ai-docs/SECURITY.md:30-35 classifies transcript/customer text as PII that must never be logged, so every such submission leaks generated or edited summary text to configured SDK logs; redact the metadata before using this archive.

AGENTS.md reference: AGENTS.md:L67-L67

Useful? React with 👍 / 👎.


let result: AISummary | undefined;
try {
result = await (action ? task.requestMidCallSummary(action) : task.requestPostCallSummary());

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Settle superseded summary requests

When requests A and B of the same kind/conversation overlap, A's HTTP acknowledgement fails after B replaces it, and B's acknowledgement succeeds, this generation guard cannot make B finish: in the vendored runtime's dist/services/ApiAiAssistant.js, A's rejection calls removeRtdRequest by key, deleting B's waiter and clearing B's timeout. B's RTD response then has no waiter, so this await and the public promise remain pending and the entry stays loading indefinitely. Fresh evidence beyond the earlier status-race report is that the actual vendored runtime removes the new SDK waiter; cancel/settle superseded requests or serialize these calls.

AGENTS.md reference: AGENTS.md:L55-L57

Useful? React with 👍 / 👎.

Comment on lines +539 to +540
state: 'DEFAULT',
numberOfTimesViewed: 1,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Record unavailable summaries as not viewed

When the SDK returns an AISummary with areTranscriptsAvailable: false, getAISummarySurface and the status notification classify it as unavailable, but this response is still initialized as DEFAULT with one view. If the agent then continues the consult/transfer or wrap-up flow, the send methods forward that record and report a summary that was hidden as successfully viewed, corrupting summary outcome metrics; initialize transcript-unavailable results with zero views and the appropriate non-received state.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Failed to sample tokens
ℹ️ 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".

@rsarika rsarika added the validated Indicates that the PR is ready for actions label Oct 13, 2026
"clean:dist": "rm -rf dist",
"build": "yarn run -T tsc",
"build:src": "yarn run clean:dist && webpack",
"build:src": "yarn run clean:dist && webpack && yarn run -T tsc --emitDeclarationOnly",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is this change needed ?

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.

Good catch. The extra build script change wasn't needed here, so I reverted it. The store package.json now only has the Contact Center SDK version update.

Comment thread package.json Outdated
"@momentum-design/components": "0.133.23",
"@momentum-design/icons": "0.17.0"
"@momentum-design/icons": "0.17.0",
"@webex/contact-center": "3.12.0-next.148",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we need changes in global package.json ?

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.

You're right, the root package.json change was unrelated to this work. I've reverted it.

void store.cc
?.stationLogout({logoutReason: 'Page unload'})
.catch(() => undefined);
void store.cc?.stationLogout({logoutReason: 'User requested logout'}).catch(() => undefined);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this an intentional change ?

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.

No, that sample app change wasn't intentional for this PR. I've reverted it.

}
}

requestMidCallSummary = (action: AISummaryAction, task: ITask = this.currentTask): Promise<void> =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are we keeping this method return a void promise when we have these methods implemented return the summary itself ?
Why arent' we returning the summary content directly /

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.

Good point. Both request methods now return the summary from the SDK. They return undefined if the feature is unavailable, the request fails, or a newer request has superseded it; the result is also saved under cc.aiSummaries.

constructor() {
makeAutoObservable(this, {
cc: observable.ref,
aiSummaries: observable.ref,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are deciding to keep the aiSummaries as separate entry and outside cc object itself ?

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.

Agreed, keeping a separate summary field on the store added an unnecessary place to look. Summaries now live under store.cc.aiSummaries, and registerCC initializes that map when needed.

* Like Agent Desktop, the initiator's and the wrap-up feedback stay local: they are sent with the consult/transfer
* response or the final post-call response.
*/
setAISummaryFeedback = (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same comment applies here

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.

I made the same change for local feedback: initiator and post-call feedback now update through aiAssistantHelper.ts. Receiver feedback still goes through StoreWrapper because it sends a response to the SDK immediately.

/**
* Stores the wrap-up code and captures the SDK response before wrap-up removes the task and its summary.
*/
getPostCallSummaryResponse = (wrapUpCode: string, task: ITask = this.currentTask): AISummaryResponse | undefined => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Need help in understanding what this methods is for ?

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.

This was there to hold the post-call response after wrap-up removed the task. I've removed it. The wrap-up click now sends the response with the selected wrap-up code on the current task before calling task.wrapup().

* Reports the initiator's summary for the consult or transfer that is starting. Like Agent Desktop, callers do
* not wait for it; it never rejects.
*/
sendMidCallSummaryResponse = async (action: AISummaryAction, task: ITask = this.currentTask): Promise<void> => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same comment here for void promise return type

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.

Good point. sendMidCallSummaryResponse now returns a typed outcome: submitted, response-failed, or not-applicable. That lets the caller see whether the send happened while the consult or transfer flow can still continue.

sendPostCallSummaryResponse = async (
response: AISummaryResponse,
task: ITask
): Promise<'submitted' | 'response-failed'> => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It would be good to have a return type defined for these values and use that

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.

Done. I added AISummaryResponseSubmissionResult in store.types.ts and use it for both mid-call and post-call response methods.

private taskEndListeners: Record<string, {task: ITask; listener: () => void}> = {};
private muteStateByInteractionId: Record<string, boolean> = {};
// Keyed by interactionId, rebound when task:hydrate / task:merged supplies a replacement task object.
private aiSummaryReceivedListeners: Record<string, {task: ITask; listener: (payload: AISummary) => void}> = {};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is having direct listener setup on the task object enough like other events ? Why do we have to setup listeners like this for summaries ? aiSummaryReceivedListeners and aiSummaryStatusListeners ?

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.

We still attach the summary handler directly to the task with task.on(). I removed aiSummaryStatusListeners because the request result already handles that state. The remaining aiSummaryReceivedListeners map tracks the task and callback so repeated setup doesn't add duplicate handlers, and so we can detach and rebind when a task object is replaced or removed. That's the same cleanup pattern used for task-end and real-time-assist events.

@github-actions github-actions Bot removed the validated Indicates that the PR is ready for actions label Oct 14, 2026
@rsarika rsarika added the validated Indicates that the PR is ready for actions label Oct 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e8793be897

ℹ️ 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 thread yarn.lock
Comment on lines +9595 to +9597
"@webex/internal-plugin-device": "npm:3.12.0-next.55"
"@webex/internal-plugin-feature": "npm:3.12.0-next.57"
"@webex/internal-plugin-metrics": "npm:3.12.0-next.56"

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 Restore the published SDK's transitive resolutions

When a clean checkout installs @webex/contact-center@3.12.0-next.148, these added edges request Device next.55 and Metrics next.56, while the new encryption stanza also requests Mercury next.62; repo-wide lockfile search finds references but no package records, and the root manifest lacks the scoped fallbacks that packages/contact-center/store/ai-docs/store-spec.md:479-482 says are required. In the checked .github/workflows/pull-request.yml Install Dependencies step (lines 100-101), CI runs bare yarn; bundled yarn install --help says --immutable “defaults to true on CI” and “will abort” if the lockfile would be modified, so a clean PR install stops before build/tests. Fresh evidence beyond the earlier vendored-lock report is that the final published SDK graph still has these unresolved descriptors after the archive was removed; restore the scoped resolutions and regenerate the lock.

AGENTS.md reference: AGENTS.md:L80-L81

Useful? React with 👍 / 👎.

Comment thread yarn.lock Outdated
"@webex/cc-ai-assistant": "workspace:*"
"@webex/cc-widgets": "workspace:*"
"@webex/contact-center": "npm:3.12.0-next.133"
"@webex/contact-center": "npm:3.12.0-next.148"

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 Reconcile the sample manifest with its lock stanza

When Yarn validates workspaces, this changed dependency says the React sample uses 3.12.0-next.148, but widgets-samples/cc/samples-cc-react-app/package.json:27 still declares 3.12.0-next.133; repo-wide lockfile search also finds no package record for .133. The checked .github/workflows/pull-request.yml Install Dependencies step (lines 100-101) runs bare yarn, and bundled yarn install --help says --immutable defaults to true on CI and aborts if the lockfile would change, so the resolver must rewrite this workspace stanza and CI exits before tests. Fresh evidence beyond the earlier dependency-pin comment is this final sample-manifest/lock mismatch rather than the old store manifest; update one source and regenerate the lock.

AGENTS.md reference: AGENTS.md:L80-L81

Useful? React with 👍 / 👎.

@github-actions github-actions Bot removed the validated Indicates that the PR is ready for actions label Oct 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c267377f56

ℹ️ 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 +718 to +720
export type AISummaryStatusDetail =
| {kind: 'mid-call'; state: 'available' | 'unavailable'}
| {kind: 'post-call'; state: 'available' | 'unavailable' | 'submitted' | 'response-failed'};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include the interaction ID in summary status details

When two interactions are active, or when sendPostCallSummaryResponse reports an original task after currentTask has changed, a listener cannot associate this detail with the entry that changed: summary state is keyed by interaction ID and the APIs accept explicit tasks, but every emission is reduced to {kind, state}. A host can therefore attribute an available or submitted status to the wrong interaction; include the originating interaction ID in this public detail.

Useful? React with 👍 / 👎.

): Promise<'submitted' | 'response-failed'> => {
let outcome: 'submitted' | 'response-failed' = 'submitted';
try {
await task.sendPostCallSummaryResponse(response);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Deduplicate post-call response submissions

When a wrap-up completion callback fires twice or a consumer retries this method after the first call settles, every invocation reaches the SDK because there is no per-interaction in-flight or submitted guard, despite the method's sends-once contract. This produces duplicate post-call response transports and duplicate submitted notifications; track submission state while still permitting an explicit retry after a failed send.

Useful? React with 👍 / 👎.

@rsarika rsarika added the validated Indicates that the PR is ready for actions label Oct 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: adf585a4dc

ℹ️ 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".

});
if (currentTask.aiSummaryCapabilities?.postCallEnabled) {
try {
await store.sendPostCallSummaryResponse(auxCodeId, currentTask);

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 Route automatic wrap-up through summary submission

When useCallControl is running a task with SDK auto-wrapup and the countdown expires, the SDK timer calls Task.wrapup() directly rather than invoking wrapupCall; the effect at the bottom of this hook only mirrors or cancels that timer. A repo-wide search finds this line as the only production call to sendPostCallSummaryResponse, so every automatic wrap loses any generated or edited response and sends no IGNORED outcome if none arrived. Route timer completion through the same store submission before wrapping.

AGENTS.md reference: AGENTS.md:L56-L57

Useful? React with 👍 / 👎.

});
if (currentTask.aiSummaryCapabilities?.postCallEnabled) {
try {
await store.sendPostCallSummaryResponse(auxCodeId, currentTask);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Stop auto-wrap-up before awaiting the response

When auto-wrapup is enabled and the agent chooses a code shortly before countdown expiry, this new network await leaves the SDK timer armed; in the SDK, Task.wrapup() is what cancels that timer, and it is now called only after this await. The timer can therefore wrap with the configured default code while the response is in flight, after which this function issues a second wrap with the agent's code. Cancel or claim the timer before sending, or otherwise serialize the two paths.

AGENTS.md reference: AGENTS.md:L56-L57

Useful? React with 👍 / 👎.

@github-actions github-actions Bot removed the validated Indicates that the PR is ready for actions label Oct 14, 2026
@rsarika
rsarika requested a review from Kesari3008 October 14, 2026 08:15
@rsarika rsarika added the validated Indicates that the PR is ready for actions label Oct 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dc5a89f0ce

ℹ️ 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 +1248 to +1250
if (currentTask.aiSummaryCapabilities?.postCallEnabled) {
try {
await store.sendPostCallSummaryResponse(auxCodeId, currentTask);

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 Gate manual submissions until post-call requests are wired

When this commit runs in an org where postCallEnabled is true, every manual wrap enters this branch, but a repository-wide search of production and generated files finds no caller of requestPostCallSummary outside its store declaration/implementation. sendPostCallSummaryResponse therefore has no post-call entry and submits EMPTY_AI_SUMMARY_RESPONSE with state: 'IGNORED' before wrapping, even though agents have no route in this tree to request or view the summary; this records all manual wraps as ignored and makes wrap-up wait for an unnecessary SDK send. Gate this integration until the requester UI ships, or wire the request path in the same deploy.

Useful? React with 👍 / 👎.

@github-actions github-actions Bot removed the validated Indicates that the PR is ready for actions label Oct 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5d4e1ad66e

ℹ️ 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".

const interactionId = task.data.interactionId;
const entry = this.store.cc.aiSummaries[interactionId]?.receiver;
runInAction(() => {
this.store.cc.aiSummaries = {

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 Keep summary state on an observable store path

When TASK_MID_CALL_SUMMARY_RECEIVED fires without another task update, this assignment only changes a nested property on the existing SDK object; Store declares cc as observable.ref, so MobX does not observe cc.aiSummaries, and wrapping the assignment in runInAction does not make it observable. An observer widget reading the new summary map therefore will not rerender for the pushed receiver summary (or subsequent edits/feedback) until unrelated observable state changes; expose the map through an observable store field/getter or make this property observable.

AGENTS.md reference: AGENTS.md:L63-L64

Useful? React with 👍 / 👎.


let sent = true;
try {
await task.sendMidCallSummaryResponse({...entry.response, feedback}, entry.action);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include copies made while receiver feedback is pending

When an agent copies a receiver summary after selecting feedback but before this SDK promise settles, this spread snapshots the pre-copy response. recordAISummaryCopied is still allowed during feedbackPending and replaces the current entry with an incremented count; settlement preserves that local count, but no subsequent receiver response is sent, so the backend records the old numberOfTimesCopied value. Block response mutations while feedback is pending or flush the latest response after they occur.

Useful? React with 👍 / 👎.

@rsarika rsarika added the validated Indicates that the PR is ready for actions label Oct 15, 2026

This branch has not been deployed

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

Labels

validated Indicates that the PR is ready for actions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants