Skip to content

Commit ef15a97

Browse files
committed
feat: convert bare URLs to hyperlinks in bot responses
- Add getProcessedText utility to transform plain URLs into markdown links - Preserve existing markdown and HTML links unchanged - Handle trailing punctuation correctly (e.g., "Visit https://example.com.") - Integrate URL processing into QA flow before markdown rendering Addresses requirement to make URLs clickable while preserving existing link formatting.
1 parent f8c8672 commit ef15a97

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

src/utils/flows/qa-flow.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { handleBotError } from '../error-handler';
22
import { getApiEndpoint, getRatingEndpoint } from '../../config/constants';
33
import { v4 as uuidv4 } from 'uuid';
4+
import { getProcessedText } from '../getProcessedText';
45

56
/**
67
* Creates the Q&A conversation flow
@@ -25,7 +26,7 @@ export const createQAFlow = ({ sessionId, apiKey }) => {
2526

2627
// Handle feedback first if it's feedback
2728
if (userInput === "👍 Helpful" || userInput === "👎 Not helpful") {
28-
29+
2930
// Send feedback using the captured query ID
3031
if (apiKey && sessionId && feedbackQueryId) {
3132
const isPositive = userInput === "👍 Helpful";
@@ -56,7 +57,7 @@ export const createQAFlow = ({ sessionId, apiKey }) => {
5657
// Generate our own query ID since we're bypassing useHandleAIQuery
5758
const queryId = uuidv4();
5859
feedbackQueryId = queryId;
59-
60+
6061
const headers = {
6162
'Content-Type': 'application/json',
6263
'X-Origin': 'access',
@@ -72,12 +73,14 @@ export const createQAFlow = ({ sessionId, apiKey }) => {
7273
query: userInput
7374
})
7475
});
75-
76+
7677
const body = await response.json();
7778
const text = body.response;
78-
79+
const processedText = getProcessedText(text);
80+
81+
7982
// Inject the response
80-
await chatState.injectMessage(text);
83+
await chatState.injectMessage(processedText);
8184
return null;
8285
} catch (error) {
8386
console.error('Error in bot flow:', error);

src/utils/getProcessedText.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Processes text to convert bare URLs into markdown hyperlinks while preserving existing links
3+
* @param {string} text - The raw text from the API response
4+
* @returns {string} - Processed text with bare URLs converted to markdown links
5+
*/
6+
export const getProcessedText = (text) => {
7+
if (!text || typeof text !== 'string') {
8+
return text;
9+
}
10+
11+
// Regex to match URLs that are NOT already in markdown or HTML link format
12+
// This looks for URLs that are not preceded by ]( or href=" and not followed by )
13+
const urlRegex = /(?<!\]\(|href=["'])https?:\/\/[^\s\[\]()]+(?![)\]])/gi;
14+
15+
// Replace bare URLs with markdown links
16+
const processedText = text.replace(urlRegex, (url) => {
17+
// Clean up common punctuation that shouldn't be part of the URL
18+
let cleanUrl = url;
19+
let trailingPunctuation = '';
20+
21+
// Check for trailing punctuation and remove it from the URL
22+
const trailingPunctuationMatch = cleanUrl.match(/([.,;:!?]+)$/);
23+
if (trailingPunctuationMatch) {
24+
trailingPunctuation = trailingPunctuationMatch[1];
25+
cleanUrl = cleanUrl.slice(0, -trailingPunctuation.length);
26+
}
27+
28+
// Create markdown link with the URL as both the link text and href
29+
return `[${cleanUrl}](${cleanUrl})${trailingPunctuation}`;
30+
});
31+
32+
return processedText;
33+
};

0 commit comments

Comments
 (0)