Skip to content

SCAL-336112: share one conversation fetch across replayed MCP frames - #693

Open
mouryabalabhadra wants to merge 2 commits into
mainfrom
SCAL-336112-followup
Open

mouryabalabhadra wants to merge 2 commits into
mainfrom
SCAL-336112-followup

Conversation

@mouryabalabhadra

Copy link
Copy Markdown
Collaborator

Summary

Replaying a stored conversation mounts every answer frame at once, and each AutoFrameRenderer resolved on its own. A conversation with N answers made N identical GET /conversation/v2/{id}/public calls, plus the N POST .../load/public calls it needs anyway.

Change

  • The list step moves out of resolveAnswerSessionParams into fetchAnswerIds(), which never rejects and returns null on failure.
  • getAnswerIds() keeps a module-level Map<conversationUrl, Promise<string[] | null>> of in-flight list requests only:
    • Frames from the same conversation that resolve together share one GET.
    • The entry is removed as soon as its request settles, whether it succeeded or failed. A failed response is never reused, and a frame mounted later always reads a fresh list. Nothing is cached long-term, so a stored list can't go stale.
  • The load POST is never shared: it returns live session state with its own expiry, and each answer needs its own.
  • Index miss. The answer list only grows as messages are appended, so a list too short for the requested index may predate the answer. The frame reads the list once more before failing. Frames that miss together share that second read.
  • Key is the full conversation-service URL, so different conversations (and hosts) never share.

Compatibility

No API or behaviour change for host apps, apart from the extra list read on an index miss. developer-examples/mcp/python-react-agent-simple-ui works unchanged on ^1.52.1 and picks this up on the next release.

Testing

New cases in auto-frame-renderer.spec.ts:

  • Two concurrent frames from one conversation → one list call, two load calls, both resolved.
  • Frames from different conversations → separate list calls.
  • A failed list is not reused by a later frame.
  • A frame mounted after the batch settles reads a fresh list.
  • A list too short for the index is read exactly once more. Two concurrent missing frames share that re-read and both resolve.

### Summary
 Replaying a stored conversation mounts every answer frame at once, and each `AutoFrameRenderer` resolved on its own. A conversation with N answers made N identical `GET /conversation/v2/{id}/public` calls, plus the N `POST .../load/public` calls it needs anyway.

### Change
- The list step moves out of `resolveAnswerSessionParams` into `fetchAnswerIds()`, which never rejects and returns `null` on failure.
- `getAnswerIds()` keeps a module-level `Map<conversationUrl, Promise<string[] | null>>` of **in-flight** list requests only:
  - Frames from the same conversation that resolve together share one `GET`.
  - The entry is removed as soon as its request settles, whether it succeeded or failed. A failed response is never reused, and a frame mounted later always reads a fresh list. Nothing is cached long-term, so a stored list can't go stale.
- The `load` POST is never shared: it returns live session state with its own expiry, and each answer needs its own.
- **Index miss.** The answer list only grows as messages are appended, so a list too short for the requested index may predate the answer. The frame reads the list once more before failing. Frames that miss together share that second read.
- Key is the full conversation-service URL, so different conversations (and hosts) never share.

### Compatibility
No API or behaviour change for host apps, apart from the extra list read on an index miss. `developer-examples/mcp/python-react-agent-simple-ui` works unchanged on `^1.52.1` and picks this up on the next release.

### Testing
New cases in `auto-frame-renderer.spec.ts`:
- Two concurrent frames from one conversation → one list call, two load calls, both resolved.
- Frames from different conversations → separate list calls.
- A failed list is not reused by a later frame.
- A frame mounted after the batch settles reads a fresh list.
- A list too short for the index is read exactly once more. Two concurrent missing frames share that re-read and both resolve.
@mouryabalabhadra
mouryabalabhadra requested a review from a team as a code owner September 30, 2026 07:43

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request optimizes the replay of stored chats by sharing in-flight answer-id list requests across concurrent frames of the same conversation, preventing redundant API calls. It also adds comprehensive unit tests to verify this behavior under various scenarios. The review feedback correctly identifies JSDoc formatting issues in the newly added helper functions, specifically pointing out missing parameter and return tags and their canonical ordering according to the style guide.

Comment thread src/embed/auto-frame-renderer.ts
Comment thread src/embed/auto-frame-renderer.ts
@pkg-pr-new

pkg-pr-new Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@thoughtspot/visual-embed-sdk@693

commit: e6467cc

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants