Skip to content

Fix #64: Render copilot conversations including Markdown tables in SWT web browser widget#330

Draft
travkin79 wants to merge 9 commits into
microsoft:mainfrom
travkin79:fix-64-browser-migration
Draft

Fix #64: Render copilot conversations including Markdown tables in SWT web browser widget#330
travkin79 wants to merge 9 commits into
microsoft:mainfrom
travkin79:fix-64-browser-migration

Conversation

@travkin79

@travkin79 travkin79 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

This PR fixes rendering Markdown tables (GitHub-flavoured Markdown syntax) by introducing a new browser-based rendering approach based on an Eclipse-internal SWT web browser and HTML code created by converting Markdown to HTML using commonmark.

The new rendering approach is encapsulated in a BrowserConversationWidget. It does only cover conversations in the chat view. The other SWT widgets in the chat view stay unchanged, i.e. the input field, send button, toolbar, etc. For better comparison, the existing copilot conversation rendering is kept working. A new preference allows switching between both approaches. The currently used rendering approach was extracted to StyledTextConversationWidget. Both classes implement the new common interface IConversationWidget. After extensive review and testing, I'd suggest to eventually remove StyledTextConversationWidget and the corresponding new preference for switching between the StyledText-based rendering and the new browser-based rendering.

The BrowserConversationWidget renders HTML DIV code blocks representing existing SWT widgets like user / copilot turns, copilot replies, thinking, tool calls, tool confirmation UI, etc. Instead of re-rendering the whole conversation of long copilot turn HTML blocks, the BrowserConversationWidget only inserts new or modifies existing HTML code blocks / attributes to efficiently update the rendered HTML, e.g. while copilot is streaming a reply or thinking text. The look in the BrowserConversationWidget is made very similar to the existing StyleText-based chat view implementation, i.e. it uses the same colors (but in separate CSS files since the e4 CSS files could not be re-used directly), same interaction features and behavior, e.g. automatically collapses a thinking block as soon as thinking finishes, etc. The JavaScript code in the HTML rendering template is kept very simple, the domain knowledge is kept in Java code.

Switching between both rendering approaches can be done using a new Copilot preference:
image

Interaction between BrowserConversationWidget and the JavaScript code in the web browser:

+---------------------------------------------+        +-----------------------------------+
| Java (Eclipse): BrowserConversationWidget   |        | Browser (chat-view.html)          |
|                                             |        |                                   |
| Generic DOM block API:                      |        |                                   |
|   insertHtmlBlockChild(parent, html)        | -----> | window.insertBlock(p, html)       |
|   insertHtmlBlockBefore(p, html, before)    | -----> | window.insertBlockBefore(p, h, b) |
|   replaceHtmlBlock(blockId, html)           | -----> | window.replaceBlock(id, html)     |
|   removeHtmlBlock(blockId)                  | -----> | window.removeBlock(id)            |
|   setTheme(theme)                           | -----> | window.setTheme(theme)            |
|                                             |        |                                   |
| BrowserFunction callbacks:                  |        | triggered by user actions:        |
|   copyToClipboard(text)                     | <----- | code-block copy button            |
|   insertAtCursor(text)                      | <----- | insert-at-cursor button           |
|   acceptToolAction(index)                   | <----- | tool confirmation: accept         |
|   dismissToolAction()                       | <----- | tool confirmation: dismiss        |
|   copilotAction(action, param)              | <----- | quota / job-list buttons          |
+---------------------------------------------+        +-----------------------------------+

This PR includes a few additional fixes. I extracted them into separate commits in order to make reviews easier.


For convenience while testing (in a separate git branch), I also added a new target definition file and launch configs for running the Eclipse IDE with all bundles necessary for testing the two rendering approaches with and without themes support.

  • Set target-2025-09.target as active target platform, first
  • Then choose one of
    • launch/Copilot4e with Themes.launch
    • launch/Copilot4e without Themes.launch
    • launch/Copilot4e (compare chat view rendering approaches).launch for side-by-side comparison (otherwise, i.e. without the com.microsoft.copilot.eclipse.ui.test bundle, the corresponding menu entry is not available, details below)

I added a Copilot menu entry for opening the two rendering alternatives side by side for visual comparison (only available in com.microsoft.copilot.eclipse.ui.test bundle).
image

Most elements visible in a conversation widget (user turns, copilot turns, tool calls, thinking, sub-agent calls, etc. in various statuses) are rendered here with both rendering approaches side by side using some artificial data. You can switch between dark and light theme, too. This way, you can easily check if the conversation details are rendered in the browser-based widget as you would expect them to be rendered.

image image image image image

Performance
I didn't compare the rendering performance of both approaches, but I implemented the browser-based rendering in such a way that only tiny DOM manipulations are needed during conversation widget content updates (e.g. adding single words while copilot is in thinking state). While testing with exemplary requests to copilot I didn't see any observable slow-downs.

@travkin79 travkin79 force-pushed the fix-64-browser-migration branch 4 times, most recently from 728eb45 to 6e4f73e Compare July 3, 2026 08:56
@travkin79 travkin79 force-pushed the fix-64-browser-migration branch 2 times, most recently from 485efc7 to 8734279 Compare July 6, 2026 08:52
@jdneo

jdneo commented Jul 7, 2026

Copy link
Copy Markdown
Member

@travkin79 This is a big change. But from the screenshot, the modern ui rendering result looks charming.

@iloveeclipse What do you think of this? I somehow towards the web tech but need to make sure this works fine in different platform, I'm not worry for Mac and Windows, but for Linux, I'm not sure.

@iloveeclipse

Copy link
Copy Markdown

I haven't tried this patch on my RHEL 9.6 yet (I'm busy with other tasks), so just few questions:

  1. @travkin79 : have you tried in our RHEL 9.6 environment? Everything is rendered etc in webkit?
  2. Built-in browser in SWT usually have problems with context menus (either there are no menus, or unexpected entries from broswer etc). I believe we have "auto-approval" blocks with menus, and model picker. Are they work as expected? Or they are not context menus at all?
  3. Same with opening Eclipse dialogs from browser (context file attachments). I believe this should work to open, the question if that still works on returning back values etc.
  4. Haven't checked code, but if you use Eclipse themes, please try with Eclipse theming disabled. That's our default state for our product.
  5. Keyboard focus/shortcuts is yet another typical issue with browser in SWT. If the focus in the browser widget, are the "usual" shortcuts Ctrl+C/Ctrl-V etc working inside (to copy part of the chat for example). Are the "global" shortcuts still working (Ctrl+3 ?).

... May be more.

In general, if that is going to be added, a fallback would be nice because each platform has its own quirks with browser and/or OS (Linux & Mac: webkit but different UI toolkits, Windows: Edge or IE for ancient systems). But that would mean to keep double implementation & tests for some time.

@travkin79

Copy link
Copy Markdown
Contributor Author

Hi @jdneo and @iloveeclipse,

Thank you for your feedback.

@jdneo, I'm glad you like the new look.

@iloveeclipse, I'm currently testing all the features, there are many of them in the chat view. I will also check the things you mentioned. One thing making the migration a little easier is: we're only changing the conversation rendering (user and copilot turns), all SWT widgets for the user input shown below the conversation and also the tool bar remain SWT widgets and they work as before. The buttons rendered in the conversation are the ones that change and need proper attention while testing.

At the moment I'm testing on Windows 11 and there are still some minor issues I'm fixing step by step. I could also test on MacOS Tahoe (Intel) and on RHEL 9.6. I think, testing all the migrated features is the main effort here.

We could add the new preference for switching between old and new rendering to the copilot preferences UI in case we want to maintain both rendering implementations for a while.

@jdneo

jdneo commented Jul 7, 2026

Copy link
Copy Markdown
Member

We could add the new preference for switching between old and new rendering to the copilot preferences UI in case we want to maintain both rendering implementations for a while.

Yes we can have a setting to progressively roll out this feature.

I haven't deeply looked into the code, just having a general design question regard the implementation: For the frontend implementation, how is the current state management looks like? Is it complex? I'm thinking if it is necessary to introduce things like React and Redux.

@travkin79

travkin79 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

I haven't deeply looked into the code, just having a general design question regard the implementation: For the frontend implementation, how is the current state management looks like? Is it complex? I'm thinking if it is necessary to introduce things like React and Redux.

The state management is kept very simple, only on Java side. Adding JavaScript frameworks like React, Redux, Vue.js, Svelte, etc. is just not necessary.

I tried making the implementation as simple as possible, simplifying debugging and code maintenance. My goal was to keep as much existing code unchanged as possible and leaving the domain knowledge in Java. The state management is kept completely in Java code (mainly in ChatView, some differently implemented parts went to StyledTextConversationWidget and BrowserConversationWidget using a common interface). The browser side only receives plain DIV code blocks (addition or replacement) for being rendered. Each block gets a unique ID. There is no state in the HTML / JavaScript besides the DOM with IDs.

@travkin79 travkin79 force-pushed the fix-64-browser-migration branch from 8734279 to 7f7d1ae Compare July 7, 2026 16:34
travkin79 and others added 9 commits July 8, 2026 10:45
…nversations

- Introduce SWT-browser-based widget for rendering conversations in copilot chat view
- Introduce common interface for the existing StyledText-based conversation rendering and the new browser-based conversation rendering
- Introduce commonmark Markdown parser and HTML renderer with extensions to properly render GitHub-Flavoured Markdown tables (and task item lists), i.e. fix issue microsoft#64
- Introduce preference for switching between StyledText-based SWT rendering and browser-based HTML rendering

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wrap the chatViewSideEffect disposal in ensureRealm() to guarantee it
runs on the correct data binding Realm thread, preventing potential
InvalidThreadAccessException when unbinding from a non-UI thread.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace preference-based theme detection with the proper IThemeEngine
service API. The previous approach read the theme ID from preferences
which could be stale or unavailable. The new approach queries the
active theme directly via IThemeEngine.getActiveTheme(). We're using reflection in order not to introduce a dependency to the SWT themes bundle and to avoid discouraged access warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Update subagent card factory test for header
Cover UiUtils.isDarkTheme() with mocked PlatformUI/Platform statics:
WITH e4 CSS theming (dark id, light id, mixed-case id, and a null active
theme falling back to the preference) and WITHOUT theming (theme bundle
absent, theme service null, and a reflective loadClass failure) — all of
which must degrade to the persisted themeid preference and finally to
light without throwing.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Add 'Compare Chat View Rendering Alternatives' Copilot menu entry
- Opens both rendering alternatives in one dialog, side by side, for visual comparison

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Both the browser-based (HTML) and the seasoned StyledText renderers ship
behind the useBrowserBasedChatRenderer preference, so both need probe
coverage. Select the renderer per launch instead of hardcoding it.

- ProbeRunner: read -Dprobe.renderer (browser | styledtext) and set
  USE_BROWSER_BASED_CHAT_RENDERER accordingly. Default styledtext matches the
  production default, so plain runs still exercise the SWT widget tree.
- chat-send-receive-001.json: restored to the strong StyledText widget-tree
  assertions (user-turn, copilot-turn, model-info-label) for the default
  renderer.
- chat-send-receive-browser-001.json (new): browser-renderer variant that
  asserts the Browser widget exists, then uses sleep + screenshot because the
  HTML DOM is opaque to SWTBot widget locators.
- REFERENCE.md: document the -Dprobe.renderer property and the two-probe
  workflow for covering both renderers.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@travkin79 travkin79 force-pushed the fix-64-browser-migration branch from 7f7d1ae to 4f22cc9 Compare July 8, 2026 10:50
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