Consolidate AgentZero status into a Context#85535
Consolidate AgentZero status into a Context#85535adhorodyski wants to merge 13 commits intoExpensify:mainfrom
Conversation
Replace three scattered modules (useAgentZeroStatusIndicator hook, ConciergeReasoningStore, and Pusher reasoning subscriptions in Report/index.ts) with a single AgentZeroStatusContext that uses a two-level gate pattern: - Outer gate (AgentZeroStatusProvider): cheap scalar check — if not Concierge chat, renders children with no hooks/Pusher/state overhead - Inner gate (AgentZeroStatusGate): owns all logic for Concierge chats: Onyx subscription, Pusher subscription with per-callback cleanup, reasoning state with deduplication, debounced label updates Consumers (ConciergeThinkingMessage, ReportActionCompose) now read from context instead of receiving props drilled through 4 levels. The prop chain ReportScreen → ReportActionsView → ReportActionsList → ConciergeThinkingMessage is eliminated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
964e83a to
bbc1155
Compare
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
The new eslint-config-expensify@2.0.107 enforces context-provider-split-values:
contexts must not mix data and functions in a single provider.
Split AgentZeroStatusContext into:
- AgentZeroStatusStateContext: {isProcessing, reasoningHistory, statusLabel}
- AgentZeroStatusActionsContext: {kickoffWaitingIndicator}
Export useAgentZeroStatus() for state and useAgentZeroStatusActions()
for actions. Update ReportActionCompose to use the actions hook.
Update tests to use the appropriate hook per test case — state-only
tests use useAgentZeroStatus(), tests needing both spread inline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…atus-context # Conflicts: # src/hooks/useAgentZeroStatusIndicator.ts # src/pages/inbox/ReportScreen.tsx
|
@DylanDylann Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7c1c53a639
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
src/pages/inbox/report/ReportActionCompose/ReportActionCompose.tsx
Outdated
Show resolved
Hide resolved
|
Marked as HOLD, SQ fixes that this PR needs will likely get reverted. I'll keep monitoring with @szymonzalarski98. |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
PR doesn’t need product input as a performance PR. Unassigning and unsubscribing myself. |
…me state Self-derive shouldSuppressIndicators inside AgentZeroStatusGate using side-panel context and report actions, then expose it via useAgentZeroStatus(). ConciergeThinkingMessage and a new AgentZeroAwareTypingIndicator wrapper consume the flag to hide indicators until the user sends a message. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); | ||
| const isConciergeChat = reportID === conciergeReportID; | ||
| const isAdmin = chatType === CONST.REPORT.CHAT_TYPE.POLICY_ADMINS; | ||
| const isAgentZeroChat = isConciergeChat || isAdmin; |
There was a problem hiding this comment.
Please use isConciergeChatReport function
There was a problem hiding this comment.
it requires me to provide the whole report to it which does not make sense here (and in general nowhere) now I'm able to calculate this without connecting to any onyx value and rely on route's reportID
@adhorodyski I’m curious about how to simulate this test case. Could you help me? |
@adhorodyski Also confused about this test case? What typing indicator does you mean? I don't see any typing indicator in this case |
|
@codex review |
|
@adhorodyski I noticed a flicker when we open another chat and then go back to the Concierge chat. The old indicator briefly appears before disappearing, and then a new indicator shows up again after a few seconds. Screen.Recording.2026-03-23.at.16.37.52.mov |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ff6322c2aa
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Document the public interface (AgentZeroStatusState, AgentZeroStatusActions) with JSDoc comments explaining each field's purpose, and add inline comments to internal state variables, refs, effects, and derived values in the gate. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…hook Extract useShouldSuppressConciergeIndicators hook that each consumer calls directly, removing shouldSuppressIndicators from AgentZeroStatusState. This keeps the context pure (isProcessing, reasoningHistory, statusLabel) and scopes suppression to Concierge DMs only, fixing the #admins bug. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This is because the NVP value only refreshes after a successful OpenReport most likely, working on this. edit: ok looks like the old |
I believe I broke this 2 commits before, can you retest please? |
I think the ~only case for this is the header's concierge everywhere features (Help button). @rlinoz can you confirm if there's any other way that we can have 2 concierge chats on the display (one in RHP)? |
|
AFAIK that is the only way really |
Avoids defaulting to empty string which violates the no-default-id-values lint rule. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f9218d2 to
cf71724
Compare
@adhorodyski It still doesn’t work on my side. |
|
@adhorodyski Could you please add video evidence? |
@rlinoz @mountiny @TMisiukiewicz
Explanation of Change
This PR replaces three scattered modules managing Concierge/AgentZero status with a single
AgentZeroStatusContextusing a two-level gate pattern:Consumers (
ConciergeThinkingMessage,ReportActionCompose) now read from context instead of receiving props drilled through 4 levels (ReportScreen → ReportActionsView → ReportActionsList → ConciergeThinkingMessage).Deleted modules:
src/hooks/useAgentZeroStatusIndicator.ts(162 lines)src/libs/ConciergeReasoningStore.ts(122 lines)src/libs/actions/Report/index.ts(~50 lines)New:
src/pages/inbox/AgentZeroStatusContext.tsx(224 lines)src/selectors/ReportNameValuePairs.ts— newagentZeroProcessingIndicatorSelectorTests: 21 new tests replace 3 deleted test files. 15 files changed, +462/-1386 lines.
Note: This PR depends on PR #85355 (useIsInSidePanel) and PR #85356 (Pusher per-callback handles). CI will fail until those merge.
Fixed Issues
$ #84895
PROPOSAL:
Tests
Offline tests
N/A
QA Steps
Same as tests, plus:
Known limitation: The side panel will only show reasoning entries that arrive after it mounts. Earlier entries visible in the main pane won't backfill into the side panel. This is cosmetic — both panes converge once new entries arrive or processing completes. A new user message triggers a new
agentZeroRequestIDwhich resets the reasoning chain in both panes anyway.PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari