Skip to content

Refine conv tags and log styles#430

Merged
iceljc merged 3 commits intoSciSharp:mainfrom
iceljc:main
Mar 10, 2026
Merged

Refine conv tags and log styles#430
iceljc merged 3 commits intoSciSharp:mainfrom
iceljc:main

Conversation

@iceljc
Copy link
Collaborator

@iceljc iceljc commented Mar 10, 2026

No description provided.

@qodo-code-review
Copy link

Review Summary by Qodo

Refactor conversation tags UI and enhance label component

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Refactor conversation tags UI from checkboxes to custom labels
• Add color and ellipsis support to Label component
• Improve markdown rendering with list style and separator formatting
• Simplify tag management with add/remove functionality
Diagram
flowchart LR
  A["Label Component"] -->|"Add color & ellipsis props"| B["Enhanced Label"]
  C["Tag Modal UI"] -->|"Replace checkboxes with labels"| D["Custom Tag Display"]
  E["Tag Management"] -->|"Add/Remove tags dynamically"| F["Improved UX"]
  G["Markdown Styles"] -->|"Fix list & separator rendering"| H["Better Formatting"]
Loading

Grey Divider

File Changes

1. src/lib/common/shared/Label.svelte ✨ Enhancement +11/-2

Add color and ellipsis props to Label

• Added color prop (default "primary") to customize button color
• Added ellipsis prop to enable text truncation with overflow handling
• Updated button class binding to use dynamic color value
• Updated span class binding to conditionally apply ellipsis or responsive display classes
• Added .label-ellipsis CSS class with overflow, text-overflow, white-space, and max-width
 properties

src/lib/common/shared/Label.svelte


2. src/routes/chat/[agentId]/[conversationId]/chat-box.svelte ✨ Enhancement +63/-39

Refactor tag management from enum to custom input

• Removed unused Input import from sveltestrap
• Removed ConversationTag enum import and replaced checkbox-based tag selection with custom tag
 management
• Changed selectedTags variable to convTags and added newTagText for new tag input
• Removed tagOptions array generation from ConversationTag enum
• Refactored changeTagSelection() function to removeTag() for removing individual tags
• Added addTag() function to create new tags with validation and deduplication
• Updated updateChatTags() to calculate tag differences and only send changes to API
• Replaced tag modal UI from checkboxes to Label components with add input field
• Changed modal cancel button text to empty string and removed cancel callback
• Updated dropdown menu item text from "Add Tags" to "Tags"
• Fixed grammar in success message from "Tags has been updated!" to "Tags have been updated!"

src/routes/chat/[agentId]/[conversationId]/chat-box.svelte


3. src/lib/scss/custom/components/_markdown.scss Formatting +1/-1

Fix markdown list style positioning

• Changed list-style-position from inside to outside for better markdown list rendering

src/lib/scss/custom/components/_markdown.scss


View more (2)
4. src/lib/scss/custom/pages/_chat.scss Formatting +7/-9

Update tag container and add input styling

• Changed scrollbar-width from none to thin in .conv-tags-container
• Removed .conv-tag-unit class with flex layout and label styling
• Added new .conv-tag-add class with flex layout for tag input and button alignment

src/lib/scss/custom/pages/_chat.scss


5. src/lib/helpers/http.js ✨ Enhancement +1/-1

Improve markdown replacement with bullet points

• Updated replaceMarkdown() function to replace list dashes with bullet points using regex
 /^-\s*/gm to 
• Changed separator replacement from @@@ to ••• for consistent bullet point styling

src/lib/helpers/http.js


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Mar 10, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Dash line content corrupted 🐞 Bug ✓ Correctness
Description
replaceMarkdown now replaces any start-of-line '-' with a bullet, so content like "-1" or "--flag"
is rewritten (e.g., "-1" → "• 1") before Markdown rendering. This changes the meaning of
user/assistant messages and logs rendered through Markdown.svelte.
Code

src/lib/helpers/http.js[352]

+    let res = text.replace(/#([\s]+)/g, '\\# ').replace(/^-\s*/gm, '• ').replace(/[-|=]{3,}/g, '•••');
Evidence
The new regex ^\-\s* matches a leading dash even when no whitespace follows (because \s* can
match zero chars), so any line starting with '-' is transformed. Markdown.svelte always applies
replaceMarkdown() before marked() for non-raw rendering, so this corruption affects all normal
markdown-rendered text in the UI.

src/lib/helpers/http.js[346-362]
src/lib/common/markdown/Markdown.svelte[51-62]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`replaceMarkdown()` rewrites any line beginning with `-` into a bullet because it uses `/^\-\s*/gm` (`\s*` matches zero chars). This corrupts non-list text like negative numbers (`-1` -> `• 1`) and CLI flags (`--help` -> `• -help`) before `marked()` renders it.

### Issue Context
`Markdown.svelte` applies `replaceMarkdown()` for all non-raw markdown rendering.

### Fix Focus Areas
- src/lib/helpers/http.js[346-362]
- src/lib/common/markdown/Markdown.svelte[51-62]

### Suggested change
Update the regex to only match markdown list items (dash followed by whitespace), e.g.:
- `res = res.replace(/^-\s+/gm, '• ');`
Optionally require content after whitespace: `res.replace(/^-\s+(?=\S)/gm, '• ')`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Tag modal stale state 🐞 Bug ✓ Correctness
Description
updateChatTags() closes the Tags modal by setting isOpenTagModal=false directly, bypassing
toggleTagModal()’s close-time reset of newTagText and convTags. As a result, typed-but-not-added tag
text (and other transient state) can persist into subsequent modal openings and lead to unintended
edits.
Code

src/routes/chat/[agentId]/[conversationId]/chat-box.svelte[R1436-1461]

+		if (toAddTags.length === 0 && toDeleteTags.length === 0) {
+			isOpenTagModal = false;
+			return;
+		}
+
		isLoading = true;
		updateConversationTags(
			params.conversationId,
-			{
-				toAddTags: selectedTags,
-				toDeleteTags: tagOptions.filter(x => !selectedTags.includes(x.value)).map(x => x.value)
-			})
+			{ toAddTags, toDeleteTags })
		.then(res => {
			if (res) {
+				conversation.tags = [...convTags];
				isComplete = true;
-				successText = "Tags has been updated!";
+				successText = "Tags have been updated!";
				setTimeout(() => {
					isComplete = false;
					successText = "";
				}, duration);
			} else {
-				throw "Failed to update chat tags.";
+				throw "Failed to update tags.";
			}
		}).catch(() => {
-			selectedTags = conversation?.tags || [];
+			convTags = conversation?.tags || [];
			isError = true;
			errorText = "Failed to update tags!";
			setTimeout(() => {
Evidence
toggleTagModal() contains the only reset logic for newTagText and convTags, and it only runs
when the function is called and the modal is being closed. updateChatTags() closes the modal by
directly setting isOpenTagModal = false (including in the no-op early-return path), so the reset
block is never executed for these close paths.

src/routes/chat/[agentId]/[conversationId]/chat-box.svelte[1407-1413]
src/routes/chat/[agentId]/[conversationId]/chat-box.svelte[1431-1468]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Tags modal reset logic lives inside `toggleTagModal()` and only runs when closing via that function. `updateChatTags()` closes the modal by directly setting `isOpenTagModal = false` (including the no-op early return and in `.finally()`), so `newTagText`/`convTags` are not reset for those close paths.

### Issue Context
DialogModal unmounts on close, but component state variables persist; reopening the modal reuses `newTagText` because the reset was skipped.

### Fix Focus Areas
- src/routes/chat/[agentId]/[conversationId]/chat-box.svelte[1407-1468]

### Suggested change
Introduce a dedicated close helper that always resets, and use it everywhere you close the modal:
```js
function closeTagModal() {
 isOpenTagModal = false;
 newTagText = '';
 convTags = conversation?.tags || [];
}
```
Then replace `isOpenTagModal = false` in `updateChatTags()` (early return + finally) with `closeTagModal()`.
Optionally also initialize state on open (inside `toggleTagModal()` when opening) to guarantee a clean modal each time.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@iceljc iceljc merged commit aeb4b5d into SciSharp:main Mar 10, 2026
1 of 2 checks passed
*/
export function replaceMarkdown(text) {
let res = text.replace(/#([\s]+)/g, '\\# ').replace(/[-|=]{3,}/g, '@@@');
let res = text.replace(/#([\s]+)/g, '\\# ').replace(/^-\s*/gm, '• ').replace(/[-|=]{3,}/g, '•••');

Choose a reason for hiding this comment

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

Action required

1. Dash line content corrupted 🐞 Bug ✓ Correctness

replaceMarkdown now replaces any start-of-line '-' with a bullet, so content like "-1" or "--flag"
is rewritten (e.g., "-1" → "• 1") before Markdown rendering. This changes the meaning of
user/assistant messages and logs rendered through Markdown.svelte.
Agent Prompt
### Issue description
`replaceMarkdown()` rewrites any line beginning with `-` into a bullet because it uses `/^\-\s*/gm` (`\s*` matches zero chars). This corrupts non-list text like negative numbers (`-1` -> `• 1`) and CLI flags (`--help` -> `• -help`) before `marked()` renders it.

### Issue Context
`Markdown.svelte` applies `replaceMarkdown()` for all non-raw markdown rendering.

### Fix Focus Areas
- src/lib/helpers/http.js[346-362]
- src/lib/common/markdown/Markdown.svelte[51-62]

### Suggested change
Update the regex to only match markdown list items (dash followed by whitespace), e.g.:
- `res = res.replace(/^-\s+/gm, '• ');`
Optionally require content after whitespace: `res.replace(/^-\s+(?=\S)/gm, '• ')`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +1436 to 1461
if (toAddTags.length === 0 && toDeleteTags.length === 0) {
isOpenTagModal = false;
return;
}

isLoading = true;
updateConversationTags(
params.conversationId,
{
toAddTags: selectedTags,
toDeleteTags: tagOptions.filter(x => !selectedTags.includes(x.value)).map(x => x.value)
})
{ toAddTags, toDeleteTags })
.then(res => {
if (res) {
conversation.tags = [...convTags];
isComplete = true;
successText = "Tags has been updated!";
successText = "Tags have been updated!";
setTimeout(() => {
isComplete = false;
successText = "";
}, duration);
} else {
throw "Failed to update chat tags.";
throw "Failed to update tags.";
}
}).catch(() => {
selectedTags = conversation?.tags || [];
convTags = conversation?.tags || [];
isError = true;
errorText = "Failed to update tags!";
setTimeout(() => {

Choose a reason for hiding this comment

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

Action required

2. Tag modal stale state 🐞 Bug ✓ Correctness

updateChatTags() closes the Tags modal by setting isOpenTagModal=false directly, bypassing
toggleTagModal()’s close-time reset of newTagText and convTags. As a result, typed-but-not-added tag
text (and other transient state) can persist into subsequent modal openings and lead to unintended
edits.
Agent Prompt
### Issue description
The Tags modal reset logic lives inside `toggleTagModal()` and only runs when closing via that function. `updateChatTags()` closes the modal by directly setting `isOpenTagModal = false` (including the no-op early return and in `.finally()`), so `newTagText`/`convTags` are not reset for those close paths.

### Issue Context
DialogModal unmounts on close, but component state variables persist; reopening the modal reuses `newTagText` because the reset was skipped.

### Fix Focus Areas
- src/routes/chat/[agentId]/[conversationId]/chat-box.svelte[1407-1468]

### Suggested change
Introduce a dedicated close helper that always resets, and use it everywhere you close the modal:
```js
function closeTagModal() {
  isOpenTagModal = false;
  newTagText = '';
  convTags = conversation?.tags || [];
}
```
Then replace `isOpenTagModal = false` in `updateChatTags()` (early return + finally) with `closeTagModal()`.
Optionally also initialize state on open (inside `toggleTagModal()` when opening) to guarantee a clean modal each time.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

1 participant