Open
Conversation
Root cause: agentState contains all historical permissions while messages are paginated (max 400). This caused old tool cards to appear mixed with current messages when switching sessions. Solution: Backend now returns permissions filtered by the time range of returned messages, ensuring permissions and messages stay in sync. - Add filterPermissionsByTimeRange() in messageService.ts - Return permissions field in GET /sessions/:id/messages response - Store and use filtered permissions in frontend message-window-store - Remove frontend time filtering workaround from reducer.ts via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
Pending requests (requests) should use real-time SSE data from agentState, not the filtered API response. This ensures new permission requests appear immediately without needing to switch sessions. Only completed requests (completedRequests) use the filtered API data to avoid showing old tool cards. via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
There was a problem hiding this comment.
Findings
- [Major] 完成态权限不会随着 SSE 更新 —
SessionChat用props.permissions.completedRequests覆盖了session.agentState.completedRequests,而权限只在拉取分页时更新,SSE 新消息不会更新权限,导致新完成的权限卡片不显示直到刷新。证据:web/src/components/SessionChat.tsx:183,web/src/lib/message-window-store.ts:327,web/src/lib/message-window-store.ts:402
Suggested fix:const oldestMessageTime = normalizedMessages.length > 0 ? Math.min(...normalizedMessages.map(m => m.createdAt)) : null const liveCompleted = props.session.agentState?.completedRequests ?? {} const filteredLiveCompleted = oldestMessageTime === null ? liveCompleted : Object.fromEntries( Object.entries(liveCompleted).filter(([, req]) => (req.createdAt ?? 0) >= oldestMessageTime) ) const filteredAgentState = { ...props.session.agentState, requests: props.session.agentState?.requests ?? {}, completedRequests: { ...props.permissions.completedRequests, ...filteredLiveCompleted } }
Summary
- 发现 1 个主要问题:完成态权限不会实时更新,可能导致权限卡片缺失。建议合并过滤后的实时 completedRequests。
Testing
- Not run (automation)
| ...props.session.agentState, | ||
| requests: props.session.agentState.requests ?? {}, | ||
| completedRequests: props.permissions.completedRequests | ||
| } |
There was a problem hiding this comment.
[MAJOR] [Realtime] 完成态权限不会随着 SSE 更新
Why this is a problem: 现在 SessionChat 只使用 props.permissions.completedRequests,而该对象只在 fetchLatestMessages/fetchOlderMessages 时更新,message-received 的 SSE 路径不会刷新权限。这样新完成的权限(没有对应 tool message 的情况下)会一直不显示,直到用户手动刷新消息。
Suggested fix:
const oldestMessageTime = normalizedMessages.length > 0
? Math.min(...normalizedMessages.map(m => m.createdAt))
: null
const liveCompleted = props.session.agentState?.completedRequests ?? {}
const filteredLiveCompleted = oldestMessageTime === null
? liveCompleted
: Object.fromEntries(
Object.entries(liveCompleted).filter(([, req]) => (req.createdAt ?? 0) >= oldestMessageTime)
)
const filteredAgentState = {
...props.session.agentState,
requests: props.session.agentState?.requests ?? {},
completedRequests: { ...props.permissions.completedRequests, ...filteredLiveCompleted }
}There was a problem hiding this comment.
Findings
- [Major] 完成态权限不会随着 SSE 更新 —
SessionChat用props.permissions.completedRequests覆盖了session.agentState.completedRequests,而权限只在拉取分页时更新,SSE 新消息不会更新权限,导致新完成的权限卡片不显示直到刷新。证据:web/src/components/SessionChat.tsx:183,web/src/lib/message-window-store.ts:327,web/src/lib/message-window-store.ts:402
Suggested fix:const oldestMessageTime = normalizedMessages.length > 0 ? Math.min(...normalizedMessages.map(m => m.createdAt)) : null const liveCompleted = props.session.agentState?.completedRequests ?? {} const filteredLiveCompleted = oldestMessageTime === null ? liveCompleted : Object.fromEntries( Object.entries(liveCompleted).filter(([, req]) => (req.createdAt ?? 0) >= oldestMessageTime) ) const filteredAgentState = { ...props.session.agentState, requests: props.session.agentState?.requests ?? {}, completedRequests: { ...props.permissions.completedRequests, ...filteredLiveCompleted } }
Summary
- 发现 1 个主要问题:完成态权限不会实时更新,可能导致权限卡片缺失。建议合并过滤后的实时 completedRequests。
Testing
- Not run (automation)
Address code review feedback: Previously, completedRequests only used filtered API data, which meant new permissions completed via SSE wouldn't appear until page refresh. Now we: 1. Filter live completedRequests by message time range (same as API) 2. Merge API-filtered permissions with filtered live completions 3. Live completions take precedence for real-time updates This ensures: - Old tool cards outside message window are still filtered out - New completed permissions appear immediately via SSE - Best of both worlds: filtering + real-time updates via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题描述
切换会话时可能出现消息排序问题,权限请求显示不正确。
修复内容
via HAPI
Co-Authored-By: HAPI noreply@hapi.run