From 9abdf7385c336d93599d55a624bd7516872cd16b Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Mon, 30 Jun 2025 17:12:27 -0500 Subject: [PATCH 1/8] add js interpreter --- src/lib/helpers/enums.js | 3 +- .../rich-content/rc-js-interpreter.svelte | 55 +++++++++++++++++++ .../rich-content/rc-message.svelte | 26 ++++++--- .../rich-content/rich-content.svelte | 6 +- 4 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte diff --git a/src/lib/helpers/enums.js b/src/lib/helpers/enums.js index 61f970bf..5c1d6614 100644 --- a/src/lib/helpers/enums.js +++ b/src/lib/helpers/enums.js @@ -27,7 +27,8 @@ const richType = { Button: 'button_template', MultiSelect: 'multi-select_template', Generic: 'generic_template', - Upload: 'upload_template' + Upload: 'upload_template', + JsCode: 'js_code', } export const RichType = Object.freeze(richType); diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte new file mode 100644 index 00000000..5ac2e719 --- /dev/null +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte @@ -0,0 +1,55 @@ + + +
+
+
\ No newline at end of file diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-message.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-message.svelte index 47f0ab42..e5ac1a96 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-message.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-message.svelte @@ -1,7 +1,9 @@ -
-
- +{#if text} +
+
+ {#if message?.rich_content?.message?.rich_type === RichType.JsCode} + + {:else} + + {/if} +
-
\ No newline at end of file +{/if} \ No newline at end of file diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rich-content.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rich-content.svelte index 5db267eb..6b1792c3 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rich-content.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rich-content.svelte @@ -48,11 +48,11 @@ } + + {#if message?.rich_content?.editor === EditorType.File} handleConfirm(title, payload)} /> -{/if} - -{#if message?.rich_content?.editor !== EditorType.File} +{:else} {#if !isComplexElement} handleConfirm(title, payload)} /> {:else} From 8bbaa0168e0319c5071e864b0f48547d87d61718 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Mon, 30 Jun 2025 17:32:24 -0500 Subject: [PATCH 2/8] add reply message --- .../rich-content/rc-js-interpreter.svelte | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte index 5ac2e719..84db9283 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte @@ -50,6 +50,11 @@ } -
-
+
+ {#if message?.text} +
{message.text}
+ {/if} +
+
+
\ No newline at end of file From cdd2582db7a1febcb4b248b5a900bb39b6017e75 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Mon, 30 Jun 2025 23:03:16 -0500 Subject: [PATCH 3/8] refine chart style --- .../[conversationId]/rich-content/rc-js-interpreter.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte index 84db9283..dd5165c1 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte @@ -55,6 +55,6 @@
{message.text}
{/if}
-
+
\ No newline at end of file From 4257a8059a7401197f0d970e10e562d0a35843ca Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Tue, 1 Jul 2025 17:32:24 -0500 Subject: [PATCH 4/8] refine log content style --- src/lib/helpers/http.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/helpers/http.js b/src/lib/helpers/http.js index 772494bc..0a57a962 100644 --- a/src/lib/helpers/http.js +++ b/src/lib/helpers/http.js @@ -212,7 +212,7 @@ export function replaceNewLine(text) { * @returns {string} */ export function replaceMarkdown(text) { - let res = text.replace(/#([\s]+)/g, '\\# ').replace(/[-|=]{3,}/g, ''); + let res = text.replace(/#([\s]+)/g, '\\# ').replace(/[-|=]{3,}/g, '@@@'); let regex1 = new RegExp('\\*(.*)\\*', 'g'); let regex2 = new RegExp('\\*([\\*]+)\\*', 'g'); From 436bb007c7c0362e6585d4513254b411bb08293d Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Wed, 2 Jul 2025 11:50:26 -0500 Subject: [PATCH 5/8] refine load script --- .../rich-content/rc-js-interpreter.svelte | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte index dd5165c1..116f5412 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte @@ -41,12 +41,35 @@ } function initCode() { - const text = message?.rich_content?.message?.text || message?.text || ''; - const parsedText = marked.lexer(text); - // @ts-ignore - const codeText = parsedText.find(token => token.type === 'code' || token.type === 'html')?.text || ''; - const code = codeText.replace(/]*>([\s\S]*?)<\/script>/i, '$1'); - eval(code); + try { + const text = message?.rich_content?.message?.text || message?.text || ''; + const parsedText = marked.lexer(text); + // @ts-ignore + const codeText = parsedText.filter(x => !!x.text).map(x => x.text).join(''); + loadScript(codeText); + } catch (error) { + console.error('Error parsing js code:', error); + } + } + + /** @param {string} codeText */ + function loadScript(codeText) { + const code = codeText.replace(/]*>([\s\S]*?)<\/script>/gi, '$1'); + const matchedSrcs = codeText.match(/]*src\s*=\s*["']([^"']+)["'][^>]*>/i); + if (matchedSrcs && matchedSrcs[1]) { + const curScripts = document.head.getElementsByTagName("script"); + const found = Array.from(curScripts).find(x => x.src === matchedSrcs[1]); + if (found) { + found.remove(); + } + + const script = document.createElement('script'); + script.src = matchedSrcs[1]; + script.onload = () => eval(code); + document.head.appendChild(script); + } else { + eval(code); + } } From c8b579abdc70bcc0bc5dd2ef84cc58a09f4f239b Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Wed, 2 Jul 2025 11:53:58 -0500 Subject: [PATCH 6/8] refine scrollbar id --- src/lib/common/markdown/Markdown.svelte | 7 +++---- .../[conversationId]/rich-content/rc-js-interpreter.svelte | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/lib/common/markdown/Markdown.svelte b/src/lib/common/markdown/Markdown.svelte index e3950a20..aa6eb7ba 100644 --- a/src/lib/common/markdown/Markdown.svelte +++ b/src/lib/common/markdown/Markdown.svelte @@ -21,8 +21,7 @@ /** @type {boolean} */ export let scrollable = false; - const scrollbarId = uuidv4(); - + const scrollbarId = `markdown-scrollbar-${uuidv4()}`; const options = { scrollbars: { visibility: 'auto', @@ -42,7 +41,7 @@ }); function initScrollbar() { - const elem = document.querySelector(`#markdown-scrollbar-${scrollbarId}`); + const elem = document.querySelector(`#${scrollbarId}`); if (elem) { // @ts-ignore const scrollbar = OverlayScrollbars(elem, options); @@ -65,7 +64,7 @@
diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte index 116f5412..52437b60 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte @@ -11,7 +11,7 @@ /** @type {boolean} */ export let scrollable = false; - const scrollbarId = uuidv4(); + const scrollbarId = `js-interpreter-scrollbar-${uuidv4()}`; const options = { scrollbars: { visibility: 'auto', @@ -33,7 +33,7 @@ }); function initScrollbar() { - const elem = document.querySelector(`#js-interpreter-scrollbar-${scrollbarId}`); + const elem = document.querySelector(`#${scrollbarId}`); if (elem) { // @ts-ignore const scrollbar = OverlayScrollbars(elem, options); @@ -77,7 +77,7 @@ {#if message?.text}
{message.text}
{/if} -
+
\ No newline at end of file From 701178441aec5b5ee8718f359c8ff8405584aa3b Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Tue, 8 Jul 2025 17:44:09 -0500 Subject: [PATCH 7/8] sync code template --- src/lib/helpers/enums.js | 2 +- src/lib/helpers/types/conversationTypes.js | 10 ++++++++++ .../[conversationId]/rich-content/rc-message.svelte | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/lib/helpers/enums.js b/src/lib/helpers/enums.js index 5c1d6614..46bf4ba6 100644 --- a/src/lib/helpers/enums.js +++ b/src/lib/helpers/enums.js @@ -28,7 +28,7 @@ const richType = { MultiSelect: 'multi-select_template', Generic: 'generic_template', Upload: 'upload_template', - JsCode: 'js_code', + ProgramCode: 'program_code', } export const RichType = Object.freeze(richType); diff --git a/src/lib/helpers/types/conversationTypes.js b/src/lib/helpers/types/conversationTypes.js index a7b436f3..42d90cba 100644 --- a/src/lib/helpers/types/conversationTypes.js +++ b/src/lib/helpers/types/conversationTypes.js @@ -104,6 +104,16 @@ IRichContent.prototype.elements; */ IRichContent.prototype.quick_replies; +/** + * The language of the code rich content. + * + * @name language + * @type {string} + * @instance + */ +IRichContent.prototype.language; + + /** * @typedef {Object} TextMessage * @property {string} text diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-message.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-message.svelte index e5ac1a96..1367aee5 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-message.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-message.svelte @@ -24,7 +24,8 @@ style={`${containerStyles}`} >
- {#if message?.rich_content?.message?.rich_type === RichType.JsCode} + {#if message?.rich_content?.message?.rich_type === RichType.ProgramCode + && message?.rich_content?.message?.language === 'javascript'} {:else} From d373619441928cb6a70e0dd4a2dc80a77a365301 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Fri, 11 Jul 2025 15:27:46 -0500 Subject: [PATCH 8/8] allow loading multiple script sources --- .../rich-content/rc-js-interpreter.svelte | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte index 52437b60..56057155 100644 --- a/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte +++ b/src/routes/chat/[agentId]/[conversationId]/rich-content/rc-js-interpreter.svelte @@ -55,21 +55,43 @@ /** @param {string} codeText */ function loadScript(codeText) { const code = codeText.replace(/]*>([\s\S]*?)<\/script>/gi, '$1'); - const matchedSrcs = codeText.match(/]*src\s*=\s*["']([^"']+)["'][^>]*>/i); - if (matchedSrcs && matchedSrcs[1]) { + const scriptTags = [...codeText.matchAll(/]*src\s*=\s*["']([^"']+)["'][^>]*>/gi)]; + const matchedSrcs = scriptTags.filter(x => !!x[1]).map(x => x[1]); + + if (matchedSrcs.length > 0) { + const promises = matchedSrcs.map(x => loadScriptSrc(x)); + Promise.all(promises).then(() => setTimeout(() => eval(code), 0)); + } else { + setTimeout(() => eval(code), 0); + } + } + + /** @param {string} src */ + function loadScriptSrc(src) { + return new Promise(resolve => { const curScripts = document.head.getElementsByTagName("script"); - const found = Array.from(curScripts).find(x => x.src === matchedSrcs[1]); + const found = Array.from(curScripts).find(x => x.src === src); if (found) { found.remove(); } const script = document.createElement('script'); - script.src = matchedSrcs[1]; - script.onload = () => eval(code); + script.async = false; + script.src = src; + script.onload = () => { + setTimeout(() => { + console.log(`Script loaded: ${src}`); + resolve(true); + }, 0); + } + script.onerror = () => { + setTimeout(() => { + console.log(`Error when loading script: ${src}`); + resolve(false); + }, 0); + } document.head.appendChild(script); - } else { - eval(code); - } + }); }