From 0bb6ce33beafeeae9e2f146563ec56786477da34 Mon Sep 17 00:00:00 2001 From: Weirui Kuang <39145382+rayrayraykk@users.noreply.github.com> Date: Fri, 25 Oct 2024 18:06:30 +0800 Subject: [PATCH] linter (#44) --- .eslintrc | 17 + .pre-commit-config.yaml | 14 + .stylelintrc | 6 + docs/sphinx_doc/en/source/_static/custom.css | 4 +- .../zh_CN/source/_static/custom.css | 4 +- src/agentscope/studio/static/css/base.css | 128 +- .../static/css/dashboard-detail-code.css | 138 +- .../static/css/dashboard-detail-dialogue.css | 620 +- .../css/dashboard-detail-invocation.css | 60 +- .../studio/static/css/dashboard-detail.css | 100 +- .../studio/static/css/dashboard-runs.css | 126 +- .../studio/static/css/dashboard.css | 46 +- src/agentscope/studio/static/css/font.css | 8 +- src/agentscope/studio/static/css/gallery.css | 88 +- src/agentscope/studio/static/css/index.css | 398 +- src/agentscope/studio/static/css/login.css | 198 +- src/agentscope/studio/static/css/server.css | 154 +- .../css/workstation-drag-components.css | 186 +- .../studio/static/css/workstation.css | 1432 ++--- .../studio/static/js/dashboard-detail-code.js | 114 +- .../static/js/dashboard-detail-dialogue.js | 1008 ++-- .../static/js/dashboard-detail-invocation.js | 134 +- .../studio/static/js/dashboard-detail.js | 144 +- .../studio/static/js/dashboard-runs.js | 194 +- src/agentscope/studio/static/js/dashboard.js | 194 +- src/agentscope/studio/static/js/gallery.js | 482 +- src/agentscope/studio/static/js/index.js | 512 +- src/agentscope/studio/static/js/server.js | 808 +-- .../studio/static/js/workstation.js | 5349 ++++++++--------- .../studio/static/js/workstation_iframe.js | 4 +- 30 files changed, 6360 insertions(+), 6310 deletions(-) create mode 100644 .eslintrc create mode 100644 .stylelintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..dcd27a36f --- /dev/null +++ b/.eslintrc @@ -0,0 +1,17 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "rules": { + "semi": ["error", "always"], + "quotes": ["error", "double"], + "indent": ["error", 2], + "linebreak-style": ["error", "unix"], + "brace-style": ["error", "1tbs"], + "curly": ["error", "all"], + "no-eval": ["error"], + "prefer-const": ["error"], + "arrow-spacing": ["error", { "before": true, "after": true }] + } +} \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fbd2fb365..3bc9b261f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -99,6 +99,20 @@ repos: --disable=W0201, --disable=C0302, ] + - repo: https://github.com/pre-commit/mirrors-eslint + rev: v7.32.0 + hooks: + - id: eslint + files: \.(js|jsx)$ + exclude: '.*js_third_party.*' + args: ['--fix'] + - repo: https://github.com/thibaudcolas/pre-commit-stylelint + rev: v14.4.0 + hooks: + - id: stylelint + files: \.(css|scss|sass|less)$ + exclude: '.*css_third_party.*' + args: ['--fix'] - repo: https://github.com/regebro/pyroma rev: "4.0" hooks: diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 000000000..52759563b --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,6 @@ +{ + "rules": { + "indentation": 2, + "string-quotes": "single" + } +} \ No newline at end of file diff --git a/docs/sphinx_doc/en/source/_static/custom.css b/docs/sphinx_doc/en/source/_static/custom.css index 68f11ceed..02b7f4cbe 100644 --- a/docs/sphinx_doc/en/source/_static/custom.css +++ b/docs/sphinx_doc/en/source/_static/custom.css @@ -1,4 +1,4 @@ .language-selector a { - color: white; - width: 20px; + color: white; + width: 20px; } \ No newline at end of file diff --git a/docs/sphinx_doc/zh_CN/source/_static/custom.css b/docs/sphinx_doc/zh_CN/source/_static/custom.css index 68f11ceed..02b7f4cbe 100644 --- a/docs/sphinx_doc/zh_CN/source/_static/custom.css +++ b/docs/sphinx_doc/zh_CN/source/_static/custom.css @@ -1,4 +1,4 @@ .language-selector a { - color: white; - width: 20px; + color: white; + width: 20px; } \ No newline at end of file diff --git a/src/agentscope/studio/static/css/base.css b/src/agentscope/studio/static/css/base.css index c6ea9a188..cc1340378 100644 --- a/src/agentscope/studio/static/css/base.css +++ b/src/agentscope/studio/static/css/base.css @@ -1,31 +1,31 @@ :root { - --tab-btn-icon-length: 20px; + --tab-btn-icon-length: 20px; - --body-bg: #ffffff; + --body-bg: #ffffff; - --main-color: #59AC80; - --main-color-light: #A0D9C4; - --main-color-light-light: #D1E9DC; - --main-color-very-light: #F3F9F1; - --main-color-dark: #3D7D5A; - --base-color: #F3F9F1; + --main-color: #59AC80; + --main-color-light: #A0D9C4; + --main-color-light-light: #D1E9DC; + --main-color-very-light: #F3F9F1; + --main-color-dark: #3D7D5A; + --base-color: #F3F9F1; - --border-color: #EBEBF0; + --border-color: #EBEBF0; - /*Titlebar for each page*/ - --page-titlebar-height: 60px; - --page-content-height: calc(100% - var(--page-titlebar-height)); + /*Titlebar for each page*/ + --page-titlebar-height: 60px; + --page-content-height: calc(100% - var(--page-titlebar-height)); - /*Navigation bar*/ - --page-sidebar-width: 250px; + /*Navigation bar*/ + --page-sidebar-width: 250px; } /*Text cannot be selected*/ .unselectable-text { - -webkit-user-select: none; /* Safari */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* IE10+/Edge */ - user-select: none; /* Standard */ + -webkit-user-select: none; /* Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+/Edge */ + user-select: none; /* Standard */ } a { @@ -33,78 +33,78 @@ a { } .page-titlebar { - display: flex; - justify-content: space-between; - width: 100%; - height: var(--page-titlebar-height); - flex-direction: row; - align-items: center; - border-bottom: 1px solid var(--border-color); - box-sizing: border-box; - padding: 0 20px; + display: flex; + justify-content: space-between; + width: 100%; + height: var(--page-titlebar-height); + flex-direction: row; + align-items: center; + border-bottom: 1px solid var(--border-color); + box-sizing: border-box; + padding: 0 20px; } .github-user-content{ - display: flex; - align-items: center; + display: flex; + align-items: center; } .user-detail{ - display: flex; - position: relative; - cursor: pointer; + display: flex; + position: relative; + cursor: pointer; } .user-option{ - position: relative; - display: flex;; - margin-right: 5px; + position: relative; + display: flex;; + margin-right: 5px; } .user-option a{ - color: black; - text-decoration: none; - font-weight: normal; + color: black; + text-decoration: none; + font-weight: normal; } .triangle-down { - width: 0; - height: 0; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-top: 5px solid gray; - position: relative; - transform: translateY(10px); - margin-left: 5px; + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid gray; + position: relative; + transform: translateY(10px); + margin-left: 5px; } .user-detail:hover .dropdown { - display: block; + display: block; } .dropdown { - display: none; - position: absolute; - width: 100%; - top:100%; - left: 0; - background-color: #f9f9f9; - box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); - z-index: 1; - white-space: nowrap; - border-radius: 0 0px 5px 5px; - overflow: hidden; + display: none; + position: absolute; + width: 100%; + top:100%; + left: 0; + background-color: #f9f9f9; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1; + white-space: nowrap; + border-radius: 0 0px 5px 5px; + overflow: hidden; } .dropdown a { - color: black; - padding: 4px 8px; - text-decoration: none; - display: block; + color: black; + padding: 4px 8px; + text-decoration: none; + display: block; } .dropdown a:hover { - background-color: #f1f1f1; + background-color: #f1f1f1; } .triangle-down:hover { - border-top: 5px solid #000; + border-top: 5px solid #000; } diff --git a/src/agentscope/studio/static/css/dashboard-detail-code.css b/src/agentscope/studio/static/css/dashboard-detail-code.css index fb1e7c748..cc2fdcb72 100644 --- a/src/agentscope/studio/static/css/dashboard-detail-code.css +++ b/src/agentscope/studio/static/css/dashboard-detail-code.css @@ -1,101 +1,101 @@ :root { - --code-list-width: 350px; - --code-content-width: calc(100% - var(--code-list-width)); + --code-list-width: 350px; + --code-content-width: calc(100% - var(--code-list-width)); } #code-body { - display: flex; - flex-direction: row; - height: 100%; - width: 100%; + display: flex; + flex-direction: row; + height: 100%; + width: 100%; } #code-list { - display: flex; - flex-direction: column; - height: 100%; - width: var(--code-list-width); - box-sizing: border-box; - border: 0; + display: flex; + flex-direction: column; + height: 100%; + width: var(--code-list-width); + box-sizing: border-box; + border: 0; } #code-list ul { - display: block; - flex-direction: column; - align-items: flex-start; - justify-content: center; - width: 100%; - height: 35px; - box-sizing: border-box; - border-bottom: 1px solid var(--border-color); - padding: 5px; - margin: 0 0 3px 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + display: block; + flex-direction: column; + align-items: flex-start; + justify-content: center; + width: 100%; + height: 35px; + box-sizing: border-box; + border-bottom: 1px solid var(--border-color); + padding: 5px; + margin: 0 0 3px 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } #code-filename { - display: block; - flex-direction: column; - align-items: flex-start; - justify-content: center; - width: 100%; - height: 35px; - box-sizing: border-box; - border-bottom: 1px solid var(--border-color); - padding: 5px; - margin: 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + display: block; + flex-direction: column; + align-items: flex-start; + justify-content: center; + width: 100%; + height: 35px; + box-sizing: border-box; + border-bottom: 1px solid var(--border-color); + padding: 5px; + margin: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } #code-list li { - display: flex; - flex-direction: column; - align-items: flex-start; - justify-content: center; - width: 100%; - height: 35px; - padding: 3px 15px; - margin: 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - box-sizing: border-box; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + width: 100%; + height: 35px; + padding: 3px 15px; + margin: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + box-sizing: border-box; } #code-list li:hover { - background-color: var(--main-color-light-light); - cursor: pointer; + background-color: var(--main-color-light-light); + cursor: pointer; } #code-list li.selected { - background-color: var(--main-color-light); + background-color: var(--main-color-light); } #code-list ul:hover { - background-color: var(--main-color-light); - overflow: visible; - width: fit-content; - border-radius: 5px; - z-index: 10; + background-color: var(--main-color-light); + overflow: visible; + width: fit-content; + border-radius: 5px; + z-index: 10; } #code-content { - display: flex; - flex-direction: column; - width: var(--code-content-width); - height: 100%; - box-sizing: border-box; - border: 1px solid var(--border-color); + display: flex; + flex-direction: column; + width: var(--code-content-width); + height: 100%; + box-sizing: border-box; + border: 1px solid var(--border-color); } #code-editor { - display: flex; - width: 100%; - height: 100%; - overflow: auto; - white-space: pre; + display: flex; + width: 100%; + height: 100%; + overflow: auto; + white-space: pre; } diff --git a/src/agentscope/studio/static/css/dashboard-detail-dialogue.css b/src/agentscope/studio/static/css/dashboard-detail-dialogue.css index e7912f5b7..255fc6fc0 100644 --- a/src/agentscope/studio/static/css/dashboard-detail-dialogue.css +++ b/src/agentscope/studio/static/css/dashboard-detail-dialogue.css @@ -1,484 +1,484 @@ :root { - --chat-bubble-border-radius: 5px; + --chat-bubble-border-radius: 5px; - --chat-icon-width: 50px; - --chat-icon-height: 50px; - --chat-icon-horizontal-margin: 10px; - /*TODO: not used here*/ - --chat-icon-total-width: calc(var(--chat-icon-width) + var(--chat-icon-horizontal-margin) * 2); + --chat-icon-width: 50px; + --chat-icon-height: 50px; + --chat-icon-horizontal-margin: 10px; + /*TODO: not used here*/ + --chat-icon-total-width: calc(var(--chat-icon-width) + var(--chat-icon-horizontal-margin) * 2); - --chat-detail-width: 350px; + --chat-detail-width: 350px; - /*Switch bar*/ - --chat-detail-switch-width: 50px; - --chat-detail-swtich-btn-length: 40px; - --chat-detail-switch-svg-length: 20px; + /*Switch bar*/ + --chat-detail-switch-width: 50px; + --chat-detail-swtich-btn-length: 40px; + --chat-detail-switch-svg-length: 20px; - --chat-panel-width: calc(100% - var(--chat-detail-width) - var(--chat-detail-switch-width)); + --chat-panel-width: calc(100% - var(--chat-detail-width) - var(--chat-detail-switch-width)); - /*Input area*/ - --chat-input-panel-height: 100px; - --chat-control-panel-height: 56px; - --chat-control-btn-margin-top: 6px; + /*Input area*/ + --chat-input-panel-height: 100px; + --chat-control-panel-height: 56px; + --chat-control-btn-margin-top: 6px; - /*Delete button*/ - --chat-control-file-delete-length: 16px; - --chat-control-file-delete-position: -5px; + /*Delete button*/ + --chat-control-file-delete-length: 16px; + --chat-control-file-delete-position: -5px; - /*List item*/ - --chat-control-file-item-length: calc(var(--chat-control-panel-height) - var(--chat-control-btn-margin-top)); + /*List item*/ + --chat-control-file-item-length: calc(var(--chat-control-panel-height) - var(--chat-control-btn-margin-top)); - /*Should be smaller than --chat-control-file-item-length--*/ - --chat-control-file-svg-length: 35px; - --chat-control-file-svg-margin: calc((var(--chat-control-file-item-length) - var(--chat-control-file-svg-length)) / 2); + /*Should be smaller than --chat-control-file-item-length--*/ + --chat-control-file-svg-length: 35px; + --chat-control-file-svg-margin: calc((var(--chat-control-file-item-length) - var(--chat-control-file-svg-length)) / 2); - --chat-input-panel-font-size: 15px; + --chat-input-panel-font-size: 15px; } #chat-body { - display: flex; - flex-direction: row; - width: 100%; - height: 100%; + display: flex; + flex-direction: row; + width: 100%; + height: 100%; } #chat-panel { - display: flex; - flex-direction: column; - width: var(--chat-panel-width); - height: 100%; - padding: 50px 50px; - box-sizing: border-box; + display: flex; + flex-direction: column; + width: var(--chat-panel-width); + height: 100%; + padding: 50px 50px; + box-sizing: border-box; } #chat-detail { - display: flex; - flex-direction: column; - height: 100%; - max-height: 100%; - width: var(--chat-detail-width); - box-sizing: border-box; - border-left: 1px solid var(--border-color); - padding: 50px 20px; + display: flex; + flex-direction: column; + height: 100%; + max-height: 100%; + width: var(--chat-detail-width); + box-sizing: border-box; + border-left: 1px solid var(--border-color); + padding: 50px 20px; } #chat-detail-switch { - display: flex; - flex-direction: column; - align-items: center; - height: 100%; - width: var(--chat-detail-switch-width); - box-sizing: border-box; - border-left: 1px solid var(--border-color); + display: flex; + flex-direction: column; + align-items: center; + height: 100%; + width: var(--chat-detail-switch-width); + box-sizing: border-box; + border-left: 1px solid var(--border-color); } .chat-detail-switch-btn { - display: flex; - flex-direction: column; - width: var(--chat-detail-swtich-btn-length); - height: var(--chat-detail-swtich-btn-length); - align-items: center; - justify-content: center; - cursor: pointer; - box-sizing: border-box; - border-radius: 10px; - margin-top: 10px; - fill: #000000; + display: flex; + flex-direction: column; + width: var(--chat-detail-swtich-btn-length); + height: var(--chat-detail-swtich-btn-length); + align-items: center; + justify-content: center; + cursor: pointer; + box-sizing: border-box; + border-radius: 10px; + margin-top: 10px; + fill: #000000; } .chat-detail-switch-btn svg { - display: flex; - width: var(--chat-detail-switch-svg-length); - height: var(--chat-detail-switch-svg-length); - align-items: center; - justify-content: center; + display: flex; + width: var(--chat-detail-switch-svg-length); + height: var(--chat-detail-switch-svg-length); + align-items: center; + justify-content: center; } .chat-detail-switch-btn:hover { - background-color: var(--main-color-light); - fill: var(--base-color); + background-color: var(--main-color-light); + fill: var(--base-color); } .chat-detail-switch-btn:active { - background-color: var(--main-color-dark); - fill: var(--base-color); + background-color: var(--main-color-dark); + fill: var(--base-color); } .chat-detail-switch-btn.selected { - background-color: var(--main-color); - fill: var(--base-color); + background-color: var(--main-color); + fill: var(--base-color); } #dialogue-detail-content { - display: flex; - height: 100%; - width: 100%; - flex-direction: column; - max-height: 100%; - max-width: 100%; - box-sizing: border-box; - white-space: normal; - word-wrap: break-word; - overflow-wrap: break-word; + display: flex; + height: 100%; + width: 100%; + flex-direction: column; + max-height: 100%; + max-width: 100%; + box-sizing: border-box; + white-space: normal; + word-wrap: break-word; + overflow-wrap: break-word; } #dialogue-info-title { - display: flex; - flex-direction: column; - justify-content: center; - font-weight: bold; - width: 100%; - height: 50px; - font-size: 18px; + display: flex; + flex-direction: column; + justify-content: center; + font-weight: bold; + width: 100%; + height: 50px; + font-size: 18px; } .dialogue-info-key { - display: flex; - width: 100%; - height: 30px; - align-items: center; - font-size: 15px; - font-weight: bold; + display: flex; + width: 100%; + height: 30px; + align-items: center; + font-size: 15px; + font-weight: bold; } .dialogue-info-value { - display: flex; - background-color: var(--border-color); - height: fit-content; - width: 100%; - max-width: 100%; - align-items: center; - padding: 5px 10px; - border-radius: 2px; - min-height: 33px; - box-sizing: border-box; - word-break: break-word; - overflow-wrap: break-word; - white-space: pre-wrap; + display: flex; + background-color: var(--border-color); + height: fit-content; + width: 100%; + max-width: 100%; + align-items: center; + padding: 5px 10px; + border-radius: 2px; + min-height: 33px; + box-sizing: border-box; + word-break: break-word; + overflow-wrap: break-word; + white-space: pre-wrap; } .dialogue-info-row { - display: flex; - flex-direction: column; - width: 100%; - height: fit-content; - margin: 5px 0; + display: flex; + flex-direction: column; + width: 100%; + height: fit-content; + margin: 5px 0; } #chat-box { - display: flex; - box-sizing: border-box; - flex-direction: column; - width: 100%; - flex-grow: 1; - margin-bottom: 50px; - max-height: 100%; - border: 1px solid var(--border-color); - border-radius: 8px; + display: flex; + box-sizing: border-box; + flex-direction: column; + width: 100%; + flex-grow: 1; + margin-bottom: 50px; + max-height: 100%; + border: 1px solid var(--border-color); + border-radius: 8px; } #chat-box-content { - display: flex; - width: 100%; - height: 100%; - flex-direction: column; - max-height: 100%; + display: flex; + width: 100%; + height: 100%; + flex-direction: column; + max-height: 100%; } .chat-row { - display: flex; - flex-direction: row; - box-sizing: border-box; - width: 100%; - height: fit-content; - padding: 10px 0; + display: flex; + flex-direction: row; + box-sizing: border-box; + width: 100%; + height: fit-content; + padding: 10px 0; } .chat-row:hover { - background-color: var(--main-color-very-light); + background-color: var(--main-color-very-light); } .user.chat-row { - justify-content: flex-end; + justify-content: flex-end; } .text-right-align { - text-align: right; + text-align: right; } .chat-icon { - display: flex; - justify-content: center; - box-sizing: border-box; - width: var(--chat-icon-width); - height: var(--chat-icon-height); - border-radius: 5px; - margin: 0 var(--chat-icon-horizontal-margin); - padding: 10px; - background-color: var(--main-color); - fill: #ffffff; + display: flex; + justify-content: center; + box-sizing: border-box; + width: var(--chat-icon-width); + height: var(--chat-icon-height); + border-radius: 5px; + margin: 0 var(--chat-icon-horizontal-margin); + padding: 10px; + background-color: var(--main-color); + fill: #ffffff; } .chat-content { - display: flex; - flex-direction: column; - width: calc(100% - 140px); - /*TODO: for test*/ - box-sizing: border-box; + display: flex; + flex-direction: column; + width: calc(100% - 140px); + /*TODO: for test*/ + box-sizing: border-box; } .user.chat-content { - align-items: flex-end; + align-items: flex-end; } .chat-name { - display: flex; - margin-bottom: 5px; + display: flex; + margin-bottom: 5px; } .chat-bubble { - display: flex; - flex-direction: column; - border: 1px solid var(--main-color-light); - background-color: #ffffff; - flex-grow: 1; - box-sizing: border-box; - padding: 10px; - width: fit-content; - max-width: 100%; - min-width: 100px; - word-wrap: break-word; - overflow-wrap: break-word; + display: flex; + flex-direction: column; + border: 1px solid var(--main-color-light); + background-color: #ffffff; + flex-grow: 1; + box-sizing: border-box; + padding: 10px; + width: fit-content; + max-width: 100%; + min-width: 100px; + word-wrap: break-word; + overflow-wrap: break-word; } .user.chat-bubble { - border-radius: var(--chat-bubble-border-radius) 0 var(--chat-bubble-border-radius) var(--chat-bubble-border-radius); - white-space: pre-wrap; + border-radius: var(--chat-bubble-border-radius) 0 var(--chat-bubble-border-radius) var(--chat-bubble-border-radius); + white-space: pre-wrap; } .other.chat-bubble { - border-radius: 0 var(--chat-bubble-border-radius) var(--chat-bubble-border-radius) var(--chat-bubble-border-radius); + border-radius: 0 var(--chat-bubble-border-radius) var(--chat-bubble-border-radius) var(--chat-bubble-border-radius); } .chat-bubble p { - display: inline; - flex-direction: row; - align-items: center; - margin: 0; + display: inline; + flex-direction: row; + align-items: center; + margin: 0; } .chat-bubble-multimodal-item { - display: flex; - max-height: 200px; - max-width: 100%; - width: auto; - height: auto; - min-height: 50px; - min-width: 50px; - margin-top: 5px; + display: flex; + max-height: 200px; + max-width: 100%; + width: auto; + height: auto; + min-height: 50px; + min-width: 50px; + margin-top: 5px; } #chat-input { - display: flex; - height: fit-content; - width: 100%; - box-sizing: border-box; - border: 1px solid var(--border-color); - border-radius: 8px; - flex-direction: column; - padding: 10px; + display: flex; + height: fit-content; + width: 100%; + box-sizing: border-box; + border: 1px solid var(--border-color); + border-radius: 8px; + flex-direction: column; + padding: 10px; } #chat-input:focus { - border-color: var(--main-color); + border-color: var(--main-color); } #chat-input-name { - display: flex; - flex-direction: column; - width: fit-content; - max-width: 100px; - height: fit-content; - margin-right: 5px; - align-items: center; - justify-content: center; - box-sizing: border-box; - padding: 2px; - font-size: var(--chat-input-panel-font-size); + display: flex; + flex-direction: column; + width: fit-content; + max-width: 100px; + height: fit-content; + margin-right: 5px; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 2px; + font-size: var(--chat-input-panel-font-size); } #chat-input-textarea { - display: flex; - flex-grow: 1; - height: 100%; - resize: none; - box-sizing: border-box; - padding: 2px; - font-size: var(--chat-input-panel-font-size); - font-family: source-sans, sans-serif; + display: flex; + flex-grow: 1; + height: 100%; + resize: none; + box-sizing: border-box; + padding: 2px; + font-size: var(--chat-input-panel-font-size); + font-family: source-sans, sans-serif; - /*remove border*/ - border-color: transparent; - border-width: 0; - outline: none; + /*remove border*/ + border-color: transparent; + border-width: 0; + outline: none; } #chat-control-panel { - display: flex; - flex-direction: row; - justify-content: flex-end; - align-items: center; - height: var(--chat-control-panel-height); - width: 100%; - box-sizing: border-box; + display: flex; + flex-direction: row; + justify-content: flex-end; + align-items: center; + height: var(--chat-control-panel-height); + width: 100%; + box-sizing: border-box; } #chat-control-url-btn svg { - display: flex; - height: 20px; - width: 20px; - align-items: center; - justify-content: center; + display: flex; + height: 20px; + width: 20px; + align-items: center; + justify-content: center; } #chat-input-panel { - display: flex; - width: 100%; - height: var(--chat-input-panel-height); - flex-direction: row; + display: flex; + width: 100%; + height: var(--chat-input-panel-height); + flex-direction: row; } .chat-control-btn { - display: flex; - flex-direction: row; - align-items: center; - height: calc(100% - var(--chat-control-btn-margin-top)); - border-radius: 5px; - padding: 0 15px; - border: none; - font-size: 15px; - cursor: pointer; - background-color: var(--main-color-light-light); - color: var(--main-color-dark); - fill: var(--main-color-dark); - margin-top: var(--chat-control-btn-margin-top); + display: flex; + flex-direction: row; + align-items: center; + height: calc(100% - var(--chat-control-btn-margin-top)); + border-radius: 5px; + padding: 0 15px; + border: none; + font-size: 15px; + cursor: pointer; + background-color: var(--main-color-light-light); + color: var(--main-color-dark); + fill: var(--main-color-dark); + margin-top: var(--chat-control-btn-margin-top); } .chat-control-btn:disabled, .chat-control-btn:disabled:hover, .chat-control-btn:disabled:active { - background-color: var(--border-color); - color: var(--base-color); - fill: var(--base-color); - cursor: not-allowed; + background-color: var(--border-color); + color: var(--base-color); + fill: var(--base-color); + cursor: not-allowed; } #chat-control-url-btn { - width: fit-content; - margin-left: 10px; + width: fit-content; + margin-left: 10px; } #chat-control-send-btn { - width: fit-content; - margin-left: 10px; + width: fit-content; + margin-left: 10px; } #chat-control-file-list { - display: flex; - flex-direction: row; - align-items: flex-end; - height: 100%; - flex-grow: 1; - padding: 0 15px; - border: none; - font-size: 15px; - overflow-x: auto; + display: flex; + flex-direction: row; + align-items: flex-end; + height: 100%; + flex-grow: 1; + padding: 0 15px; + border: none; + font-size: 15px; + overflow-x: auto; } .chat-control-file-item { - position: relative; - display: inline-block; - border-radius: 5px; - align-items: center; - justify-content: center; - height: var(--chat-control-file-item-length); - width: var(--chat-control-file-item-length); - margin: 0 5px; - vertical-align: center; - text-align: center; + position: relative; + display: inline-block; + border-radius: 5px; + align-items: center; + justify-content: center; + height: var(--chat-control-file-item-length); + width: var(--chat-control-file-item-length); + margin: 0 5px; + vertical-align: center; + text-align: center; } .chat-control-file-item:hover { - background-color: var(--main-color-light); + background-color: var(--main-color-light); } .chat-control-file-delete { - position: absolute; - top: var(--chat-control-file-delete-position); - right: var(--chat-control-file-delete-position); - height: var(--chat-control-file-delete-length); - width: var(--chat-control-file-delete-length); - background-color: white; - fill: var(--main-color-dark); - border: 2px solid var(--main-color-dark); - border-radius: 50%; - cursor: pointer; - box-sizing: border-box; - display: none; + position: absolute; + top: var(--chat-control-file-delete-position); + right: var(--chat-control-file-delete-position); + height: var(--chat-control-file-delete-length); + width: var(--chat-control-file-delete-length); + background-color: white; + fill: var(--main-color-dark); + border: 2px solid var(--main-color-dark); + border-radius: 50%; + cursor: pointer; + box-sizing: border-box; + display: none; } .chat-control-file-delete > svg { - display: flex; - width: calc(var(--chat-control-file-delete-length) - 4px); - height: calc(var(--chat-control-file-delete-length) - 4px); + display: flex; + width: calc(var(--chat-control-file-delete-length) - 4px); + height: calc(var(--chat-control-file-delete-length) - 4px); } .chat-control-file-item:hover .chat-control-file-delete { - display: block; + display: block; } .chat-control-file-item > svg { - display: block; - margin: var(--chat-control-file-svg-margin); - height: var(--chat-control-file-svg-length); - width: var(--chat-control-file-svg-length); + display: block; + margin: var(--chat-control-file-svg-margin); + height: var(--chat-control-file-svg-length); + width: var(--chat-control-file-svg-length); } .chat-control-btn:hover { - background-color: var(--main-color); - color: var(--base-color); - fill: var(--base-color); + background-color: var(--main-color); + color: var(--base-color); + fill: var(--base-color); } .chat-control-btn:active { - background-color: var(--main-color-dark); - color: var(--base-color); - fill: var(--base-color); + background-color: var(--main-color-dark); + color: var(--base-color); + fill: var(--base-color); } .chat-control-send-btn-svg { - display: flex; - width: 20px; - height: 25px; - margin-left: 5px; + display: flex; + width: 20px; + height: 25px; + margin-left: 5px; } #hidden-file-input { - display: none; + display: none; } #agentSwitchBtn { - display: none; + display: none; } .chat-bubble pre code { - white-space: pre-wrap; - word-wrap: break-word; + white-space: pre-wrap; + word-wrap: break-word; } #chat-box-content .clusterize-no-data { - display: flex; - justify-content: center; - align-items: center; - height: 100%; - width: 100%; - color: var(--main-color-light); + display: flex; + justify-content: center; + align-items: center; + height: 100%; + width: 100%; + color: var(--main-color-light); } \ No newline at end of file diff --git a/src/agentscope/studio/static/css/dashboard-detail-invocation.css b/src/agentscope/studio/static/css/dashboard-detail-invocation.css index 6a7f1782e..29ec10ccb 100644 --- a/src/agentscope/studio/static/css/dashboard-detail-invocation.css +++ b/src/agentscope/studio/static/css/dashboard-detail-invocation.css @@ -1,44 +1,44 @@ #invocation-body { - display: flex; - flex-direction: row; - align-items: flex-end; - height: 100%; - width: 100%; + display: flex; + flex-direction: row; + align-items: flex-end; + height: 100%; + width: 100%; } #invocation-list { - display: flex; - flex-direction: column; - height: 100%; - width: 350px; - box-sizing: border-box; - border: 0; - background-color: #ffffff; + display: flex; + flex-direction: column; + height: 100%; + width: 350px; + box-sizing: border-box; + border: 0; + background-color: #ffffff; } #invocation-content { - display: flex; - flex-direction: column; - width: calc(100% - 350px); - height: 100%; - box-sizing: border-box; - border-left: 1px solid var(--border-color); + display: flex; + flex-direction: column; + width: calc(100% - 350px); + height: 100%; + box-sizing: border-box; + border-left: 1px solid var(--border-color); } #invocation-content .monaco-editor { - display: flex; - height: 100%; - width: 100%; - flex-grow: 1; - min-width: 100%; + display: flex; + height: 100%; + width: 100%; + flex-grow: 1; + min-width: 100%; } .content-placeholder { - display: flex; - color: var(--main-color-light-light); - width: 100%; - height: 100%; - align-items: center; - justify-content: center; - font-size: 18px; + display: flex; + color: var(--main-color-light-light); + width: 100%; + height: 100%; + align-items: center; + justify-content: center; + font-size: 18px; } \ No newline at end of file diff --git a/src/agentscope/studio/static/css/dashboard-detail.css b/src/agentscope/studio/static/css/dashboard-detail.css index 7681cfd14..aa8851c30 100644 --- a/src/agentscope/studio/static/css/dashboard-detail.css +++ b/src/agentscope/studio/static/css/dashboard-detail.css @@ -1,82 +1,82 @@ :root { - --detail-sidebar-padding-vertical: 5px; - --detail-content-width: calc(100% - var(--page-sidebar-width)); + --detail-sidebar-padding-vertical: 5px; + --detail-content-width: calc(100% - var(--page-sidebar-width)); } #detail-body { - display: flex; - flex-direction: row; - height: 100%; - width: 100%; + display: flex; + flex-direction: row; + height: 100%; + width: 100%; } #detail-sidebar { - display: flex; - box-sizing: border-box; - height: 100%; - flex-direction: column; - width: var(--page-sidebar-width); - background-color: #ffffff; + display: flex; + box-sizing: border-box; + height: 100%; + flex-direction: column; + width: var(--page-sidebar-width); + background-color: #ffffff; - border-right-color: var(--border-color); - border-right-width: 1px; - border-right-style: solid; - padding: var(--detail-sidebar-padding-vertical) 0; + border-right-color: var(--border-color); + border-right-width: 1px; + border-right-style: solid; + padding: var(--detail-sidebar-padding-vertical) 0; } .detail-sidebar-tabs { - display: flex; - flex-direction: column; - width: 100%; - height: 100%; - padding: 45px 10px; - box-sizing: border-box; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + padding: 45px 10px; + box-sizing: border-box; } .detail-sidebar-tab { - display: flex; - flex-direction: row; - height: var(--navigation-bar-item-height); - width: 100%; - box-sizing: border-box; - align-items: center; - border-radius: 10px; - padding-left: 20px; - margin: 5px 0; - cursor: pointer; + display: flex; + flex-direction: row; + height: var(--navigation-bar-item-height); + width: 100%; + box-sizing: border-box; + align-items: center; + border-radius: 10px; + padding-left: 20px; + margin: 5px 0; + cursor: pointer; } .detail-sidebar-tab:hover { - background-color: var(--main-color-light); - fill: var(--base-color); - color: var(--base-color); + background-color: var(--main-color-light); + fill: var(--base-color); + color: var(--base-color); } .detail-sidebar-tab:active { - background-color: var(--main-color-dark); - fill: var(--base-color); - color: var(--base-color); + background-color: var(--main-color-dark); + fill: var(--base-color); + color: var(--base-color); } .detail-sidebar-tab.selected { - background-color: var(--main-color); - fill: var(--base-color); - color: var(--base-color); + background-color: var(--main-color); + fill: var(--base-color); + color: var(--base-color); } .detail-sidebar-tab-svg { - display: flex; - width: var(--tab-btn-icon-length); - height: var(--tab-btn-icon-length); - margin-right: 10px; + display: flex; + width: var(--tab-btn-icon-length); + height: var(--tab-btn-icon-length); + margin-right: 10px; } #detail-content { - display: flex; - background-color: #ffffff; - flex-direction: row; - height: 100%; - width: var(--detail-content-width); + display: flex; + background-color: #ffffff; + flex-direction: row; + height: 100%; + width: var(--detail-content-width); } diff --git a/src/agentscope/studio/static/css/dashboard-runs.css b/src/agentscope/studio/static/css/dashboard-runs.css index 73e7712dd..2cc2cd5a7 100644 --- a/src/agentscope/studio/static/css/dashboard-runs.css +++ b/src/agentscope/studio/static/css/dashboard-runs.css @@ -1,72 +1,72 @@ :root { - --runs-content-padding-vertical: 50px; - --runs-content-padding-horizontal: 80px; - --runs-content-control-panel-height: 55px; - --runs-search-input-height: 35px; - --runs-table-height: calc(100% - var(--runs-content-control-panel-height)); + --runs-content-padding-vertical: 50px; + --runs-content-padding-horizontal: 80px; + --runs-content-control-panel-height: 55px; + --runs-search-input-height: 35px; + --runs-table-height: calc(100% - var(--runs-content-control-panel-height)); } #runs-content { - display: flex; - flex-direction: column; - height: 100%; - width: 100%; - padding: var(--runs-content-padding-vertical) var(--runs-content-padding-horizontal); - box-sizing: border-box; + display: flex; + flex-direction: column; + height: 100%; + width: 100%; + padding: var(--runs-content-padding-vertical) var(--runs-content-padding-horizontal); + box-sizing: border-box; } #runs-control-panel { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - height: var(--runs-content-control-panel-height); - width: 100%; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + height: var(--runs-content-control-panel-height); + width: 100%; } #runs-table { - flex-grow: 1; - overflow-y: auto; - width: 100%; - height: var(--runs-table-height); - max-height: var(--runs-table-height); - background-color: #ffffff; - border: 1px solid var(--border-color); + flex-grow: 1; + overflow-y: auto; + width: 100%; + height: var(--runs-table-height); + max-height: var(--runs-table-height); + background-color: #ffffff; + border: 1px solid var(--border-color); } #runs-search-input { - display: flex; - height: var(--runs-search-input-height); - flex-grow: 1; - align-items: center; - border: 1px solid var(--border-color); - padding: 0 10px; + display: flex; + height: var(--runs-search-input-height); + flex-grow: 1; + align-items: center; + border: 1px solid var(--border-color); + padding: 0 10px; } #runs-search-input:focus { - border-color: var(--main-color); - outline: none; /* 移除默认的焦点轮廓样式 */ + border-color: var(--main-color); + outline: none; /* 移除默认的焦点轮廓样式 */ } /* Remove border from tabulator */ .tabulator .tabulator-cell, .tabulator .tabulator-col, .tabulator .tabulator-header .tabulator-col { - border: none !important; + border: none !important; } .tabulator .tabulator-cell { - height: 45px; + height: 45px; } /* Remove the bottom border from table header */ .tabulator .tabulator-header { - border-bottom: none !important; + border-bottom: none !important; } .tabulator-col-sorter-element.tabulator-sortable.tabulator-col { - background-color: var(--main-color-light); - color: var(--main-color-dark); + background-color: var(--main-color-light); + color: var(--main-color-dark); } /* Set the same color for all rows */ @@ -80,45 +80,45 @@ /*}*/ .runs-table-status-tag { - display: flex; - flex-direction: row; - align-items: center; - height: 26px; - width: fit-content; - border-radius: 13px; - color: var(--base-color); - box-sizing: border-box; - margin: 0 5px; - padding: 0 14px; + display: flex; + flex-direction: row; + align-items: center; + height: 26px; + width: fit-content; + border-radius: 13px; + color: var(--base-color); + box-sizing: border-box; + margin: 0 5px; + padding: 0 14px; } .running.runs-table-status-tag { - background-color: #d1e7fa; - color: #58c1ef; - fill: #58c1ef; + background-color: #d1e7fa; + color: #58c1ef; + fill: #58c1ef; } .finished.runs-table-status-tag { - background-color: var(--main-color-light); - color: var(--main-color-dark); - fill: var(--main-color-dark); + background-color: var(--main-color-light); + color: var(--main-color-dark); + fill: var(--main-color-dark); } .waiting.runs-table-status-tag { - background-color: #f8efba; - color: #f6b93b; - fill: #f6b93b; + background-color: #f8efba; + color: #f6b93b; + fill: #f6b93b; } .unknown.runs-table-status-tag { - background-color: #e1e1e1; - color: #3d4047; - fill: #3d4047; + background-color: #e1e1e1; + color: #3d4047; + fill: #3d4047; } .runs-table-status-svg { - display: flex; - width: 15px; - height: 15px; - margin-right: 7px; + display: flex; + width: 15px; + height: 15px; + margin-right: 7px; } diff --git a/src/agentscope/studio/static/css/dashboard.css b/src/agentscope/studio/static/css/dashboard.css index d5e71c3c7..4078883c1 100644 --- a/src/agentscope/studio/static/css/dashboard.css +++ b/src/agentscope/studio/static/css/dashboard.css @@ -1,37 +1,37 @@ #dashboard-panel { - display: flex; - height: 100%; - width: 100%; - flex-direction: column; + display: flex; + height: 100%; + width: 100%; + flex-direction: column; } .dashboard-titlebar-span { - display: flex; - height: 50px; - width: fit-content; - align-items: center; - cursor: pointer; + display: flex; + height: 50px; + width: fit-content; + align-items: center; + cursor: pointer; } .dashboard-subtitlebar-span { - display: flex; - height: 50px; - width: fit-content; - align-items: center; + display: flex; + height: 50px; + width: fit-content; + align-items: center; } .dashboard-titlebar-svg { - display: flex; - width: 15px; - height: 15px; - align-items: center; - justify-content: center; - margin: 0 10px; + display: flex; + width: 15px; + height: 15px; + align-items: center; + justify-content: center; + margin: 0 10px; } #dashboard-content { - display: flex; - height: var(--page-content-height); - width: 100%; - flex-direction: row; + display: flex; + height: var(--page-content-height); + width: 100%; + flex-direction: row; } \ No newline at end of file diff --git a/src/agentscope/studio/static/css/font.css b/src/agentscope/studio/static/css/font.css index 5b151527f..5d87f16ea 100644 --- a/src/agentscope/studio/static/css/font.css +++ b/src/agentscope/studio/static/css/font.css @@ -1,9 +1,9 @@ @font-face { - font-family: 'krypton'; - src: url('/static/fonts/KRYPTON.ttf') format('truetype'); + font-family: 'krypton'; + src: url('/static/fonts/KRYPTON.ttf') format('truetype'); } @font-face { - font-family: 'source-sans'; - src: url('/static/fonts/SourceSans3-Regular.ttf') format('truetype'); + font-family: 'source-sans'; + src: url('/static/fonts/SourceSans3-Regular.ttf') format('truetype'); } \ No newline at end of file diff --git a/src/agentscope/studio/static/css/gallery.css b/src/agentscope/studio/static/css/gallery.css index 5024161e4..8bdc6ccc8 100644 --- a/src/agentscope/studio/static/css/gallery.css +++ b/src/agentscope/studio/static/css/gallery.css @@ -1,88 +1,88 @@ .two-column-layout { - display: flex; - width: 100%; - height: var(--page-content-height); + display: flex; + width: 100%; + height: var(--page-content-height); } .sidebar { - flex-basis: var(--page-sidebar-width); - box-sizing: border-box; - padding: 50px 10px; - border-right: 1px solid var(--border-color); - overflow-y: auto; - width: 100%; + flex-basis: var(--page-sidebar-width); + box-sizing: border-box; + padding: 50px 10px; + border-right: 1px solid var(--border-color); + overflow-y: auto; + width: 100%; } .tabs { - display: block; - padding: 0; - margin: 50px 0 20px 0; + display: block; + padding: 0; + margin: 50px 0 20px 0; } .tab-button { - cursor: pointer; - padding: 10px; - border: none; - margin-right: 20px; - border-radius: 15px; + cursor: pointer; + padding: 10px; + border: none; + margin-right: 20px; + border-radius: 15px; } .tab-button.active { - background-color: var(--main-color-light); + background-color: var(--main-color-light); } .tab { - display: none; + display: none; } .tab.active { - display: block; + display: block; } .grid-container { - grid-template-columns: repeat(6, 1fr); - gap: 1rem; - padding: 1rem; - display: flex; - flex-wrap: wrap; - gap: 1rem; - padding: 1rem; + grid-template-columns: repeat(6, 1fr); + gap: 1rem; + padding: 1rem; + display: flex; + flex-wrap: wrap; + gap: 1rem; + padding: 1rem; } .grid-item { - background-color: #f0f0f0; - border-radius: 4px; - overflow: hidden; - width: 200px; - height: 200px; - position: relative; - display: flex; - flex-direction: column; + background-color: #f0f0f0; + border-radius: 4px; + overflow: hidden; + width: 200px; + height: 200px; + position: relative; + display: flex; + flex-direction: column; } .grid-item :hover { - transform: scale(1.05); + transform: scale(1.05); } .grid-item img { - width: 100%; - height: 61.8%; - object-fit: cover; + width: 100%; + height: 61.8%; + object-fit: cover; } .grid-item .caption { - width: 100%; - height: 38.2%; + width: 100%; + height: 38.2%; } .thumbnail { - width: 100%; - flex-grow: 1; + width: 100%; + flex-grow: 1; } .caption { - text-align: center; + text-align: center; } diff --git a/src/agentscope/studio/static/css/index.css b/src/agentscope/studio/static/css/index.css index 99d227392..0ab164015 100644 --- a/src/agentscope/studio/static/css/index.css +++ b/src/agentscope/studio/static/css/index.css @@ -1,315 +1,315 @@ :root { - --navigation-bar-background-color: #ffffff; - --logo-font-color: #000000; - --tab-font-color: #000000; + --navigation-bar-background-color: #ffffff; + --logo-font-color: #000000; + --tab-font-color: #000000; - --navigation-bar-width: 240px; - --content-width: calc(100% - var(--navigation-bar-width)); + --navigation-bar-width: 240px; + --content-width: calc(100% - var(--navigation-bar-width)); - /*To ensure the collapsed navigation bar fit the icon*/ - --navigation-bar-item-icon-length: var(--tab-btn-icon-length); - --navigation-bar-item-icon-margin: 10px; - --navigation-bar-item-padding: 10px; - --navigation-bar-width-collapsed: calc(var(--navigation-bar-item-icon-length) + 2 * var(--navigation-bar-item-icon-margin) + 2 * var(--navigation-bar-item-padding)); - --navigation-bar-item-height: calc(var(--navigation-bar-item-icon-length) + 2 * var(--navigation-bar-item-icon-margin)) + /*To ensure the collapsed navigation bar fit the icon*/ + --navigation-bar-item-icon-length: var(--tab-btn-icon-length); + --navigation-bar-item-icon-margin: 10px; + --navigation-bar-item-padding: 10px; + --navigation-bar-width-collapsed: calc(var(--navigation-bar-item-icon-length) + 2 * var(--navigation-bar-item-icon-margin) + 2 * var(--navigation-bar-item-padding)); + --navigation-bar-item-height: calc(var(--navigation-bar-item-icon-length) + 2 * var(--navigation-bar-item-icon-margin)) } html { - height: 100%; /* Fill the entire screen height */ - width: 100%; /* Fill the entire screen width */ - margin: 0; /* Eliminate default html margin */ - padding: 0; + height: 100%; /* Fill the entire screen height */ + width: 100%; /* Fill the entire screen width */ + margin: 0; /* Eliminate default html margin */ + padding: 0; } body { - display: flex; /* Allows body to be a flex container */ - height: 100%; /* Fill the entire screen height */ - width: 100%; /* Fill the entire screen width */ - margin: 0; /* Eliminate default body margin */ - flex-direction: row; - padding: 0; - background: var(--body-bg); - font-family: source-sans, sans-serif; - box-sizing: border-box; + display: flex; /* Allows body to be a flex container */ + height: 100%; /* Fill the entire screen height */ + width: 100%; /* Fill the entire screen width */ + margin: 0; /* Eliminate default body margin */ + flex-direction: row; + padding: 0; + background: var(--body-bg); + font-family: source-sans, sans-serif; + box-sizing: border-box; } #workstation-iframe { - display: flex; - width: 100%; - height: 100%; - border: 0; + display: flex; + width: 100%; + height: 100%; + border: 0; } #navigation-bar { - display: flex; - position: relative; - flex-direction: column; - width: var(--navigation-bar-width); - height: 100%; - justify-content: space-between; - align-items: center; - padding: 50px 0 50px 0; - box-sizing: border-box; - background-color: var(--navigation-bar-background-color); - border-right: 1px solid var(--border-color); + display: flex; + position: relative; + flex-direction: column; + width: var(--navigation-bar-width); + height: 100%; + justify-content: space-between; + align-items: center; + padding: 50px 0 50px 0; + box-sizing: border-box; + background-color: var(--navigation-bar-background-color); + border-right: 1px solid var(--border-color); - /*Animation*/ - transition: width 0.5s; + /*Animation*/ + transition: width 0.5s; } #navigation-bar.collapsed { - width: var(--navigation-bar-width-collapsed); + width: var(--navigation-bar-width-collapsed); } .navigation-bar-item-label { - display: flex; - white-space: nowrap; + display: flex; + white-space: nowrap; } #navigation-bar.collapsed .navigation-bar-item-label { - display: none; + display: none; } #content { - display: flex; - box-sizing: border-box; - width: var(--content-width); - height: 100%; - flex-grow: 1; + display: flex; + box-sizing: border-box; + width: var(--content-width); + height: 100%; + flex-grow: 1; } #guide { - display: flex; - flex-direction: column; - width: 100%; - height: 100%; - box-sizing: border-box; - padding: 50px + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + box-sizing: border-box; + padding: 50px } .guide-block { - display: flex; - flex-direction: column; - height: 150px; - width: 500px; - min-width: 200px; - background-color: var(--main-color); - border-radius: 10px; - justify-content: flex-end; - padding: 25px; - color: #ffffff; - cursor: pointer; + display: flex; + flex-direction: column; + height: 150px; + width: 500px; + min-width: 200px; + background-color: var(--main-color); + border-radius: 10px; + justify-content: flex-end; + padding: 25px; + color: #ffffff; + cursor: pointer; } /*when guide-block and right are all in class*/ .guide-block.left { - margin-right: 10px; + margin-right: 10px; } .guide-block.right { - margin-left: 10px; + margin-left: 10px; } .guide-entry { - display: flex; - flex-direction: row; - justify-content: space-around; - width: 100%; - height: fit-content; - margin: 25px 0; + display: flex; + flex-direction: row; + justify-content: space-around; + width: 100%; + height: fit-content; + margin: 25px 0; } .empty.guide-block { - background-color: #ffffff; + background-color: #ffffff; } .guide-block-title { - display: flex; - height: fit-content; - width: 100%; - justify-content: flex-start; - align-items: center; - font-size: 25px; - font-weight: bold; + display: flex; + height: fit-content; + width: 100%; + justify-content: flex-start; + align-items: center; + font-size: 25px; + font-weight: bold; } .guide-block-detail { - display: flex; - height: fit-content; - width: 100%; - justify-content: flex-start; - align-items: center; - font-size: 15px; + display: flex; + height: fit-content; + width: 100%; + justify-content: flex-start; + align-items: center; + font-size: 15px; } #navigation-bar-logo { - font-family: 'krypton', sans-serif; - font-size: 20px; - color: var(--logo-font-color); - white-space: nowrap; + font-family: 'krypton', sans-serif; + font-size: 20px; + color: var(--logo-font-color); + white-space: nowrap; } #navigation-bar.collapsed .navigation-bar-logo-text { - display: none; + display: none; } .navigation-bar-items { - display: flex; - justify-content: center; - flex-grow: 1; /* 使得 .navigation-bar-items 占据可用空间 */ - width: 100%; - flex-direction: column; + display: flex; + justify-content: center; + flex-grow: 1; /* 使得 .navigation-bar-items 占据可用空间 */ + width: 100%; + flex-direction: column; - padding: var(--navigation-bar-item-padding); - box-sizing: border-box; + padding: var(--navigation-bar-item-padding); + box-sizing: border-box; } .navigation-bar-item { - display: flex; - flex-direction: row; - align-items: center; - background-color: var(--navigation-bar-background-color); - width: 100%; - height: var(--navigation-bar-item-height); - border-radius: 10px; - color: var(--tab-font-color); - box-sizing: border-box; - margin: 5px 0; - cursor: pointer; + display: flex; + flex-direction: row; + align-items: center; + background-color: var(--navigation-bar-background-color); + width: 100%; + height: var(--navigation-bar-item-height); + border-radius: 10px; + color: var(--tab-font-color); + box-sizing: border-box; + margin: 5px 0; + cursor: pointer; } .navigation-bar-item:hover { - background-color: var(--main-color-light); - fill: var(--base-color); - color: var(--base-color); + background-color: var(--main-color-light); + fill: var(--base-color); + color: var(--base-color); } .navigation-bar-item:active { - background-color: var(--main-color-dark); - fill: var(--base-color); - color: var(--base-color); + background-color: var(--main-color-dark); + fill: var(--base-color); + color: var(--base-color); } .navigation-bar-item.selected { - background-color: var(--main-color); - fill: var(--base-color); - color: var(--base-color); + background-color: var(--main-color); + fill: var(--base-color); + color: var(--base-color); } .navigation-bar-item-icon { - display: flex; - width: var(--navigation-bar-item-icon-length); - height: var(--navigation-bar-item-icon-length); - margin: 0 var(--navigation-bar-item-icon-margin); - min-height: var(--navigation-bar-item-icon-length); - min-width: var(--navigation-bar-item-icon-length); + display: flex; + width: var(--navigation-bar-item-icon-length); + height: var(--navigation-bar-item-icon-length); + margin: 0 var(--navigation-bar-item-icon-margin); + min-height: var(--navigation-bar-item-icon-length); + min-width: var(--navigation-bar-item-icon-length); } .navigation-bar-hr { - display: flex; - height: 1px; - background-color: var(--border-color); - border: none; - margin: 10px 0; + display: flex; + height: 1px; + background-color: var(--border-color); + border: none; + margin: 10px 0; } .coming-soon-hint { - display: flex; - height: 100%; - width: 100%; - justify-content: center; - align-items: center; - color: var(--main-color-light); + display: flex; + height: 100%; + width: 100%; + justify-content: center; + align-items: center; + color: var(--main-color-light); } .navbar,.navbar ul{ - display: flex; - justify-content: center; - align-items: center; - margin: 0; - padding: 0; + display: flex; + justify-content: center; + align-items: center; + margin: 0; + padding: 0; } .navbar{ - position: absolute; - /* padding: 10px; */ - background-color: #fff; - border-radius: 50px; - background-color: var(--main-color); - top: 90%; - left: 2%; + position: absolute; + /* padding: 10px; */ + background-color: #fff; + border-radius: 50px; + background-color: var(--main-color); + top: 90%; + left: 2%; } .navbar input{ - width: 40px; - height: 40px; - opacity: 0; - cursor: pointer; + width: 40px; + height: 40px; + opacity: 0; + cursor: pointer; } .navbar span{ - position: absolute; - left:11px; - width: 25px; - height: 4px; - top: calc(50% - 10px); - border-radius: 15px; - background-color: #fff; - pointer-events: none; - transition: transform 0.3s ease-in-out,top 0.3s ease-in-out 0.3s; + position: absolute; + left:11px; + width: 25px; + height: 4px; + top: calc(50% - 10px); + border-radius: 15px; + background-color: #fff; + pointer-events: none; + transition: transform 0.3s ease-in-out,top 0.3s ease-in-out 0.3s; } .navbar span:nth-child(3){ - top: calc(50% + 6px); + top: calc(50% + 6px); } .navbar ul{ - width: 0; - overflow: hidden; - transition: all 0.5s; - white-space: nowrap; + width: 0; + overflow: hidden; + transition: all 0.5s; + white-space: nowrap; } .navbar ul li{ - list-style: none; - margin: 0px 15px; + list-style: none; + margin: 0px 15px; } .navbar ul li a{ - text-decoration: none; - font-size: 20px; - font-weight: 700; - color:#fff; + text-decoration: none; + font-size: 20px; + font-weight: 700; + color:#fff; } .navbar ul li a:hover{ - color:#000; + color:#000; } .navbar input:checked ~ ul{ - width: 100px; + width: 100px; } .navbar input:checked ~ span:nth-child(2){ - top: calc(50% - 2px); - transform: rotate(-45deg); - background-color: #fff; - transition: top 0.3s ease-in-out,transform 0.3s ease-in-out 0.3s; + top: calc(50% - 2px); + transform: rotate(-45deg); + background-color: #fff; + transition: top 0.3s ease-in-out,transform 0.3s ease-in-out 0.3s; } .navbar input:checked ~ span:nth-child(3){ - top: calc(50% - 2px); - transform: rotate(45deg); - background-color: #fff; - transition: top 0.3s ease-in-out,transform 0.3s ease-in-out 0.3s; + top: calc(50% - 2px); + transform: rotate(45deg); + background-color: #fff; + transition: top 0.3s ease-in-out,transform 0.3s ease-in-out 0.3s; } .close{ - position: absolute; - display: none; - top: -20%; - left: 70%; - width: 20px; - height: 20px; - border: 1px solid #999; - border-radius: 50%; - justify-content: center; - align-items: end; - background: #999; - color: #fff; - cursor: pointer; + position: absolute; + display: none; + top: -20%; + left: 70%; + width: 20px; + height: 20px; + border: 1px solid #999; + border-radius: 50%; + justify-content: center; + align-items: end; + background: #999; + color: #fff; + cursor: pointer; } .navbar:hover .close{ - display: flex; + display: flex; } .navbar input:checked ~ .close{ - display: none; + display: none; } \ No newline at end of file diff --git a/src/agentscope/studio/static/css/login.css b/src/agentscope/studio/static/css/login.css index 4e5317275..93988b23d 100644 --- a/src/agentscope/studio/static/css/login.css +++ b/src/agentscope/studio/static/css/login.css @@ -1,158 +1,158 @@ body { - font-family: 'Arial', sans-serif; - background-color: #f0f0f0; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - height: 100vh; - margin: 0; + font-family: 'Arial', sans-serif; + background-color: #f0f0f0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; } .login-container { - padding: 2rem; - background: #fff; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); - border-radius: 8px; - text-align: center; - width: 100%; - max-width: 80%; + padding: 2rem; + background: #fff; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + border-radius: 8px; + text-align: center; + width: 100%; + max-width: 80%; } #loginButton { - background-color: #2ea44f; - color: white; - font-size: 18px; - padding: 15px 24px; - border: none; - border-radius: 5px; - cursor: pointer; - box-shadow: 0px 4px 14px -3px rgba(0, 0, 0, 0.4); - transition: background-color 0.3s, transform 0.2s; - margin-top: 1rem; - display: inline-block; - width: 100%; + background-color: #2ea44f; + color: white; + font-size: 18px; + padding: 15px 24px; + border: none; + border-radius: 5px; + cursor: pointer; + box-shadow: 0px 4px 14px -3px rgba(0, 0, 0, 0.4); + transition: background-color 0.3s, transform 0.2s; + margin-top: 1rem; + display: inline-block; + width: 100%; } #loginButton:hover { - background-color: #2c974b; - transform: scale(1.05); + background-color: #2c974b; + transform: scale(1.05); } #loginButton:active { - background-color: #258741; - transform: scale(1); + background-color: #258741; + transform: scale(1); } #loginButton:disabled { - background-color: #94d3a2; - cursor: not-allowed; + background-color: #94d3a2; + cursor: not-allowed; } #loginGuestButton { - color: #a0a0a0; - font-size: 12px; - padding: 5px 8px; - cursor: pointer; - box-shadow: none; - transition: transform 0.2s; - margin-top: 0.5rem; - display: inline-block; - width: auto; - background: none; - border: none; - text-decoration: underline; - opacity: 0.001; + color: #a0a0a0; + font-size: 12px; + padding: 5px 8px; + cursor: pointer; + box-shadow: none; + transition: transform 0.2s; + margin-top: 0.5rem; + display: inline-block; + width: auto; + background: none; + border: none; + text-decoration: underline; + opacity: 0.001; } #loginGuestButton:hover { - transform: scale(1.01); - text-decoration: underline; - cursor: default; + transform: scale(1.01); + text-decoration: underline; + cursor: default; } #loginGuestButton:disabled { - color: #d3d3d3; - text-decoration: none; - transform: none; + color: #d3d3d3; + text-decoration: none; + transform: none; } .terms { - background: #fff; - padding: 20px; - margin: 1rem auto; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.05); - border-radius: 8px; - max-width: 600px; + background: #fff; + padding: 20px; + margin: 1rem auto; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.05); + border-radius: 8px; + max-width: 600px; } .terms ul { - margin-left: 20px; + margin-left: 20px; } .terms li { - margin-bottom: 10px; + margin-bottom: 10px; } .checkbox { - margin-bottom: 1rem; + margin-bottom: 1rem; } .brand-gif { - background: #fff; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - width: 50%; - height: auto; - border-radius: 8px; + background: #fff; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + width: 50%; + height: auto; + border-radius: 8px; } .link-like { - color: #707070; - text-decoration: underline; - cursor: pointer; - opacity: 0.15; + color: #707070; + text-decoration: underline; + cursor: pointer; + opacity: 0.15; } .link-like:hover { - opacity: 1.0; + opacity: 1.0; } .waiting { - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; - background-color: rgba(255, 255, 255, 0.8); - border-radius: 10px; - padding: 20px 40px; - box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25); - flex-direction: column; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + background-color: rgba(255, 255, 255, 0.8); + border-radius: 10px; + padding: 20px 40px; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25); + flex-direction: column; } .css-spinner { - border: 4px solid rgba(0, 0, 0, .1); - border-radius: 50%; - border-top: 4px solid #3498db; - width: 40px; - height: 40px; - animation: spin 2s linear infinite; + border: 4px solid rgba(0, 0, 0, .1); + border-radius: 50%; + border-top: 4px solid #3498db; + width: 40px; + height: 40px; + animation: spin 2s linear infinite; } @keyframes spin { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } } .waiting b { - color: #555; - font-weight: normal; - font-size: 1.5em; + color: #555; + font-weight: normal; + font-size: 1.5em; } diff --git a/src/agentscope/studio/static/css/server.css b/src/agentscope/studio/static/css/server.css index 285e151f2..a916730ad 100644 --- a/src/agentscope/studio/static/css/server.css +++ b/src/agentscope/studio/static/css/server.css @@ -1,132 +1,132 @@ :root { - --server-content-padding-vertical: 20px; - --server-content-padding-horizontal: 30px; - --server-table-height: calc(100% - var(--runs-content-control-panel-height)); + --server-content-padding-vertical: 20px; + --server-content-padding-horizontal: 30px; + --server-table-height: calc(100% - var(--runs-content-control-panel-height)); } #server-panel { - display: flex; - height: 100%; - width: 100%; - flex-direction: column; + display: flex; + height: 100%; + width: 100%; + flex-direction: column; } #server-content { - display: flex; - flex-direction: column; - width: 100%; - padding: var(--server-content-padding-vertical) var(--server-content-padding-horizontal); - box-sizing: border-box; + display: flex; + flex-direction: column; + width: 100%; + padding: var(--server-content-padding-vertical) var(--server-content-padding-horizontal); + box-sizing: border-box; } .collapsed { - display: none; + display: none; } #server-table { - flex-grow: 1; - overflow-y: auto; - max-height: 30vh; - width: 100%; - background-color: #ffffff; - border: 1px solid var(--border-color); + flex-grow: 1; + overflow-y: auto; + max-height: 30vh; + width: 100%; + background-color: #ffffff; + border: 1px solid var(--border-color); } #agent-memory-content { - display: flex; - flex-direction: row; - height: 200px; - width: 100%; - border: 1px solid var(--border-color); + display: flex; + flex-direction: row; + height: 200px; + width: 100%; + border: 1px solid var(--border-color); } #agent-memory-table { - display: flex; - flex-direction: column; - width: 350px; - box-sizing: border-box; - border: 0; - background-color: #ffffff; + display: flex; + flex-direction: column; + width: 350px; + box-sizing: border-box; + border: 0; + background-color: #ffffff; } #agent-memory-raw { - display: flex; - flex-direction: column; - width: calc(100% - 350px); - height: 100%; - box-sizing: border-box; - border-left: 1px solid var(--border-color); + display: flex; + flex-direction: column; + width: calc(100% - 350px); + height: 100%; + box-sizing: border-box; + border-left: 1px solid var(--border-color); } #agent-memory-raw .monaco-editor { - display: flex; - height: 100%; - width: 100%; - min-width: 100%; + display: flex; + height: 100%; + width: 100%; + min-width: 100%; } .server-section-title-bar { - display: flex; - justify-content: flex-start; - font-size: 20px; - padding: 6px 0px; + display: flex; + justify-content: flex-start; + font-size: 20px; + padding: 6px 0px; } .align-right-btn { - margin-left: auto; + margin-left: auto; } #server-content .icon { - display: flex; - height: 20px; - padding: 4px 15px; - cursor: pointer; + display: flex; + height: 20px; + padding: 4px 15px; + cursor: pointer; } #agent-table { - flex-grow: 1; - overflow-y: auto; - max-height: 30vh; - width: 100%; - background-color: #ffffff; - border: 1px solid var(--border-color); + flex-grow: 1; + overflow-y: auto; + max-height: 30vh; + width: 100%; + background-color: #ffffff; + border: 1px solid var(--border-color); } .status-tag { - display: flex; - flex-direction: row; - align-items: center; - height: 26px; - width: fit-content; - border-radius: 13px; - color: var(--base-color); - box-sizing: border-box; - margin: 0 5px; - padding: 0 14px; + display: flex; + flex-direction: row; + align-items: center; + height: 26px; + width: fit-content; + border-radius: 13px; + color: var(--base-color); + box-sizing: border-box; + margin: 0 5px; + padding: 0 14px; } .running.status-tag { - background-color: #ccf4dd; - color: #27ae60; - fill: #27ae60; + background-color: #ccf4dd; + color: #27ae60; + fill: #27ae60; } .dead.status-tag { - background-color: #f5d5d1; - color: #c0392b; - fill: #c0392b; + background-color: #f5d5d1; + color: #c0392b; + fill: #c0392b; } .loading.status-tag { - background-color: #e1e1e1; - color: #3d4047; - fill: #3d4047; + background-color: #e1e1e1; + color: #3d4047; + fill: #3d4047; } .unknown.status-tag { - background-color: #e1e1e1; - color: #3d4047; - fill: #3d4047; + background-color: #e1e1e1; + color: #3d4047; + fill: #3d4047; } \ No newline at end of file diff --git a/src/agentscope/studio/static/css/workstation-drag-components.css b/src/agentscope/studio/static/css/workstation-drag-components.css index 128f39999..2a67c7cf6 100644 --- a/src/agentscope/studio/static/css/workstation-drag-components.css +++ b/src/agentscope/studio/static/css/workstation-drag-components.css @@ -1,165 +1,165 @@ .title-box { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - overflow: hidden; - text-overflow: ellipsis; - width: 100%; - height: 50px; - box-sizing: border-box; - border-radius: 5px; - background: var(--background-box-title); - padding: 0 10px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + overflow: hidden; + text-overflow: ellipsis; + width: 100%; + height: 50px; + box-sizing: border-box; + border-radius: 5px; + background: var(--background-box-title); + padding: 0 10px; } .drawflow-node.selected .title-box { - background-color: #ffffff; + background-color: #ffffff; } .title-box-left-items { - display: flex; - flex-direction: row; - align-items: center; - overflow-x: auto; - height: 100%; + display: flex; + flex-direction: row; + align-items: center; + overflow-x: auto; + height: 100%; } .title-box-svg { - display: flex; - align-items: center; - justify-content: center; - height: 25px; - width: 25px; - background-color: var(--main-color); - border-radius: 5px; - fill: #ffffff; - margin-right: 8px; + display: flex; + align-items: center; + justify-content: center; + height: 25px; + width: 25px; + background-color: var(--main-color); + border-radius: 5px; + fill: #ffffff; + margin-right: 8px; } /*TODO: 没有生效*/ .drawflow-node.selected input, .drawflow-node.selected textarea { - border: 1px solid var(--main-color-light); + border: 1px solid var(--main-color-light); } .drawflow-node.selected input:focus, .drawflow-node.selected textarea:focus { - outline: 1px solid var(--main-color); + outline: 1px solid var(--main-color); } .drawflow-node .input:hover { - background: #43b993; + background: #43b993; } .drawflow-node .output:hover { - background: #43b993; + background: #43b993; } .drawflow > .drawflow-delete { - border: 2px solid #43b993; - background: white; - color: #43b993; - -webkit-box-shadow: 0 2px 20px 2px #43b993; - box-shadow: 0 2px 20px 2px #43b993; + border: 2px solid #43b993; + background: white; + color: #43b993; + -webkit-box-shadow: 0 2px 20px 2px #43b993; + box-shadow: 0 2px 20px 2px #43b993; } .toggle-arrow { - display: flex; - height: 10px; - width: 10px; - margin-right: 5px; - transform: translateY(-50%); - cursor: pointer; - box-sizing: border-box; + display: flex; + height: 10px; + width: 10px; + margin-right: 5px; + transform: translateY(-50%); + cursor: pointer; + box-sizing: border-box; } .box { - display: flex; - flex-direction: column; - font-size: 14px; - margin-top: 10px; - height: fit-content; + display: flex; + flex-direction: column; + font-size: 14px; + margin-top: 10px; + height: fit-content; } .box.hidden { - display: none; + display: none; } .hidden { - display: none; + display: none; } .box input, .box select, .box textarea { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - box-sizing: border-box; - width: 100%; - height: 40px; - min-height: 40px; - padding: 0 10px; - border: 1px solid var(--border-color); - border-radius: 5px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + box-sizing: border-box; + width: 100%; + height: 40px; + min-height: 40px; + padding: 0 10px; + border: 1px solid var(--border-color); + border-radius: 5px; } .box label { - display: flex; - flex-direction: row; - align-items: center; - margin-top: 5px; - margin-bottom: 5px; + display: flex; + flex-direction: row; + align-items: center; + margin-top: 5px; + margin-bottom: 5px; } .box a { - target: "_blank"; + target: '_blank'; } .readme { - display: flex; - flex-direction: column; - background-color: #ADD8E6; - font-size: 14px; - border: 1px solid #ddd; - border-radius: 5px; - width: 100%; - height: fit-content; - box-sizing: border-box; - padding: 10px; + display: flex; + flex-direction: column; + background-color: #ADD8E6; + font-size: 14px; + border: 1px solid #ddd; + border-radius: 5px; + width: 100%; + height: fit-content; + box-sizing: border-box; + padding: 10px; } .drawflow-node .box-highlight { - padding: 10px 20px 20px 20px; - color: #555555; - font-size: 16px; - background-color: rgba(173, 216, 230, 0.5); - overflow: auto; + padding: 10px 20px 20px 20px; + color: #555555; + font-size: 16px; + background-color: rgba(173, 216, 230, 0.5); + overflow: auto; } .drawflow-node.welcome { - width: 250px; - min-width: 250px; + width: 250px; + min-width: 250px; } .drawflow .connection .point { - stroke: var(--border-color); - stroke-width: 2; - fill: white; + stroke: var(--border-color); + stroke-width: 2; + fill: white; } .drawflow .connection .point.selected, .drawflow .connection .point:hover { - fill: #4ea9ff; + fill: #4ea9ff; } .drawflow .drawflow-node.GROUP { - width: 500px; - z-index: 0; + width: 500px; + z-index: 0; } .placeholder { - height: 300px; - z-index: 0; + height: 300px; + z-index: 0; } .drawflow .drawflow-node.GROUP.hover-drop { - background: hsl(225, 100%, 96%); + background: hsl(225, 100%, 96%); } \ No newline at end of file diff --git a/src/agentscope/studio/static/css/workstation.css b/src/agentscope/studio/static/css/workstation.css index ab1ca0cb7..32cc47c2f 100644 --- a/src/agentscope/studio/static/css/workstation.css +++ b/src/agentscope/studio/static/css/workstation.css @@ -1,1162 +1,1162 @@ :root { - --background-color: #ffffff; - --background-box-title: #f7f7f7; - --scale-factor: 2; + --background-color: #ffffff; + --background-box-title: #f7f7f7; + --scale-factor: 2; - --menu-height: 48px; - --menu-btn-height: 35px; - --menu-btn-width: 50px; + --menu-height: 48px; + --menu-btn-height: 35px; + --menu-btn-width: 50px; - --drawflow-height: calc(100% - var(--menu-height)); + --drawflow-height: calc(100% - var(--menu-height)); - --workstation-sidebar-item-font-size: 18px; - --workstation-sidebar-subitem-font-size: 15px; + --workstation-sidebar-item-font-size: 18px; + --workstation-sidebar-subitem-font-size: 15px; - --logo-font-color: #000000; + --logo-font-color: #000000; } html { - height: 100%; /* Fill the entire screen height */ - width: 100%; /* Fill the entire screen width */ - margin: 0; /* Eliminate default html margin */ - padding: 0; + height: 100%; /* Fill the entire screen height */ + width: 100%; /* Fill the entire screen width */ + margin: 0; /* Eliminate default html margin */ + padding: 0; } body { - display: flex; /* Allows body to be a flex container */ - height: 100%; /* Fill the entire screen height */ - width: 100%; /* Fill the entire screen width */ - margin: 0; /* Eliminate default body margin */ - flex-direction: row; - padding: 0; - background: var(--body-bg); - font-family: sans-serif; - box-sizing: border-box; + display: flex; /* Allows body to be a flex container */ + height: 100%; /* Fill the entire screen height */ + width: 100%; /* Fill the entire screen width */ + margin: 0; /* Eliminate default body margin */ + flex-direction: row; + padding: 0; + background: var(--body-bg); + font-family: sans-serif; + box-sizing: border-box; } #workstation-panel { - display: flex; - height: 100%; - width: 100%; - flex-direction: column; + display: flex; + height: 100%; + width: 100%; + flex-direction: column; } .them-edit-link { - position: absolute; - top: 10px; - right: 100px; - color: black; - font-size: 40px; + position: absolute; + top: 10px; + right: 100px; + color: black; + font-size: 40px; } .them-edit-link a { - text-decoration: none; + text-decoration: none; } .wrapper { - display: flex; - flex-direction: row; - width: 100%; - box-sizing: border-box; - height: var(--page-content-height); + display: flex; + flex-direction: row; + width: 100%; + box-sizing: border-box; + height: var(--page-content-height); } .col { - display: flex; - flex-direction: column; - width: var(--page-sidebar-width); - min-width: var(--page-sidebar-width); - max-width: var(--page-sidebar-width); - box-sizing: border-box; - height: 100%; - border-right: 1px solid var(--border-color); - padding: 50px 10px; - overflow-y: auto; + display: flex; + flex-direction: column; + width: var(--page-sidebar-width); + min-width: var(--page-sidebar-width); + max-width: var(--page-sidebar-width); + box-sizing: border-box; + height: 100%; + border-right: 1px solid var(--border-color); + padding: 50px 10px; + overflow-y: auto; } .col ul { - margin: 0; + margin: 0; } .col ul { - padding-left: 0; + padding-left: 0; } .col ul, li { - list-style-type: none; + list-style-type: none; } .col-right { - display: flex; - flex-direction: column; - width: calc(100% - var(--page-sidebar-width)); - height: 100%; + display: flex; + flex-direction: column; + width: calc(100% - var(--page-sidebar-width)); + height: 100%; } .menu { - display: flex; - flex-direction: row; - height: var(--menu-height); - width: 100%; - box-sizing: border-box; - align-items: center; + display: flex; + flex-direction: row; + height: var(--menu-height); + width: 100%; + box-sizing: border-box; + align-items: center; } .menu-btn { - display: flex; - height: var(--menu-btn-height); - width: var(--menu-btn-width); - white-space: nowrap; - align-items: center; - justify-content: center; - background-color: var(--main-color-light); - border-radius: 10px; - margin: 0 5px; - cursor: pointer; - position: relative; - position: relative; + display: flex; + height: var(--menu-btn-height); + width: var(--menu-btn-width); + white-space: nowrap; + align-items: center; + justify-content: center; + background-color: var(--main-color-light); + border-radius: 10px; + margin: 0 5px; + cursor: pointer; + position: relative; + position: relative; } .menu-btn:hover { - background-color: var(--main-color); - fill: #ffffff; + background-color: var(--main-color); + fill: #ffffff; } .menu-btn:active { - background-color: var(--main-color-dark); - fill: #ffffff; + background-color: var(--main-color-dark); + fill: #ffffff; } .menu-btn-svg { - display: flex; - width: 20px; - height: 20px; + display: flex; + width: 20px; + height: 20px; } .menu-btn:hover .tooltip { - display: flex; - flex-direction: column; - align-items: center; - height: fit-content; - width: fit-content; - padding: 10px; - background-color: var(--main-color-light); + display: flex; + flex-direction: column; + align-items: center; + height: fit-content; + width: fit-content; + padding: 10px; + background-color: var(--main-color-light); } .btn-cover { - position: relative; - cursor: not-allowed; - background: transparent; - z-index: 15000; - margin-left: 10px; + position: relative; + cursor: not-allowed; + background: transparent; + z-index: 15000; + margin-left: 10px; } .btn-cover::after { - content: attr(data-title); - pointer-events: none; - visibility: hidden; - opacity: 0; - transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out; - - position: absolute; - left: 50%; - top: 100%; - transform: translateX(-50%); - white-space: normal; - max-width: 200px; - text-align: center; - word-wrap: break-word; - background-color: #000; - color: #fff; - padding: 1px 1px; - border-radius: 3px; - font-size: 0.75rem; - z-index: 15000; - - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); - margin-top: 8px; - min-width: 100px; + content: attr(data-title); + pointer-events: none; + visibility: hidden; + opacity: 0; + transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out; + + position: absolute; + left: 50%; + top: 100%; + transform: translateX(-50%); + white-space: normal; + max-width: 200px; + text-align: center; + word-wrap: break-word; + background-color: #000; + color: #fff; + padding: 1px 1px; + border-radius: 3px; + font-size: 0.75rem; + z-index: 15000; + + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + margin-top: 8px; + min-width: 100px; } .btn-cover[data-title]:hover::after { - visibility: visible; - opacity: 1; - min-width: 100px; + visibility: visible; + opacity: 1; + min-width: 100px; } .btn-cover:hover + .btn-disabled:hover::after { - visibility: visible; - opacity: 1; + visibility: visible; + opacity: 1; } .btn-disabled { - pointer-events: none; - opacity: 0.6; - background-color: #ccc; - color: #666; - border: 1px solid #999; + pointer-events: none; + opacity: 0.6; + background-color: #ccc; + color: #666; + border: 1px solid #999; } .btn-enabled + .btn-cover { - display: block; + display: block; } .swal-wide { - width: 80% !important; + width: 80% !important; } .control-bar { - display: flex; - flex-direction: row; - float: right; - position: absolute; - bottom: 10px; - right: 10px; - padding: 5px 10px; + display: flex; + flex-direction: row; + float: right; + position: absolute; + bottom: 10px; + right: 10px; + padding: 5px 10px; } .lock-btn { - display: flex; - align-items: center; - justify-content: center; - padding: 5px; - background: #555555; - border-radius: 4px; - z-index: 10000; - margin-right: 10px; - height: fit-content; - width: fit-content; + display: flex; + align-items: center; + justify-content: center; + padding: 5px; + background: #555555; + border-radius: 4px; + z-index: 10000; + margin-right: 10px; + height: fit-content; + width: fit-content; } .zoom-bar { - display: flex; - float: right; - bottom: 10px; - right: 10px; - padding: 5px 10px; - background: #555555; - border-radius: 4px; - z-index: 10000; + display: flex; + float: right; + bottom: 10px; + right: 10px; + padding: 5px 10px; + background: #555555; + border-radius: 4px; + z-index: 10000; } .control-bar svg { - display: flex; - height: 25px; - width: 25px; - justify-content: center; - align-items: center; - fill: white; - margin: 5px; + display: flex; + height: 25px; + width: 25px; + justify-content: center; + align-items: center; + fill: white; + margin: 5px; } .zoom-bar svg:nth-child(1) { - padding-left: 0px; + padding-left: 0px; } #drawflow { - display: flex; - width: 100%; - height: var(--drawflow-height); - top: 40px; - background: var(--background-color); - background-size: 25px 25px; - background-image: linear-gradient(to right, #f1f1f1 1px, transparent 1px), + display: flex; + width: 100%; + height: var(--drawflow-height); + top: 40px; + background: var(--background-color); + background-size: 25px 25px; + background-image: linear-gradient(to right, #f1f1f1 1px, transparent 1px), linear-gradient(to bottom, #f1f1f1 1px, transparent 1px); } @media only screen and (max-width: 768px) { - .col { - width: 50px; - } + .col { + width: 50px; + } - .col .workstation-sidebar-dragitem span { - display: none; - } + .col .workstation-sidebar-dragitem span { + display: none; + } - #drawflow { - width: calc(100vw - 51px); - } + #drawflow { + width: calc(100vw - 51px); + } } /* Modal */ .modal { - display: none; - position: fixed; - z-index: 10000; - left: 0; - top: 0; - width: 100vw; - height: 100vh; - overflow: auto; - background-color: rgb(0, 0, 0); - background-color: rgba(0, 0, 0, 0.7); + display: none; + position: fixed; + z-index: 10000; + left: 0; + top: 0; + width: 100vw; + height: 100vh; + overflow: auto; + background-color: rgb(0, 0, 0); + background-color: rgba(0, 0, 0, 0.7); } .modal-content { - position: relative; - background-color: #fefefe; - margin: 15% auto; - padding: 20px; - border: 1px solid #888; - width: 400px; + position: relative; + background-color: #fefefe; + margin: 15% auto; + padding: 20px; + border: 1px solid #888; + width: 400px; } .modal .close { - color: #aaa; - float: right; - font-size: 28px; - font-weight: bold; - cursor: pointer; + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; + cursor: pointer; } @media only screen and (max-width: 768px) { - .modal-content { - width: 80%; - } + .modal-content { + width: 80%; + } } .workstation-sidebar-item { - display: flex; - flex-direction: column; - justify-content: center; - cursor: pointer; - font-size: var(--workstation-sidebar-item-font-size); - font-weight: bold; - box-sizing: border-box; - width: 100%; - height: 45px; - border-radius: 10px; - padding: 0 10px; + display: flex; + flex-direction: column; + justify-content: center; + cursor: pointer; + font-size: var(--workstation-sidebar-item-font-size); + font-weight: bold; + box-sizing: border-box; + width: 100%; + height: 45px; + border-radius: 10px; + padding: 0 10px; } .workstation-sidebar-subitem { - display: flex; - flex-direction: row; - align-items: center; - cursor: pointer; - font-size: var(--workstation-sidebar-subitem-font-size); - box-sizing: border-box; - width: 100%; - height: 40px; - border-radius: 10px; - padding: 0 10px; - font-weight: bold; - color: #808080; + display: flex; + flex-direction: row; + align-items: center; + cursor: pointer; + font-size: var(--workstation-sidebar-subitem-font-size); + box-sizing: border-box; + width: 100%; + height: 40px; + border-radius: 10px; + padding: 0 10px; + font-weight: bold; + color: #808080; } .workstation-sidebar-subitem:hover { - background-color: var(--main-color-light); - color: #ffffff; + background-color: var(--main-color-light); + color: #ffffff; } .workstation-sidebar-placeholder { - display: flex; - height: 20px; - width: 100%; + display: flex; + height: 20px; + width: 100%; } .workstation-sidebar-sub-content { - display: none; + display: none; } .active + .workstation-sidebar-sub-content { - display: block; + display: block; } .workstation-sidebar-dragitem { - display: flex; - flex-direction: column; - justify-content: center; - font-size: var(--workstation-sidebar-subitem-font-size); - box-sizing: border-box; - width: calc(100% - 10px); - cursor: move; - height: 40px; - border-radius: 10px; - padding: 0 10px; - margin-left: 10px; + display: flex; + flex-direction: column; + justify-content: center; + font-size: var(--workstation-sidebar-subitem-font-size); + box-sizing: border-box; + width: calc(100% - 10px); + cursor: move; + height: 40px; + border-radius: 10px; + padding: 0 10px; + margin-left: 10px; } .workstation-sidebar-dragitem:hover { - background-color: var(--main-color-light); - color: #ffffff; + background-color: var(--main-color-light); + color: #ffffff; } .workstation-sidebar-subitem-arrow { - display: flex; - height: 10px; - width: 10px; - align-items: center; - justify-content: center; - fill: #000; - margin-right: 5px; + display: flex; + height: 10px; + width: 10px; + align-items: center; + justify-content: center; + fill: #000; + margin-right: 5px; } .highlighted-tab { - cursor: pointer; - color: #ffffff; - background-color: rgba(255, 167, 38, 0.8); - user-select: none; - transition: background-color 0.3s ease; - text-align: center; + cursor: pointer; + color: #ffffff; + background-color: rgba(255, 167, 38, 0.8); + user-select: none; + transition: background-color 0.3s ease; + text-align: center; } .highlighted-tab:hover { - background-color: rgba(251, 140, 0, 0.9); + background-color: rgba(251, 140, 0, 0.9); } .toggle-sub-title { - cursor: pointer; - background-color: var(--main-color-light); - padding: 10px; - margin-top: 0; - margin-bottom: 0; - user-select: none; - transition: background-color 0.3s ease; - text-align: center; - border-radius: 10px; - flex-grow: 1; + cursor: pointer; + background-color: var(--main-color-light); + padding: 10px; + margin-top: 0; + margin-bottom: 0; + user-select: none; + transition: background-color 0.3s ease; + text-align: center; + border-radius: 10px; + flex-grow: 1; } .toggle-sub-title:hover { - background-color: #e2e2e2; + background-color: #e2e2e2; } .draggable-content { - display: flex; - flex-direction: column; - max-height: 0; - opacity: 0; - overflow: auto; - transition: max-height 0.3s ease, opacity 0.3s ease, padding 0.3s ease, margin 0.3s ease; + display: flex; + flex-direction: column; + max-height: 0; + opacity: 0; + overflow: auto; + transition: max-height 0.3s ease, opacity 0.3s ease, padding 0.3s ease, margin 0.3s ease; } .draggable-content.visible { - margin-top: 5px; - padding: 10px; - height: fit-content; - opacity: 1; + margin-top: 5px; + padding: 10px; + height: fit-content; + opacity: 1; } -pre[class*="language-"] { - font-size: 0.5em; - max-height: 60vh; - overflow: auto; - margin: 1rem 0; +pre[class*='language-'] { + font-size: 0.5em; + max-height: 60vh; + overflow: auto; + margin: 1rem 0; } .swal2-title { - font-size: 20px; + font-size: 20px; } .resize-handle-se { - position: absolute; - width: 18px; - height: 18px; - bottom: 0; - fill: var(--border-color); - right: 0; - cursor: nwse-resize; - z-index: 10; + position: absolute; + width: 18px; + height: 18px; + bottom: 0; + fill: var(--border-color); + right: 0; + cursor: nwse-resize; + z-index: 10; } .drawflow .drawflow-node.selected .resize-handle-se { - fill: var(--main-color-light); + fill: var(--main-color-light); } .if-placeholder, .else-placeholder { - border: 1px dashed #ccc; - height: 30%; - margin: 5px; + border: 1px dashed #ccc; + height: 30%; + margin: 5px; } .cases-container { - margin-top: 10px; - min-height: 50px; + margin-top: 10px; + min-height: 50px; } .case-placeholder { - border: 1px dashed #ccc; - height: 100px; - padding: 5px; - margin-bottom: 5px; + border: 1px dashed #ccc; + height: 100px; + padding: 5px; + margin-bottom: 5px; } .case-placeholder:last-child { - height: 100px; - border-bottom: 1px dashed #ccc; + height: 100px; + border-bottom: 1px dashed #ccc; } .button { - display: inline-block; - padding: 6px 12px; - margin: 5px; - font-size: 10px; - font-weight: bold; - color: #ffffff; - background-image: linear-gradient(to right, #6e48aa, #9d50bb); - border: 2px solid transparent; - border-radius: 30px; - cursor: pointer; - text-align: center; - text-decoration: none; - transition: all 0.3s ease; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + display: inline-block; + padding: 6px 12px; + margin: 5px; + font-size: 10px; + font-weight: bold; + color: #ffffff; + background-image: linear-gradient(to right, #6e48aa, #9d50bb); + border: 2px solid transparent; + border-radius: 30px; + cursor: pointer; + text-align: center; + text-decoration: none; + transition: all 0.3s ease; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } .button:hover { - background-image: linear-gradient(to left, #6e48aa, #9d50bb); - box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2); - transform: translateY(-2px); + background-image: linear-gradient(to left, #6e48aa, #9d50bb); + box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2); + transform: translateY(-2px); } .add-case { - background-image: linear-gradient(to right, #56ab2f, #a8e063); + background-image: linear-gradient(to right, #56ab2f, #a8e063); } .remove-case { - background-image: linear-gradient(to right, #f85032, #e73827); + background-image: linear-gradient(to right, #f85032, #e73827); } .button:disabled, .button:disabled:hover, .button:disabled:active { - background-color: #cccccc; - color: #666666; - cursor: not-allowed; - box-shadow: none; - border: 2px solid #cccccc; + background-color: #cccccc; + color: #666666; + cursor: not-allowed; + box-shadow: none; + border: 2px solid #cccccc; } .code-snippet { - display: inline; - margin-bottom: 4px; - line-height: 1.4; - padding: 2px 4px; - background-color: #f0f0f0; - font-family: 'Courier New', monospace; - border-radius: 3px; - border: 1px solid #eee; - color: #d63384; + display: inline; + margin-bottom: 4px; + line-height: 1.4; + padding: 2px 4px; + background-color: #f0f0f0; + font-family: 'Courier New', monospace; + border-radius: 3px; + border: 1px solid #eee; + color: #d63384; } .iframe-container { - display: none; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 20000; - background: rgba(0, 0, 0, 0.5); - justify-content: center; - align-items: center; + display: none; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 20000; + background: rgba(0, 0, 0, 0.5); + justify-content: center; + align-items: center; } .copilot-iframe { - width: 100%; - height: 100%; - border: 1px solid #ddd; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - transition: all 0.3s; - background: #ffffff; - border-radius: 10px; + width: 100%; + height: 100%; + border: 1px solid #ddd; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + transition: all 0.3s; + background: #ffffff; + border-radius: 10px; } #close-iframe { - position: absolute; - top: 10px; - right: 10px; - padding: 5px 10px; - border: none; - background: rgba(0, 123, 255, 0.4); - color: white; - cursor: pointer; - border-radius: 0 0 0 5px; - font-size: 16px; - z-index: 10000; + position: absolute; + top: 10px; + right: 10px; + padding: 5px 10px; + border: none; + background: rgba(0, 123, 255, 0.4); + color: white; + cursor: pointer; + border-radius: 0 0 0 5px; + font-size: 16px; + z-index: 10000; } #iframe-wrapper { - position: relative; - width: 90%; - height: 90%; + position: relative; + width: 90%; + height: 90%; } #close-iframe .fas { - pointer-events: none; + pointer-events: none; } .tools-placeholder { - border: 2px dashed #ccc; - padding: 30px; - text-align: center; - margin-top: 10px; - color: #888; + border: 2px dashed #ccc; + padding: 30px; + text-align: center; + margin-top: 10px; + color: #888; } .swal2-container { - z-index: 20000 !important; + z-index: 20000 !important; } .modules-info { - background-color: rgba(128, 128, 128, 0.2); - padding: 2px; - margin-bottom: 10px; + background-color: rgba(128, 128, 128, 0.2); + padding: 2px; + margin-bottom: 10px; } .modules-info h4 { - margin: 0 0 10px 0; - font-size: 18px; - color: #444; + margin: 0 0 10px 0; + font-size: 18px; + color: #444; } .modules-info ul { - margin: 0; - padding: 0 0 0 20px; + margin: 0; + padding: 0 0 0 20px; } .modules-info li { - font-size: 14px; - color: #555; - margin-bottom: 10px; + font-size: 14px; + color: #555; + margin-bottom: 10px; } .highlight-module { - font-weight: bold; - color: #2a6496; - cursor: pointer; + font-weight: bold; + color: #2a6496; + cursor: pointer; } .highlight-module:hover { - text-decoration: underline; - color: #1d5b8f; + text-decoration: underline; + color: #1d5b8f; } .advanced-title-box { - cursor: pointer; - color: #333; - margin-top: 20px; + cursor: pointer; + color: #333; + margin-top: 20px; } .advanced-box { - margin: 10px 0; + margin: 10px 0; } .swal2-textarea { - height: 400px; - font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace; /* 设置等宽字体 */ + height: 400px; + font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace; /* 设置等宽字体 */ } .swal2-textarea.code { - padding: 15px; - background-color: #f5f5f5; - border: 1px solid #eee; - box-shadow: inset 0 1px 8px rgba(0, 0, 0, .1); - border-radius: 4px; + padding: 15px; + background-color: #f5f5f5; + border: 1px solid #eee; + box-shadow: inset 0 1px 8px rgba(0, 0, 0, .1); + border-radius: 4px; } .example-wrapper { - display: flex; - align-items: center; - justify-content: space-between; + display: flex; + align-items: center; + justify-content: space-between; } .new-action { - cursor: pointer; - padding: 8px; - margin-left: auto; - border: none; - border-radius: 20px; - background-color: var(--main-color); - color: white; - transition: all 0.3s ease; - font-size: 14px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - max-width: 30px; - overflow: hidden; - white-space: nowrap; - display: flex; - justify-content: center; - align-items: center; + cursor: pointer; + padding: 8px; + margin-left: auto; + border: none; + border-radius: 20px; + background-color: var(--main-color); + color: white; + transition: all 0.3s ease; + font-size: 14px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + max-width: 30px; + overflow: hidden; + white-space: nowrap; + display: flex; + justify-content: center; + align-items: center; } .new-action:hover, .new-action:focus { - width: auto; - padding: 8px 16px; - background-color: var(--main-color); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); + width: auto; + padding: 8px 16px; + background-color: var(--main-color); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); } .new-action:active { - background-color: var(--main-color); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); + background-color: var(--main-color); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); } #import-buttons { - display: flex; - flex-direction: column; - align-items: center; - position: absolute; - top: 30%; - right: 50px; - z-index: 10; - padding: 5px; - border-radius: 10px; - background-color: #ffffff; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - font-family: 'Poppins', sans-serif; - transition: all 0.3s ease; + display: flex; + flex-direction: column; + align-items: center; + position: absolute; + top: 30%; + right: 50px; + z-index: 10; + padding: 5px; + border-radius: 10px; + background-color: #ffffff; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + font-family: 'Poppins', sans-serif; + transition: all 0.3s ease; } #import-buttons:hover { - box-shadow: 5px 5px 20px rgba(0, 0, 0, 0.25); - transform: translateY(-2px); + box-shadow: 5px 5px 20px rgba(0, 0, 0, 0.25); + transform: translateY(-2px); } #step-info { - margin-bottom: 10px; - padding: 10px; - border-radius: 4px; - text-align: center; - width: 150px; - font-family: 'Poppins', sans-serif; - font-size: 14px; - font-weight: 500; - letter-spacing: 0.05em; - line-height: 1.6; - color: #333; - background-color: rgba(173, 216, 230, 0.5); - box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.1); - cursor: pointer; + margin-bottom: 10px; + padding: 10px; + border-radius: 4px; + text-align: center; + width: 150px; + font-family: 'Poppins', sans-serif; + font-size: 14px; + font-weight: 500; + letter-spacing: 0.05em; + line-height: 1.6; + color: #333; + background-color: rgba(173, 216, 230, 0.5); + box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.1); + cursor: pointer; } #step-warning { - position: absolute; - top: 8%; - right: 25.5%; - padding: 10px; - text-align: center; - /*font-family: 'Poppins', sans-serif;*/ - font-size: 14px; - letter-spacing: 0.05em; - line-height: 1.6; - color: #333; - margin: 10px; - border-radius: 5px; - border: 1px solid #ffcc00; - background-color: rgba(255, 255, 0, 0.15); - box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.1); - cursor: pointer; + position: absolute; + top: 8%; + right: 25.5%; + padding: 10px; + text-align: center; + /*font-family: 'Poppins', sans-serif;*/ + font-size: 14px; + letter-spacing: 0.05em; + line-height: 1.6; + color: #333; + margin: 10px; + border-radius: 5px; + border: 1px solid #ffcc00; + background-color: rgba(255, 255, 0, 0.15); + box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.1); + cursor: pointer; } #step-info:hover, #step-warning:hover { - box-shadow: 5px 5px 20px rgba(0, 0, 0, 0.25); - transform: translateY(-2px); + box-shadow: 5px 5px 20px rgba(0, 0, 0, 0.25); + transform: translateY(-2px); } #import-prev, #import-next, #import-skip, #import-quit { - padding: 8px 12px; - margin: 4px; - border: none; - border-radius: 4px; - background-color: var(--main-color); - color: white; - cursor: pointer; - font-size: 16px; + padding: 8px 12px; + margin: 4px; + border: none; + border-radius: 4px; + background-color: var(--main-color); + color: white; + cursor: pointer; + font-size: 16px; } #import-prev:hover, #import-next:hover, #import-skip:hover, #import-quit:hover { - background-color: var(--main-color); - transform: translateY(-2px); + background-color: var(--main-color); + transform: translateY(-2px); } #import-prev i, #import-next i, #import-skip i, #import-quit i { - margin-right: 5px; + margin-right: 5px; } #import-next:disabled, #import-prev:disabled, #import-skip:disabled { - background-color: #ccc; - cursor: not-allowed; + background-color: #ccc; + cursor: not-allowed; } #surveyModal { - display: none; - position: fixed; - bottom: 60px; - right: 20px; - background-color: white; - box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); - z-index: 1000; - border-radius: 10px; - overflow: hidden; - animation: fadeIn 0.3s; + display: none; + position: fixed; + bottom: 60px; + right: 20px; + background-color: white; + box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); + z-index: 1000; + border-radius: 10px; + overflow: hidden; + animation: fadeIn 0.3s; } #surveyContent { - position: relative; - padding: 20px; - text-align: center; + position: relative; + padding: 20px; + text-align: center; } #surveyButton { - padding: 10px 20px; - background-color: #2ea44f; - color: white; - border: none; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.3s, transform 0.2s; + padding: 10px 20px; + background-color: #2ea44f; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.3s, transform 0.2s; } #surveyButton:hover { - background-color: #258741; - transform: scale(1.05); + background-color: #258741; + transform: scale(1.05); } #surveyClose { - position: absolute; - top: 10px; - right: 15px; - color: #aaaaaa; - font-size: 25px; - cursor: pointer; + position: absolute; + top: 10px; + right: 15px; + color: #aaaaaa; + font-size: 25px; + cursor: pointer; } #surveyClose:hover { - color: #777; + color: #777; } @keyframes fadeIn { - from { - opacity: 0; - } - to { - opacity: 1; - } + from { + opacity: 0; + } + to { + opacity: 1; + } } .text-input { - font-family: Arial, sans-serif; - font-size: 16px; - line-height: 1.2; - resize: vertical; + font-family: Arial, sans-serif; + font-size: 16px; + line-height: 1.2; + resize: vertical; } .tour-guide { - display: none; - z-index: 3; + display: none; + z-index: 3; } .tour-step { - position: relative; - display: flex; - flex-direction: column; - align-items: center; - padding: 10px; - border: 1px solid #ccc; - border-radius: 5px; - background-color: #fff; + position: relative; + display: flex; + flex-direction: column; + align-items: center; + padding: 10px; + border: 1px solid #ccc; + border-radius: 5px; + background-color: #fff; } .tour-arrow { - position: absolute; - top: 50%; - left: -10px; - width: 0; - height: 0; - border-style: solid; - border-width: 10px 10px 10px 0; - border-color: transparent #ccc transparent transparent; - transform: translateY(-50%); + position: absolute; + top: 50%; + left: -10px; + width: 0; + height: 0; + border-style: solid; + border-width: 10px 10px 10px 0; + border-color: transparent #ccc transparent transparent; + transform: translateY(-50%); } .tour-content { - display: flex; - flex-direction: column; - align-items: center; - border-radius: 5px; - background-color: #fff; + display: flex; + flex-direction: column; + align-items: center; + border-radius: 5px; + background-color: #fff; } .overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - display: flex; - justify-content: center; - align-items: center; - z-index: 1; - display: none; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1; + display: none; } .guide-Example { - background: #fff; - height: fit-content; - border-radius: 4px; - border: 1px solid #fff; - color: #000; - z-index: 2; + background: #fff; + height: fit-content; + border-radius: 4px; + border: 1px solid #fff; + color: #000; + z-index: 2; } .guide-skip { - padding: 8px 12px; - margin: 4px; - border: none; - border-radius: 4px; - background-color: var(--main-color); - color: white; - cursor: pointer; - font-size: 16px; - margin-top: 10px; + padding: 8px 12px; + margin: 4px; + border: none; + border-radius: 4px; + background-color: var(--main-color); + color: white; + cursor: pointer; + font-size: 16px; + margin-top: 10px; } .notification { - position: fixed; - flex-direction: column; - padding: 10px 30px; - border: 1px solid #ccc; - border-radius: 10px; - background-color: #fff; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - font-size: 14px; - line-height: 1.5; - z-index: 1000; - overflow: hidden; - box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); - transition: right 0.5s ease-out, left 0.5s ease-out; + position: fixed; + flex-direction: column; + padding: 10px 30px; + border: 1px solid #ccc; + border-radius: 10px; + background-color: #fff; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + font-size: 14px; + line-height: 1.5; + z-index: 1000; + overflow: hidden; + box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); + transition: right 0.5s ease-out, left 0.5s ease-out; } .notification-arrow { - position: absolute; - width: 10px; - height: 10px; - background-color: #ccc; - transform: rotate(45deg); + position: absolute; + width: 10px; + height: 10px; + background-color: #ccc; + transform: rotate(45deg); } .notification-title { - display: flex; - justify-content: space-between; - align-items: center; - font-weight: bold; - margin-bottom: 5px; + display: flex; + justify-content: space-between; + align-items: center; + font-weight: bold; + margin-bottom: 5px; } .notification-content { - margin-bottom: 5px; + margin-bottom: 5px; } .notification-close { - cursor: pointer; - color: #ccc; - font-size: 12px; - font-weight: bold; - transition: transform 0.5s, color 0.5s; + cursor: pointer; + color: #ccc; + font-size: 12px; + font-weight: bold; + transition: transform 0.5s, color 0.5s; } .notification-close:hover { - color: #000; - transform: rotate(180deg); + color: #000; + transform: rotate(180deg); } .notification-close:mouseout { - color: #ccc; - transform: rotate(0deg); + color: #ccc; + transform: rotate(0deg); } .notification-clickBotton-box { - align-self: end; - display: flex; - gap: 5px; + align-self: end; + display: flex; + gap: 5px; } .notification-btn { - padding: 8px 12px; - margin: 4px; - border: none; - border-radius: 4px; - cursor: pointer; - font-size: 16px; + padding: 8px 12px; + margin: 4px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 16px; } .notification-btn:hover { - transform: translateY(-2px); + transform: translateY(-2px); } .notification-btn.confirmBotton { - background-color: var(--main-color); - color: white; + background-color: var(--main-color); + color: white; } .notification-btn.cancelBotton { - background-color: #ccc; + background-color: #ccc; } .notification-progress { - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 4px; - background-color: #4CAF50; - transition: width 0.1s linear; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 4px; + background-color: #4CAF50; + transition: width 0.1s linear; } .code-content { - display: flex; - width: var(--code-content-width); - min-height: 200px; - height: 100%; - overflow: auto; - white-space: pre; + display: flex; + width: var(--code-content-width); + min-height: 200px; + height: 100%; + overflow: auto; + white-space: pre; } .two-column-layout { - display: flex; - width: 100%; - height: var(--page-content-height); + display: flex; + width: 100%; + height: var(--page-content-height); } .sidebar { - flex-basis: var(--page-sidebar-width); - box-sizing: border-box; - padding: 50px 10px; - border-right: 1px solid var(--border-color); - overflow-y: auto; - width: 100%; + flex-basis: var(--page-sidebar-width); + box-sizing: border-box; + padding: 50px 10px; + border-right: 1px solid var(--border-color); + overflow-y: auto; + width: 100%; } .tabs { - display: block; - padding: 0; - margin: 50px 0 20px 0; + display: block; + padding: 0; + margin: 50px 0 20px 0; } .tab-button { - cursor: pointer; - padding: 10px; - border: none; - margin-right: 20px; - border-radius: 15px; + cursor: pointer; + padding: 10px; + border: none; + margin-right: 20px; + border-radius: 15px; } .tab-button.active { - background-color: var(--main-color-light); + background-color: var(--main-color-light); } .tab { - display: none; + display: none; } .tab.active { - display: block; + display: block; } .grid-container { - grid-template-columns: repeat(6, 1fr); - gap: 1rem; - padding: 1rem; - display: flex; - flex-wrap: wrap; - gap: 1rem; - padding: 1rem; + grid-template-columns: repeat(6, 1fr); + gap: 1rem; + padding: 1rem; + display: flex; + flex-wrap: wrap; + gap: 1rem; + padding: 1rem; } .grid-item { - background-color: #f0f0f0; - border-radius: 15px; - overflow: hidden; - width: 200px; - height: 200px; - position: relative; - display: flex; - flex-direction: column; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); - transition: transform 0.2s ease-in-out; + background-color: #f0f0f0; + border-radius: 15px; + overflow: hidden; + width: 200px; + height: 200px; + position: relative; + display: flex; + flex-direction: column; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + transition: transform 0.2s ease-in-out; } .grid-item:hover { - transform: scale(1.05); + transform: scale(1.05); } .thumbnail { - width: 100%; - flex-grow: 1; - background-size: cover; - background-position: center; + width: 100%; + flex-grow: 1; + background-size: cover; + background-position: center; } .caption { - width: 100%; - height: auto; - text-align: center; - background-color: white; + width: 100%; + height: auto; + text-align: center; + background-color: white; } .caption h6, .caption p { - margin: 1px 0; - font-size: 10px; + margin: 1px 0; + font-size: 10px; } .caption .button { - background-color: #007aff; - color: white; - padding: 2px 7px; - border: none; - border-radius: 8px; - font-size: 12px; - cursor: pointer; - transition: background 0.3s; + background-color: #007aff; + color: white; + padding: 2px 7px; + border: none; + border-radius: 8px; + font-size: 12px; + cursor: pointer; + transition: background 0.3s; } .caption .load-button { - margin-top: 5px; + margin-top: 5px; } .caption .delete-button { - margin-top: 5px; - padding: 2px 3px; + margin-top: 5px; + padding: 2px 3px; } .tooltip { - visibility: hidden; - width: 120px; - background-color: black; - color: rgb(0, 0, 0); - text-align: center; - border-radius: 5px; - padding: 5px; - position: absolute; - z-index: 1; - top: 100%; - left: 50%; - margin-left: -30px; - opacity: 0; - transition: opacity 0.3s; + visibility: hidden; + width: 120px; + background-color: black; + color: rgb(0, 0, 0); + text-align: center; + border-radius: 5px; + padding: 5px; + position: absolute; + z-index: 1; + top: 100%; + left: 50%; + margin-left: -30px; + opacity: 0; + transition: opacity 0.3s; } .menu-btn:hover .tooltip { - visibility: visible; - opacity: 1; + visibility: visible; + opacity: 1; } #navigation-bar-logo { - font-family: 'krypton', sans-serif; - font-size: 20px; - color: var(--logo-font-color); - white-space: nowrap; + font-family: 'krypton', sans-serif; + font-size: 20px; + color: var(--logo-font-color); + white-space: nowrap; } #navigation-bar-logo:hover { - cursor: pointer; + cursor: pointer; } \ No newline at end of file diff --git a/src/agentscope/studio/static/js/dashboard-detail-code.js b/src/agentscope/studio/static/js/dashboard-detail-code.js index e43c779cf..747fc69c7 100644 --- a/src/agentscope/studio/static/js/dashboard-detail-code.js +++ b/src/agentscope/studio/static/js/dashboard-detail-code.js @@ -2,76 +2,76 @@ let currentCode = null; let editorInstance = null; function initializeDashboardDetailCodePage(codeUrl) { - initializeMonacoEditor(); + initializeMonacoEditor(); - fetch("/api/code?run_dir=" + codeUrl) - .then((response) => { - if (!response.ok) { - throw new Error("Connection error, cannot load the web page."); - } - return response.json(); - }) - .then((data) => { - console.log("Get ", data); - currentCode = data; - constructCodeFileList(codeUrl, data); - }) - .catch((error) => { - console.error("Error encountered while loading page: ", error); - }); + fetch("/api/code?run_dir=" + codeUrl) + .then((response) => { + if (!response.ok) { + throw new Error("Connection error, cannot load the web page."); + } + return response.json(); + }) + .then((data) => { + console.log("Get ", data); + currentCode = data; + constructCodeFileList(codeUrl, data); + }) + .catch((error) => { + console.error("Error encountered while loading page: ", error); + }); } function constructCodeFileList(codeUrl, code) { - let codeFileRows = [``]; + let codeFileRows = [``]; - if (code !== null && code !== undefined) { - if (Object.keys(code).length === 0) { - codeFileRows = [ - '
No code available
', - ]; - } else { - Object.keys(code).forEach((key) => - codeFileRows.push( - `
  • ${key}
  • ` - ) - ); - } + if (code !== null && code !== undefined) { + if (Object.keys(code).length === 0) { + codeFileRows = [ + "
    No code available
    ", + ]; + } else { + Object.keys(code).forEach((key) => + codeFileRows.push( + `
  • ${key}
  • ` + ) + ); } + } - document.getElementById("code-list").innerHTML = codeFileRows.join("\n"); + document.getElementById("code-list").innerHTML = codeFileRows.join("\n"); } function initializeMonacoEditor() { - require.config({ - paths: { - vs: "https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs", - }, - }); - require(["vs/editor/editor.main"], function () { - editorInstance = monaco.editor.create( - document.getElementById("code-editor"), - { - language: "python", - theme: "vs-light", - scrollBeyondLastLine: false, - readOnly: true, - } - ); - }, function (error) { - console.error("Error encountered while loading monaco editor: ", error); - }); + require.config({ + paths: { + vs: "https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs", + }, + }); + require(["vs/editor/editor.main"], function () { + editorInstance = monaco.editor.create( + document.getElementById("code-editor"), + { + language: "python", + theme: "vs-light", + scrollBeyondLastLine: false, + readOnly: true, + } + ); + }, function (error) { + console.error("Error encountered while loading monaco editor: ", error); + }); } function displayCode(codeFileName) { - document.getElementById("code-filename").innerHTML = codeFileName; + document.getElementById("code-filename").innerHTML = codeFileName; - if (editorInstance) { - editorInstance.setValue(currentCode[codeFileName]); - } else { - console.log( - "Monaco editor instance is not available, set text content" - ); - document.getElementById("code-editor").textContent = + if (editorInstance) { + editorInstance.setValue(currentCode[codeFileName]); + } else { + console.log( + "Monaco editor instance is not available, set text content" + ); + document.getElementById("code-editor").textContent = currentCode[codeFileName]; - } + } } diff --git a/src/agentscope/studio/static/js/dashboard-detail-dialogue.js b/src/agentscope/studio/static/js/dashboard-detail-dialogue.js index a13520ceb..5fa87622c 100644 --- a/src/agentscope/studio/static/js/dashboard-detail-dialogue.js +++ b/src/agentscope/studio/static/js/dashboard-detail-dialogue.js @@ -1,7 +1,7 @@ let chatRowOtherTemplate, - chatRowUserTemplate, - chatRowSystemTemplate, - infoRowTemplate; + chatRowUserTemplate, + chatRowSystemTemplate, + infoRowTemplate; let currentRuntimeInfo, currentMsgInfo, currentAgentInfo; @@ -9,18 +9,18 @@ let randomNumberGenerator; let infoClusterize; -let inputFileList = document.getElementById("chat-control-file-list"); +const inputFileList = document.getElementById("chat-control-file-list"); let waitForUserInput = false; let userInputRequest = null; const agentIcons = [ - '', - '', - '', - '', - '', - '', + "", + "", + "", + "", + "", + "", ]; let nameToIconAndColor = {}; @@ -28,625 +28,627 @@ let nameToIconAndColor = {}; hljs.highlightAll(); const marked_options = { - gfm: true, - breaks: true, - pedantic: false, + gfm: true, + breaks: true, + pedantic: false, }; marked.use({ - renderer: { - code(code, infostring, escaped) { - const language = infostring - ? hljs.getLanguage(infostring) - ? infostring - : "plaintext" - : "plaintext"; - // Use Highlight.js to highlight code blocks - return `
    ${
    -                hljs.highlight(code, {language}).value
    -            }
    `; - }, + renderer: { + code(code, infostring, escaped) { + const language = infostring + ? hljs.getLanguage(infostring) + ? infostring + : "plaintext" + : "plaintext"; + // Use Highlight.js to highlight code blocks + return `
    ${
    +        hljs.highlight(code, {language}).value
    +      }
    `; }, + }, }); function randomSelectAgentIcon() { - return agentIcons[Math.floor(randomNumberGenerator.nextFloat() * agentIcons.length)]; + return agentIcons[Math.floor(randomNumberGenerator.nextFloat() * agentIcons.length)]; } function randomIntFromInterval(min, max) { - return Math.floor(randomNumberGenerator.nextFloat() * (max - min + 1) + min); + return Math.floor(randomNumberGenerator.nextFloat() * (max - min + 1) + min); } function hslToHex(h, s, l) { - l /= 100; - const a = (s * Math.min(l, 1 - l)) / 100; - const f = (n) => { - const k = (n + h / 30) % 12; - const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); - return Math.round(255 * color) - .toString(16) - .padStart(2, "0"); // 转换为16进制并补零 - }; - return `#${f(0)}${f(8)}${f(4)}`; + l /= 100; + const a = (s * Math.min(l, 1 - l)) / 100; + const f = (n) => { + const k = (n + h / 30) % 12; + const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); + return Math.round(255 * color) + .toString(16) + .padStart(2, "0"); // 转换为16进制并补零 + }; + return `#${f(0)}${f(8)}${f(4)}`; } function randomSelectColor() { - const h = randomIntFromInterval(0, 360); // 色相:0°到360° - const s = randomIntFromInterval(50, 100); // 饱和度:50%到100% - const l = randomIntFromInterval(25, 75); // 亮度:25%到75% - return hslToHex(h, s, l); + const h = randomIntFromInterval(0, 360); // 色相:0°到360° + const s = randomIntFromInterval(50, 100); // 饱和度:50%到100% + const l = randomIntFromInterval(25, 75); // 亮度:25%到75% + return hslToHex(h, s, l); } async function loadChatTemplate() { - const response = await fetch("static/html/template.html"); - const htmlText = await response.text(); - const parser = new DOMParser(); - const doc = parser.parseFromString(htmlText, "text/html"); - - // save - chatRowOtherTemplate = doc.querySelector( - "#chat-row-other-template" - ).content; - chatRowUserTemplate = doc.querySelector("#chat-row-user-template").content; - chatRowSystemTemplate = doc.querySelector( - "#chat-row-system-template" - ).content; - infoRowTemplate = doc.querySelector("#dialogue-info-row-template").content; + const response = await fetch("static/html/template.html"); + const htmlText = await response.text(); + const parser = new DOMParser(); + const doc = parser.parseFromString(htmlText, "text/html"); + + // save + chatRowOtherTemplate = doc.querySelector( + "#chat-row-other-template" + ).content; + chatRowUserTemplate = doc.querySelector("#chat-row-user-template").content; + chatRowSystemTemplate = doc.querySelector( + "#chat-row-system-template" + ).content; + infoRowTemplate = doc.querySelector("#dialogue-info-row-template").content; } // Add a chat row according to the role field in the message function addChatRow(index, pMsg) { - switch (pMsg.role.toLowerCase()) { - case "user": - return _addUserChatRow(index, pMsg); - case "system": - return _addSystemChatRow(index, pMsg); - case "assistant": - return _addAssistantChatRow(index, pMsg); - default: - console.error("Unknown role: " + pMsg.role); - return _addAssistantChatRow(index, pMsg); - } + switch (pMsg.role.toLowerCase()) { + case "user": + return _addUserChatRow(index, pMsg); + case "system": + return _addSystemChatRow(index, pMsg); + case "assistant": + return _addAssistantChatRow(index, pMsg); + default: + console.error("Unknown role: " + pMsg.role); + return _addAssistantChatRow(index, pMsg); + } } function _determineFileType(url) { - // Image - let img_suffix = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".webp"]; - // Video - let video_suffix = [ - ".mp4", - ".webm", - ".avi", - ".mov", - ".wmv", - ".flv", - ".f4v", - ".m4v", - ".rmvb", - ".rm", - ".3gp", - ".dat", - ".ts", - ".mts", - ".vob", - ]; + // Image + const img_suffix = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".webp"]; + // Video + const video_suffix = [ + ".mp4", + ".webm", + ".avi", + ".mov", + ".wmv", + ".flv", + ".f4v", + ".m4v", + ".rmvb", + ".rm", + ".3gp", + ".dat", + ".ts", + ".mts", + ".vob", + ]; // Audio - let audio_suffix = [".mp3", ".wav", ".wma", ".ogg", ".aac", ".flac"]; + const audio_suffix = [".mp3", ".wav", ".wma", ".ogg", ".aac", ".flac"]; - const parsed_url = new URL(url); - const path = parsed_url.pathname; + const parsed_url = new URL(url); + const path = parsed_url.pathname; - const extension = path.split('.').pop().toLowerCase(); + const extension = path.split(".").pop().toLowerCase(); - if (img_suffix.includes('.' + extension)) { - return "image"; - } else if (video_suffix.includes('.' + extension)) { - return "video"; - } else if (audio_suffix.includes('.' + extension)) { - return "audio"; - } - return "file"; + if (img_suffix.includes("." + extension)) { + return "image"; + } else if (video_suffix.includes("." + extension)) { + return "video"; + } else if (audio_suffix.includes("." + extension)) { + return "audio"; + } + return "file"; } function _getMultiModalComponent(url) { - // Determine the type of the file - let urlType = _determineFileType(url); - - // If we need to fetch the url from the backend - let src = null; - if (url.startsWith("http://") || url.startsWith("https://")) { - // Obtain the url from the backend - src = url; - } else { - src = "/api/file?path=" + url; - } - - switch (urlType) { - case "image": - return `Image`; - case "audio": - return ``; - case "video": - return ``; - default: - return `${url}`; - } + // Determine the type of the file + const urlType = _determineFileType(url); + + // If we need to fetch the url from the backend + let src = null; + if (url.startsWith("http://") || url.startsWith("https://")) { + // Obtain the url from the backend + src = url; + } else { + src = "/api/file?path=" + url; + } + + switch (urlType) { + case "image": + return `Image`; + case "audio": + return ``; + case "video": + return ``; + default: + return `${url}`; + } } // Render multiple urls in a chat bubble function _renderMultiModalUrls(urls) { - if (urls == null || urls === "") { - return "" - } - - if (typeof urls === "string") { - urls = [urls] - } - - if (Array.isArray(urls) && urls.length > 0) { - let innerHtml = ""; - for (let i = 0; i < urls.length; i++) { - innerHtml += _getMultiModalComponent(urls[i]); - } - return innerHtml; - } else { - return "" + if (urls == null || urls === "") { + return ""; + } + + if (typeof urls === "string") { + urls = [urls]; + } + + if (Array.isArray(urls) && urls.length > 0) { + let innerHtml = ""; + for (let i = 0; i < urls.length; i++) { + innerHtml += _getMultiModalComponent(urls[i]); } + return innerHtml; + } else { + return ""; + } } function _addUserChatRow(index, pMsg) { - const template = chatRowUserTemplate.cloneNode(true); - // template.querySelector('.chat-icon'). - template.querySelector(".chat-name").textContent = pMsg.name; - let chatBubble = template.querySelector(".chat-bubble"); - chatBubble.textContent += pMsg.content; - chatBubble.innerHTML += _renderMultiModalUrls(pMsg.url); - template.querySelector(".chat-row").setAttribute("data-index", index); - template - .querySelector(".chat-row") - .setAttribute("data-msg", JSON.stringify(pMsg)); - return template.firstElementChild; + const template = chatRowUserTemplate.cloneNode(true); + // template.querySelector('.chat-icon'). + template.querySelector(".chat-name").textContent = pMsg.name; + const chatBubble = template.querySelector(".chat-bubble"); + chatBubble.textContent += pMsg.content; + chatBubble.innerHTML += _renderMultiModalUrls(pMsg.url); + template.querySelector(".chat-row").setAttribute("data-index", index); + template + .querySelector(".chat-row") + .setAttribute("data-msg", JSON.stringify(pMsg)); + return template.firstElementChild; } function _addAssistantChatRow(index, pMsg) { - const template = chatRowOtherTemplate.cloneNode(true); - - // If not record - let svg_html, color; - if (pMsg.name in nameToIconAndColor) { - svg_html = nameToIconAndColor[pMsg.name][0]; - color = nameToIconAndColor[pMsg.name][1]; - } else { - // First choose a svg icon - svg_html = randomSelectAgentIcon(); - color = randomSelectColor(); - // Record the color and icon - nameToIconAndColor[pMsg.name] = [svg_html, color]; - } - template.querySelector(".chat-icon").innerHTML = svg_html; - // change the background color randomly - template.querySelector(".chat-icon").style.backgroundColor = color; - - template.querySelector(".chat-name").textContent = pMsg.name; - let chatBubble = template.querySelector(".chat-bubble"); - chatBubble.innerHTML += marked.parse(pMsg.content, marked_options); - chatBubble.innerHTML += _renderMultiModalUrls(pMsg.url); - template.querySelector(".chat-row").setAttribute("data-index", index); - template - .querySelector(".chat-row") - .setAttribute("data-msg", JSON.stringify(pMsg)); - return template.firstElementChild; + const template = chatRowOtherTemplate.cloneNode(true); + + // If not record + let svg_html, color; + if (pMsg.name in nameToIconAndColor) { + svg_html = nameToIconAndColor[pMsg.name][0]; + color = nameToIconAndColor[pMsg.name][1]; + } else { + // First choose a svg icon + svg_html = randomSelectAgentIcon(); + color = randomSelectColor(); + // Record the color and icon + nameToIconAndColor[pMsg.name] = [svg_html, color]; + } + template.querySelector(".chat-icon").innerHTML = svg_html; + // change the background color randomly + template.querySelector(".chat-icon").style.backgroundColor = color; + + template.querySelector(".chat-name").textContent = pMsg.name; + const chatBubble = template.querySelector(".chat-bubble"); + chatBubble.innerHTML += marked.parse(pMsg.content, marked_options); + chatBubble.innerHTML += _renderMultiModalUrls(pMsg.url); + template.querySelector(".chat-row").setAttribute("data-index", index); + template + .querySelector(".chat-row") + .setAttribute("data-msg", JSON.stringify(pMsg)); + return template.firstElementChild; } function _addSystemChatRow(index, pMsg) { - const template = chatRowSystemTemplate.cloneNode(true); - template.querySelector(".chat-name").textContent = pMsg.name; - let chatBubble = template.querySelector(".chat-bubble"); - chatBubble.innerHTML += marked.parse(pMsg.content, marked_options); - chatBubble.innerHTML += _renderMultiModalUrls(pMsg.url); - template.querySelector(".chat-row").setAttribute("data-index", index); - template - .querySelector(".chat-row") - .setAttribute("data-msg", JSON.stringify(pMsg)); - - return template.firstElementChild; + const template = chatRowSystemTemplate.cloneNode(true); + template.querySelector(".chat-name").textContent = pMsg.name; + const chatBubble = template.querySelector(".chat-bubble"); + chatBubble.innerHTML += marked.parse(pMsg.content, marked_options); + chatBubble.innerHTML += _renderMultiModalUrls(pMsg.url); + template.querySelector(".chat-row").setAttribute("data-index", index); + template + .querySelector(".chat-row") + .setAttribute("data-msg", JSON.stringify(pMsg)); + + return template.firstElementChild; } function _addKeyValueInfoRow(pKey, pValue) { - const template = infoRowTemplate.cloneNode(true); - template.querySelector(".dialogue-info-key").textContent = + const template = infoRowTemplate.cloneNode(true); + template.querySelector(".dialogue-info-key").textContent = pKey.toUpperCase(); - // Not null - if (pValue !== null) { - let infoValue = template.querySelector(".dialogue-info-value"); - if (pKey.toLowerCase() === "url") { - infoValue.style.wordBreak = "break-all"; - } - - if (typeof pValue === "object") { - infoValue.textContent = JSON.stringify(pValue); - } else { - infoValue.textContent = pValue; - } + // Not null + if (pValue !== null) { + const infoValue = template.querySelector(".dialogue-info-value"); + if (pKey.toLowerCase() === "url") { + infoValue.style.wordBreak = "break-all"; + } + + if (typeof pValue === "object") { + infoValue.textContent = JSON.stringify(pValue); + } else { + infoValue.textContent = pValue; } - return template.firstElementChild.outerHTML; + } + return template.firstElementChild.outerHTML; } function disableInput() { - document.getElementById("chat-control-url-btn").disabled = true; - document.getElementById("chat-control-send-btn").disabled = true; + document.getElementById("chat-control-url-btn").disabled = true; + document.getElementById("chat-control-send-btn").disabled = true; } function activateInput() { - document.getElementById("chat-control-url-btn").disabled = false; - document.getElementById("chat-control-send-btn").disabled = false; + document.getElementById("chat-control-url-btn").disabled = false; + document.getElementById("chat-control-send-btn").disabled = false; } function _showInfoInDialogueDetailContent(data) { - if (data === null) { - infoClusterize.clear(); - return; - } - - let priorityKeys = [ - "run_id", - "id", - "project", - "name", - "timestamp", - "role", - "url", - "metadata", - "content", - ]; + if (data === null) { + infoClusterize.clear(); + return; + } + + const priorityKeys = [ + "run_id", + "id", + "project", + "name", + "timestamp", + "role", + "url", + "metadata", + "content", + ]; // Deal with the priority keys first - let infoRows = priorityKeys - .filter((key) => key in data) - .map((key) => _addKeyValueInfoRow(key, data[key])); + const infoRows = priorityKeys + .filter((key) => key in data) + .map((key) => _addKeyValueInfoRow(key, data[key])); // Handle the rest of the keys - Object.keys(data) - .filter((key) => !priorityKeys.includes(key)) // Skip the priority keys - .forEach((key) => infoRows.push(_addKeyValueInfoRow(key, data[key]))); + Object.keys(data) + .filter((key) => !priorityKeys.includes(key)) // Skip the priority keys + .forEach((key) => infoRows.push(_addKeyValueInfoRow(key, data[key]))); - // Create table - infoClusterize.update(infoRows); + // Create table + infoClusterize.update(infoRows); } function _obtainAllUrlFromFileList() { - let urls = []; - for (let i = 0; i < inputFileList.children.length; i++) { - // obtain from the title attribute - urls.push(inputFileList.children[i].title); - } - return urls; + const urls = []; + for (let i = 0; i < inputFileList.children.length; i++) { + // obtain from the title attribute + urls.push(inputFileList.children[i].title); + } + return urls; } function addFileListItem(url) { - let svg; - switch (_determineFileType(url)) { - case "image": - svg = ` + let svg; + switch (_determineFileType(url)) { + case "image": + svg = ` `; - break; - case "video": - svg = ` + break; + case "video": + svg = ` `; - break; - case "audio": - svg = ``; - break; - default: - svg = ``; - break; - } - - let newItem = document.createElement("div"); - newItem.classList.add("chat-control-file-item"); - newItem.innerHTML = svg; - newItem.title = url; - - // Delete btn - const deleteBtn = document.createElement("div"); - deleteBtn.classList.add("chat-control-file-delete"); - // deleteBtn.innerHTML = ``; - deleteBtn.innerHTML = ``; - deleteBtn.onclick = function () { - inputFileList.removeChild(newItem); - }; - newItem.appendChild(deleteBtn); - - inputFileList.appendChild(newItem); - inputFileList.scrollLeft = + break; + case "audio": + svg = ""; + break; + default: + svg = ""; + break; + } + + const newItem = document.createElement("div"); + newItem.classList.add("chat-control-file-item"); + newItem.innerHTML = svg; + newItem.title = url; + + // Delete btn + const deleteBtn = document.createElement("div"); + deleteBtn.classList.add("chat-control-file-delete"); + // deleteBtn.innerHTML = ``; + deleteBtn.innerHTML = ""; + deleteBtn.onclick = function () { + inputFileList.removeChild(newItem); + }; + newItem.appendChild(deleteBtn); + + inputFileList.appendChild(newItem); + inputFileList.scrollLeft = inputFileList.scrollWidth - inputFileList.clientWidth; } // Turn a list of dom elements to a list of html strings function _turnDom2HTML(domList) { - return Array.from(domList).map((dom) => dom.outerHTML); + return Array.from(domList).map((dom) => dom.outerHTML); } function _showUrlPrompt() { - const userInput = prompt("Please enter a local or web URL:", ""); + const userInput = prompt("Please enter a local or web URL:", ""); - if (userInput !== null && userInput !== "") { - addFileListItem(userInput); - } + if (userInput !== null && userInput !== "") { + addFileListItem(userInput); + } } function _isMacOS() { - return navigator.platform.toUpperCase().indexOf("MAC") >= 0; + return navigator.platform.toUpperCase().indexOf("MAC") >= 0; } function initializeDashboardDetailDialoguePage(pRuntimeInfo) { - console.log("Initialize with runtime id: " + pRuntimeInfo.run_id); + console.log("Initialize with runtime id: " + pRuntimeInfo.run_id); - // Initialize the random seed generator by run_id - randomNumberGenerator = new SeededRand(_hashStringToSeed(pRuntimeInfo.run_id)); + // Initialize the random seed generator by run_id + randomNumberGenerator = new SeededRand(_hashStringToSeed(pRuntimeInfo.run_id)); - // Reset the flag - waitForUserInput = false; + // Reset the flag + waitForUserInput = false; - // Empty the record dictionary - nameToIconAndColor = {}; + // Empty the record dictionary + nameToIconAndColor = {}; - let sendBtn = document.getElementById( - "chat-control-send-btn" - ); + const sendBtn = document.getElementById( + "chat-control-send-btn" + ); - let inputTextArea = document.getElementById( - "chat-input-textarea" - ) + const inputTextArea = document.getElementById( + "chat-input-textarea" + ); - inputTextArea.addEventListener("keydown", function (e) { - if (e.key === "Enter" && !e.ctrlKey && !e.metaKey) { - e.preventDefault(); - - if (sendBtn.disabled === false) { - sendBtn.click(); - } - } else if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) { - e.preventDefault(); + inputTextArea.addEventListener("keydown", function (e) { + if (e.key === "Enter" && !e.ctrlKey && !e.metaKey) { + e.preventDefault(); - let cursorPosition = inputTextArea.selectionStart; - let textBeforeCursor = inputTextArea.value.substring(0, cursorPosition); - let textAfterCursor = inputTextArea.value.substring(cursorPosition); + if (sendBtn.disabled === false) { + sendBtn.click(); + } + } else if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) { + e.preventDefault(); - inputTextArea.value = textBeforeCursor + "\n" + textAfterCursor; + const cursorPosition = inputTextArea.selectionStart; + const textBeforeCursor = inputTextArea.value.substring(0, cursorPosition); + const textAfterCursor = inputTextArea.value.substring(cursorPosition); - // Update the cursor position - inputTextArea.selectionStart = inputTextArea.selectionEnd = cursorPosition + 1; - } - }) + inputTextArea.value = textBeforeCursor + "\n" + textAfterCursor; - // Set the placeholder according to the platform - if (_isMacOS()) { - inputTextArea.placeholder = "Input message here, ⌘ + Enter for new line"; - } else { - inputTextArea.placeholder = "Input message here, Ctrl + Enter for new line"; + // Update the cursor position + inputTextArea.selectionStart = inputTextArea.selectionEnd = cursorPosition + 1; } - - // Load the chat template - loadChatTemplate() - .then(() => { - // Initialize the detail objects - currentRuntimeInfo = pRuntimeInfo; - currentMsgInfo = null; - currentAgentInfo = null; - - infoClusterize = new Clusterize({ - scrollId: "chat-detail", - contentId: "dialogue-detail-content", - }); - - disableInput(); - - // Fetch the chat history from backend - fetch( - "/api/messages/run/" + + }); + + // Set the placeholder according to the platform + if (_isMacOS()) { + inputTextArea.placeholder = "Input message here, ⌘ + Enter for new line"; + } else { + inputTextArea.placeholder = "Input message here, Ctrl + Enter for new line"; + } + + // Load the chat template + loadChatTemplate() + .then(() => { + // Initialize the detail objects + currentRuntimeInfo = pRuntimeInfo; + currentMsgInfo = null; + currentAgentInfo = null; + + infoClusterize = new Clusterize({ + scrollId: "chat-detail", + contentId: "dialogue-detail-content", + }); + + disableInput(); + + // Fetch the chat history from backend + fetch( + "/api/messages/run/" + pRuntimeInfo.run_id + "?run_dir=" + pRuntimeInfo.run_dir - ) - .then((response) => { - if (!response.ok) { - throw new Error("Failed to fetch messages data"); - } - return response.json(); - }) - .then((data) => { - // Load the chat history - let chatRows = data.map((msg, index) => - addChatRow(index, msg) - ); - var clusterize = new Clusterize({ - rows: _turnDom2HTML(chatRows), - scrollId: "chat-box", - contentId: "chat-box-content", - }); - document.getElementById("chat-box-content"); - addEventListener("click", function (event) { - let target = event.target; - - while ( - target && + ) + .then((response) => { + if (!response.ok) { + throw new Error("Failed to fetch messages data"); + } + return response.json(); + }) + .then((data) => { + // Load the chat history + const chatRows = data.map((msg, index) => + addChatRow(index, msg) + ); + const clusterize = new Clusterize({ + rows: _turnDom2HTML(chatRows), + scrollId: "chat-box", + contentId: "chat-box-content", + }); + document.getElementById("chat-box-content"); + addEventListener("click", function (event) { + let target = event.target; + + while ( + target && target !== this && target instanceof Element - ) { - if (target.matches(".chat-row")) { - // Record the current message - currentMsgInfo = JSON.parse( - target.getAttribute("data-msg") - ); - - // Update web ui - showInDetail("Message"); - break; - } - target = target.parentNode; - } - }); - // Load the detail content in the right panel - // traverse all the keys in pRuntimeInfo and create a key-value row - currentRuntimeInfo = pRuntimeInfo; - showInDetail("Runtime"); - - var socket = io(); - socket.on("connect", () => { - // Tell flask server the web ui is ready - socket.emit("join", {run_id: pRuntimeInfo.run_id}); - - sendBtn.onclick = () => { - var message = document.getElementById( - "chat-input-textarea" - ).value; - - if (message === "") { - alert("Please input a message!"); - return; - } - - // Send the message to the flask server according to the current request - let url = _obtainAllUrlFromFileList(); - socket.emit("user_input_ready", { - run_id: userInputRequest.run_id, - agent_id: userInputRequest.agent_id, - name: userInputRequest.name, - url: url, - content: message, - }); - // Finish a user input - while (inputFileList.firstChild) { - inputFileList.removeChild(inputFileList.firstChild); - } - - waitForUserInput = false; - - console.log("Studio: send user_input_ready"); - - document.getElementById( - "chat-input-textarea" - ).value = ""; - disableInput(); - }; - }); - socket.on("display_message", (data) => { - if (data.run_id === pRuntimeInfo.run_id) { - console.log("Studio: receive display_message"); - - // Check the chatRows list in the reverse order to - // save time - let found = false; - for (let index = chatRows.length - 1; index >= 0; index--) { - const row = chatRows[index]; - let rowDataMsg = JSON.parse(row.getAttribute("data-msg")); - if (rowDataMsg.id === data.id) { - // Update the row - chatRows[index] = addChatRow(index, data); - // Update the list - clusterize.update(_turnDom2HTML(chatRows)); - found = true; - // Break the loop - break; - } - } - - if (!found) { - // Create a new row - let newRow = addChatRow( - clusterize.getRowsAmount(), - data - ); - chatRows.push(newRow); - clusterize.append(_turnDom2HTML([newRow])); - clusterize.refresh(); - } - - var scrollElem = + ) { + if (target.matches(".chat-row")) { + // Record the current message + currentMsgInfo = JSON.parse( + target.getAttribute("data-msg") + ); + + // Update web ui + showInDetail("Message"); + break; + } + target = target.parentNode; + } + }); + // Load the detail content in the right panel + // traverse all the keys in pRuntimeInfo and create a key-value row + currentRuntimeInfo = pRuntimeInfo; + showInDetail("Runtime"); + + const socket = io(); + socket.on("connect", () => { + // Tell flask server the web ui is ready + socket.emit("join", {run_id: pRuntimeInfo.run_id}); + + sendBtn.onclick = () => { + const message = document.getElementById( + "chat-input-textarea" + ).value; + + if (message === "") { + alert("Please input a message!"); + return; + } + + // Send the message to the flask server according to the current request + const url = _obtainAllUrlFromFileList(); + socket.emit("user_input_ready", { + run_id: userInputRequest.run_id, + agent_id: userInputRequest.agent_id, + name: userInputRequest.name, + url: url, + content: message, + }); + // Finish a user input + while (inputFileList.firstChild) { + inputFileList.removeChild(inputFileList.firstChild); + } + + waitForUserInput = false; + + console.log("Studio: send user_input_ready"); + + document.getElementById( + "chat-input-textarea" + ).value = ""; + disableInput(); + }; + }); + socket.on("display_message", (data) => { + if (data.run_id === pRuntimeInfo.run_id) { + console.log("Studio: receive display_message"); + + // Check the chatRows list in the reverse order to + // save time + let found = false; + for (let index = chatRows.length - 1; index >= 0; index--) { + const row = chatRows[index]; + const rowDataMsg = JSON.parse(row.getAttribute("data-msg")); + if (rowDataMsg.id === data.id) { + // Update the row + chatRows[index] = addChatRow(index, data); + // Update the list + clusterize.update(_turnDom2HTML(chatRows)); + found = true; + // Break the loop + break; + } + } + + if (!found) { + // Create a new row + const newRow = addChatRow( + clusterize.getRowsAmount(), + data + ); + chatRows.push(newRow); + clusterize.append(_turnDom2HTML([newRow])); + clusterize.refresh(); + } + + const scrollElem = document.getElementById("chat-box"); - scrollElem.scrollTop = scrollElem.scrollHeight; - } - }); - socket.on("enable_user_input", (data) => { - // Require user input in web ui - console.log("Studio: receive enable_user_input"); - - // If already waiting for user input, just abort the request - if (!waitForUserInput) { - // If not waiting for user input, enable the send button - waitForUserInput = true; - // Record the current request - userInputRequest = data; - activateInput(); - document.getElementById( - "chat-input-name" - ).textContent = data.name; - } - }); - }) - .catch((error) => { - console.error("Failed to fetch messages data:", error); - }); + scrollElem.scrollTop = scrollElem.scrollHeight; + } + }); + socket.on("enable_user_input", (data) => { + // Require user input in web ui + console.log("Studio: receive enable_user_input"); + + // If already waiting for user input, just abort the request + if (!waitForUserInput) { + // If not waiting for user input, enable the send button + waitForUserInput = true; + // Record the current request + userInputRequest = data; + activateInput(); + document.getElementById( + "chat-input-name" + ).textContent = data.name; + } + }); }) .catch((error) => { - console.error("Failed to load chat template:", error); + console.error("Failed to fetch messages data:", error); }); + }) + .catch((error) => { + console.error("Failed to load chat template:", error); + }); } function showInDetail(detailType) { - document.getElementById("dialogue-info-title").innerHTML = + document.getElementById("dialogue-info-title").innerHTML = detailType.toUpperCase(); - document.getElementById("runtimeSwitchBtn").classList.remove("selected"); - document.getElementById("msgSwitchBtn").classList.remove("selected"); - document.getElementById("agentSwitchBtn").classList.remove("selected"); - - switch (detailType.toLowerCase()) { - case "runtime": - document - .getElementById("runtimeSwitchBtn") - .classList.add("selected"); - _showInfoInDialogueDetailContent(currentRuntimeInfo); - break; - case "message": - document.getElementById("msgSwitchBtn").classList.add("selected"); - _showInfoInDialogueDetailContent(currentMsgInfo); - break; - case "agent": - document.getElementById("agentSwitchBtn").classList.add("selected"); - _showInfoInDialogueDetailContent(currentAgentInfo); - break; - } + document.getElementById("runtimeSwitchBtn").classList.remove("selected"); + document.getElementById("msgSwitchBtn").classList.remove("selected"); + document.getElementById("agentSwitchBtn").classList.remove("selected"); + + switch (detailType.toLowerCase()) { + case "runtime": + document + .getElementById("runtimeSwitchBtn") + .classList.add("selected"); + _showInfoInDialogueDetailContent(currentRuntimeInfo); + break; + case "message": + document.getElementById("msgSwitchBtn").classList.add("selected"); + _showInfoInDialogueDetailContent(currentMsgInfo); + break; + case "agent": + document.getElementById("agentSwitchBtn").classList.add("selected"); + _showInfoInDialogueDetailContent(currentAgentInfo); + break; + } } function _hashStringToSeed(str) { - let hash = 0; - for (let i = 0; i < str.length; i++) { - const char = str.charCodeAt(i); - hash = ((hash << 5) - hash) + char; - hash = hash & hash; // Turn it into a 32bit integer - } - return hash; + let hash = 0; + for (let i = 0; i < str.length; i++) { + const char = str.charCodeAt(i); + hash = ((hash << 5) - hash) + char; + hash = hash & hash; // Turn it into a 32bit integer + } + return hash; } // Linear congruential generator class SeededRand { - constructor(seed) { - this.modulus = 2147483648; // 2**31 - this.multiplier = 48271; // 常数 - this.increment = 0; // 常数 - this.seed = seed % this.modulus; - if (this.seed <= 0) this.seed += this.modulus - 1; + constructor(seed) { + this.modulus = 2147483648; // 2**31 + this.multiplier = 48271; // 常数 + this.increment = 0; // 常数 + this.seed = seed % this.modulus; + if (this.seed <= 0) { + this.seed += this.modulus - 1; } + } - nextFloat() { - this.seed = (this.seed * this.multiplier + this.increment) % this.modulus; - return this.seed / this.modulus; - } + nextFloat() { + this.seed = (this.seed * this.multiplier + this.increment) % this.modulus; + return this.seed / this.modulus; + } } \ No newline at end of file diff --git a/src/agentscope/studio/static/js/dashboard-detail-invocation.js b/src/agentscope/studio/static/js/dashboard-detail-invocation.js index 34daf1ea7..213f2ae8b 100644 --- a/src/agentscope/studio/static/js/dashboard-detail-invocation.js +++ b/src/agentscope/studio/static/js/dashboard-detail-invocation.js @@ -1,75 +1,75 @@ let invocationEditor = null; function initializeDashboardDetailInvocationPage(runDir) { - // load monaco editor - require.config({ - paths: { - vs: "https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs", + // load monaco editor + require.config({ + paths: { + vs: "https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs", + }, + }); + require(["vs/editor/editor.main"], function () { + invocationEditor = monaco.editor.create( + document.getElementById("invocation-content"), + { + language: "json", + theme: "vs-light", + minimap: { + enabled: false, }, - }); - require(["vs/editor/editor.main"], function () { - invocationEditor = monaco.editor.create( - document.getElementById("invocation-content"), - { - language: "json", - theme: "vs-light", - minimap: { - enabled: false, - }, - scrollBeyondLastLine: false, - readOnly: true, - } - ); - }); + scrollBeyondLastLine: false, + readOnly: true, + } + ); + }); - // fetch data from server - fetch("/api/invocation?run_dir=" + runDir) - .then((response) => { - if (response.ok) { - return response.json(); - } else { - throw new Error("Failed to fetch invocation detail"); - } - }) - .then((data) => { - console.log(data); - var invocationTable = new Tabulator("#invocation-list", { - data: data, - columns: [ - { - title: "Model Wrapper", - field: "model_class", - editor: false, - vertAlign: "middle", - }, - { - title: "Timestamp", - field: "timestamp", - editor: false, - vertAlign: "middle", - }, - ], - layout: "fitColumns", - placeholder: + // fetch data from server + fetch("/api/invocation?run_dir=" + runDir) + .then((response) => { + if (response.ok) { + return response.json(); + } else { + throw new Error("Failed to fetch invocation detail"); + } + }) + .then((data) => { + console.log(data); + const invocationTable = new Tabulator("#invocation-list", { + data: data, + columns: [ + { + title: "Model Wrapper", + field: "model_class", + editor: false, + vertAlign: "middle", + }, + { + title: "Timestamp", + field: "timestamp", + editor: false, + vertAlign: "middle", + }, + ], + layout: "fitColumns", + placeholder: "
    No invocation records available.
    ", - initialSort: [ - { - column: "timestamp", - dir: "asc", - }, - ], - }); + initialSort: [ + { + column: "timestamp", + dir: "asc", + }, + ], + }); - // Set up row click event - invocationTable.on("rowClick", function (e, row) { - // Jump to the run detail page - console.log(row.getData()); - invocationEditor.setValue( - JSON.stringify(row.getData(), null, 2) - ); - }); - }) - .catch((error) => { - console.error(error); - }); + // Set up row click event + invocationTable.on("rowClick", function (e, row) { + // Jump to the run detail page + console.log(row.getData()); + invocationEditor.setValue( + JSON.stringify(row.getData(), null, 2) + ); + }); + }) + .catch((error) => { + console.error(error); + }); } diff --git a/src/agentscope/studio/static/js/dashboard-detail.js b/src/agentscope/studio/static/js/dashboard-detail.js index 806b15131..0847ac3a6 100644 --- a/src/agentscope/studio/static/js/dashboard-detail.js +++ b/src/agentscope/studio/static/js/dashboard-detail.js @@ -2,17 +2,17 @@ let runtimeInfo = null; let currentContent = null; function initializeDashboardDetailPageByUrl(pageUrl) { - switch (pageUrl) { - case "static/html/dashboard-detail-dialogue.html": - initializeDashboardDetailDialoguePage(runtimeInfo); - break; - case "static/html/dashboard-detail-code.html": - initializeDashboardDetailCodePage(runtimeInfo["run_dir"]); - break; - case "static/html/dashboard-detail-invocation.html": - initializeDashboardDetailInvocationPage(runtimeInfo["run_dir"]); - break; - } + switch (pageUrl) { + case "static/html/dashboard-detail-dialogue.html": + initializeDashboardDetailDialoguePage(runtimeInfo); + break; + case "static/html/dashboard-detail-code.html": + initializeDashboardDetailCodePage(runtimeInfo["run_dir"]); + break; + case "static/html/dashboard-detail-invocation.html": + initializeDashboardDetailInvocationPage(runtimeInfo["run_dir"]); + break; + } } // The dashboard detail page supports three tabs: @@ -20,73 +20,73 @@ function initializeDashboardDetailPageByUrl(pageUrl) { // 2. code tab: the code files // 3. invocation tab: the model invocation records function loadDashboardDetailContent(pageUrl, javascriptUrl) { - const dialogueTabBtn = document.getElementById("dialogue-tab-btn"); - const codeTabBtn = document.getElementById("code-tab-btn"); - const invocationTabBtn = document.getElementById("invocation-tab-btn"); - if (currentContent === pageUrl) { - return; - } else { - currentContent = pageUrl; - } - // switch selected status - switch (pageUrl) { - case "static/html/dashboard-detail-dialogue.html": - dialogueTabBtn.classList.add("selected"); - codeTabBtn.classList.remove("selected"); - invocationTabBtn.classList.remove("selected"); - break; - case "static/html/dashboard-detail-code.html": - dialogueTabBtn.classList.remove("selected"); - codeTabBtn.classList.add("selected"); - invocationTabBtn.classList.remove("selected"); - break; - case "static/html/dashboard-detail-invocation.html": - dialogueTabBtn.classList.remove("selected"); - codeTabBtn.classList.remove("selected"); - invocationTabBtn.classList.add("selected"); - break; - } + const dialogueTabBtn = document.getElementById("dialogue-tab-btn"); + const codeTabBtn = document.getElementById("code-tab-btn"); + const invocationTabBtn = document.getElementById("invocation-tab-btn"); + if (currentContent === pageUrl) { + return; + } else { + currentContent = pageUrl; + } + // switch selected status + switch (pageUrl) { + case "static/html/dashboard-detail-dialogue.html": + dialogueTabBtn.classList.add("selected"); + codeTabBtn.classList.remove("selected"); + invocationTabBtn.classList.remove("selected"); + break; + case "static/html/dashboard-detail-code.html": + dialogueTabBtn.classList.remove("selected"); + codeTabBtn.classList.add("selected"); + invocationTabBtn.classList.remove("selected"); + break; + case "static/html/dashboard-detail-invocation.html": + dialogueTabBtn.classList.remove("selected"); + codeTabBtn.classList.remove("selected"); + invocationTabBtn.classList.add("selected"); + break; + } - fetch(pageUrl, { cache: "no-store" }) - .then((response) => { - if (!response.ok) { - throw new Error("Connection error, cannot load the web page."); - } - return response.text(); - }) - .then((html) => { - // Load the page content - document.getElementById("detail-content").innerHTML = html; + fetch(pageUrl, { cache: "no-store" }) + .then((response) => { + if (!response.ok) { + throw new Error("Connection error, cannot load the web page."); + } + return response.text(); + }) + .then((html) => { + // Load the page content + document.getElementById("detail-content").innerHTML = html; - if (!isScriptLoaded(javascriptUrl)) { - let script = document.createElement("script"); - script.src = javascriptUrl; - script.onload = function () { - initializeDashboardDetailPageByUrl(pageUrl); - }; - document.head.appendChild(script); - } else { - initializeDashboardDetailPageByUrl(pageUrl); - } - }) - .catch((error) => { - console.error("Error encountered while loading page: ", error); - document.getElementById("content").innerHTML = + if (!isScriptLoaded(javascriptUrl)) { + const script = document.createElement("script"); + script.src = javascriptUrl; + script.onload = function () { + initializeDashboardDetailPageByUrl(pageUrl); + }; + document.head.appendChild(script); + } else { + initializeDashboardDetailPageByUrl(pageUrl); + } + }) + .catch((error) => { + console.error("Error encountered while loading page: ", error); + document.getElementById("content").innerHTML = "

    Loading failed.

    " + error; - }); + }); } // Initialize the dashboard detail page, this function is the entry point of the dashboard detail page function initializeDashboardDetailPage(pRuntimeInfo) { - // The default content of the dashboard detail page - console.log( - "Initialize dashboard detail page with runtime id: " + + // The default content of the dashboard detail page + console.log( + "Initialize dashboard detail page with runtime id: " + pRuntimeInfo.run_id - ); - runtimeInfo = pRuntimeInfo; - currentContent = null; - loadDashboardDetailContent( - "static/html/dashboard-detail-dialogue.html", - "static/js/dashboard-detail-dialogue.js" - ); + ); + runtimeInfo = pRuntimeInfo; + currentContent = null; + loadDashboardDetailContent( + "static/html/dashboard-detail-dialogue.html", + "static/js/dashboard-detail-dialogue.js" + ); } diff --git a/src/agentscope/studio/static/js/dashboard-runs.js b/src/agentscope/studio/static/js/dashboard-runs.js index 51be4960c..e3375ebc4 100644 --- a/src/agentscope/studio/static/js/dashboard-runs.js +++ b/src/agentscope/studio/static/js/dashboard-runs.js @@ -1,115 +1,115 @@ // Search functionality for runs table function allColumnFilter(data) { - let searchValue = document - .getElementById("runs-search-input") - .value.toLowerCase(); + const searchValue = document + .getElementById("runs-search-input") + .value.toLowerCase(); - for (var field in data) { - if (data.hasOwnProperty(field)) { - var value = data[field]; + for (const field in data) { + if (data.hasOwnProperty(field)) { + let value = data[field]; - if (value != null) { - value = value.toString().toLowerCase(); - if (value.includes(searchValue)) { - return true; - } - } + if (value != null) { + value = value.toString().toLowerCase(); + if (value.includes(searchValue)) { + return true; } + } } - return false; + } + return false; } function renderIconInRunsTable(cell, formatterParams, onRendered) { - let value = cell.getValue(); - switch (value) { - case "running": - return '
    running
    '; + const value = cell.getValue(); + switch (value) { + case "running": + return "
    running
    "; - case "waiting": - return '
    waiting
    '; + case "waiting": + return "
    waiting
    "; - case "finished": - return '
    finished
    '; + case "finished": + return "
    finished
    "; - default: - return '
    unknown
    '; - } + default: + return "
    unknown
    "; + } } function initializeDashboardRunsPage() { - //TODO: fetch runs data from server - fetch("/api/runs/all") - .then((response) => { - if (!response.ok) { - throw new Error("Failed to fetch runs data"); - } - return response.json(); - }) - .then((data) => { - var runsTable = new Tabulator("#runs-table", { - data: data, - columns: [ - { - title: "Status", - field: "status", - editor: false, - vertAlign: "middle", - formatter: renderIconInRunsTable, - }, - { - title: "ID", - field: "run_id", - editor: false, - vertAlign: "middle", - }, - { - title: "Project", - field: "project", - editor: false, - vertAlign: "middle", - }, - { - title: "Name", - field: "name", - editor: false, - vertAlign: "middle", - }, - { - title: "Timestamp", - field: "timestamp", - editor: false, - vertAlign: "middle", - }, - ], - layout: "fitColumns", - initialSort: [{ column: "timestamp", dir: "desc" }], - }); - - // Search logic - document - .getElementById("runs-search-input") - .addEventListener("input", function (e) { - let searchValue = e.target.value; - if (searchValue) { - // Filter the table - runsTable.setFilter(allColumnFilter); - } else { - //Clear the filter - runsTable.clearFilter(); - } - }); + //TODO: fetch runs data from server + fetch("/api/runs/all") + .then((response) => { + if (!response.ok) { + throw new Error("Failed to fetch runs data"); + } + return response.json(); + }) + .then((data) => { + const runsTable = new Tabulator("#runs-table", { + data: data, + columns: [ + { + title: "Status", + field: "status", + editor: false, + vertAlign: "middle", + formatter: renderIconInRunsTable, + }, + { + title: "ID", + field: "run_id", + editor: false, + vertAlign: "middle", + }, + { + title: "Project", + field: "project", + editor: false, + vertAlign: "middle", + }, + { + title: "Name", + field: "name", + editor: false, + vertAlign: "middle", + }, + { + title: "Timestamp", + field: "timestamp", + editor: false, + vertAlign: "middle", + }, + ], + layout: "fitColumns", + initialSort: [{ column: "timestamp", dir: "desc" }], + }); - // Set up row click event - runsTable.on("rowClick", function (e, row) { - // Jump to the run detail page - loadDetailPageInDashboardContent( - "static/html/dashboard-detail.html", - "static/js/dashboard-detail.js", - row.getData() - ); - }); - }) - .catch((error) => { - console.error(error); + // Search logic + document + .getElementById("runs-search-input") + .addEventListener("input", function (e) { + const searchValue = e.target.value; + if (searchValue) { + // Filter the table + runsTable.setFilter(allColumnFilter); + } else { + //Clear the filter + runsTable.clearFilter(); + } }); + + // Set up row click event + runsTable.on("rowClick", function (e, row) { + // Jump to the run detail page + loadDetailPageInDashboardContent( + "static/html/dashboard-detail.html", + "static/js/dashboard-detail.js", + row.getData() + ); + }); + }) + .catch((error) => { + console.error(error); + }); } diff --git a/src/agentscope/studio/static/js/dashboard.js b/src/agentscope/studio/static/js/dashboard.js index ffaeeb43d..9b066623f 100644 --- a/src/agentscope/studio/static/js/dashboard.js +++ b/src/agentscope/studio/static/js/dashboard.js @@ -1,117 +1,117 @@ function loadRunsPageInDashboardContent(pageUrl, javascriptUrl) { - fetch(pageUrl) - .then((response) => { - if (!response.ok) { - throw new Error("Connection error, cannot load the web page."); - } - return response.text(); - }) - .then((html) => { - // Load the page content - document.getElementById("dashboard-content").innerHTML = html; + fetch(pageUrl) + .then((response) => { + if (!response.ok) { + throw new Error("Connection error, cannot load the web page."); + } + return response.text(); + }) + .then((html) => { + // Load the page content + document.getElementById("dashboard-content").innerHTML = html; - // Load the javascript file - if (!isScriptLoaded(javascriptUrl)) { - console.log("Loading script from " + javascriptUrl + "..."); - let script = document.createElement("script"); - script.src = javascriptUrl; - script.onload = function () { - // Initialize the runs tables - initializeDashboardRunsPage(); - }; - document.head.appendChild(script); - } else { - // Initialize the runs tables - initializeDashboardRunsPage(); - } + // Load the javascript file + if (!isScriptLoaded(javascriptUrl)) { + console.log("Loading script from " + javascriptUrl + "..."); + const script = document.createElement("script"); + script.src = javascriptUrl; + script.onload = function () { + // Initialize the runs tables + initializeDashboardRunsPage(); + }; + document.head.appendChild(script); + } else { + // Initialize the runs tables + initializeDashboardRunsPage(); + } - // Jump to specific run if url contains run_id - const urlParams = new URLSearchParams(window.location.search); - if (urlParams.has("run_id")) { - var loc = window.location; - var baseUrl = loc.protocol + "//" + loc.host; - const run_id = urlParams.get("run_id"); - history.replaceState(null, null, baseUrl); - fetch("/api/runs/get/" + run_id) - .then((response) => { - console.log("fetch /api/runs/get/"); + // Jump to specific run if url contains run_id + const urlParams = new URLSearchParams(window.location.search); + if (urlParams.has("run_id")) { + const loc = window.location; + const baseUrl = loc.protocol + "//" + loc.host; + const run_id = urlParams.get("run_id"); + history.replaceState(null, null, baseUrl); + fetch("/api/runs/get/" + run_id) + .then((response) => { + console.log("fetch /api/runs/get/"); - if (!response.ok) { - throw new Error( - "Runtime id " + run_id + " not found." - ); - } - return response.json(); - }) - .then((data) => { - console.log("get runs" + data); - loadDetailPageInDashboardContent( - "static/html/dashboard-detail.html", - "static/js/dashboard-detail.js", - data - ); - }); + if (!response.ok) { + throw new Error( + "Runtime id " + run_id + " not found." + ); } - }) - .catch((error) => { - console.error("Error encountered while loading page: ", error); - document.getElementById("content").innerHTML = + return response.json(); + }) + .then((data) => { + console.log("get runs" + data); + loadDetailPageInDashboardContent( + "static/html/dashboard-detail.html", + "static/js/dashboard-detail.js", + data + ); + }); + } + }) + .catch((error) => { + console.error("Error encountered while loading page: ", error); + document.getElementById("content").innerHTML = "

    Loading failed.

    " + error; - }); + }); } function loadDetailPageInDashboardContent(pageUrl, javascriptUrl, runtimeInfo) { - fetch(pageUrl) - .then((response) => { - if (!response.ok) { - throw new Error("Connection error, cannot load the web page."); - } - return response.text(); - }) - .then((html) => { - // Load the page content - document.getElementById("dashboard-content").innerHTML = html; + fetch(pageUrl) + .then((response) => { + if (!response.ok) { + throw new Error("Connection error, cannot load the web page."); + } + return response.text(); + }) + .then((html) => { + // Load the page content + document.getElementById("dashboard-content").innerHTML = html; - if (!isScriptLoaded(javascriptUrl)) { - console.log("Loading script from " + javascriptUrl + "..."); - let script = document.createElement("script"); - script.src = javascriptUrl; - script.onload = function () { - initializeDashboardDetailPage(runtimeInfo); - }; - document.head.appendChild(script); - } else { - initializeDashboardDetailPage(runtimeInfo); - } + if (!isScriptLoaded(javascriptUrl)) { + console.log("Loading script from " + javascriptUrl + "..."); + const script = document.createElement("script"); + script.src = javascriptUrl; + script.onload = function () { + initializeDashboardDetailPage(runtimeInfo); + }; + document.head.appendChild(script); + } else { + initializeDashboardDetailPage(runtimeInfo); + } - // Update the title bar of the dashboard page - let titleBar = document.getElementById("dashboard-titlebar"); - // TODO: Add link to the dashboard page - titleBar.innerHTML += - '' + + // Update the title bar of the dashboard page + const titleBar = document.getElementById("dashboard-titlebar"); + // TODO: Add link to the dashboard page + titleBar.innerHTML += + "" + "Runtime ID: " + runtimeInfo.run_id + ""; - let mainTitle = document.getElementById("dashboard-main-title"); - mainTitle.onclick = () => { - loadTabPage( - "static/html/dashboard.html", - "static/js/dashboard.js" - ); - }; - }) - .catch((error) => { - console.error("Error encountered while loading page: ", error); - document.getElementById("content").innerHTML = + const mainTitle = document.getElementById("dashboard-main-title"); + mainTitle.onclick = () => { + loadTabPage( + "static/html/dashboard.html", + "static/js/dashboard.js" + ); + }; + }) + .catch((error) => { + console.error("Error encountered while loading page: ", error); + document.getElementById("content").innerHTML = "

    Loading failed.

    " + error; - }); + }); } // Initialize the dashboard page with a table of runtime instances function initializeDashboardPage() { - // The default content of the dashboard page - loadRunsPageInDashboardContent( - "static/html/dashboard-runs.html", - "static/js/dashboard-runs.js" - ); + // The default content of the dashboard page + loadRunsPageInDashboardContent( + "static/html/dashboard-runs.html", + "static/js/dashboard-runs.js" + ); } diff --git a/src/agentscope/studio/static/js/gallery.js b/src/agentscope/studio/static/js/gallery.js index 57e0f1f43..67695e748 100644 --- a/src/agentscope/studio/static/js/gallery.js +++ b/src/agentscope/studio/static/js/gallery.js @@ -1,280 +1,284 @@ -showTab('tab1'); +showTab("tab1"); function showTab(tabId) { - var tabs = document.getElementsByClassName("tab"); - for (var i = 0; i < tabs.length; i++) { - tabs[i].classList.remove("active"); - tabs[i].style.display = "none"; + const tabs = document.getElementsByClassName("tab"); + for (let i = 0; i < tabs.length; i++) { + tabs[i].classList.remove("active"); + tabs[i].style.display = "none"; + } + const tab = document.getElementById(tabId); + if (tab) { + tab.classList.add("active"); + tab.style.display = "block"; + console.log(`Activated tab with ID: ${tab.id}`); + + const tabButtons = document.getElementsByClassName("tab-button"); + for (let j = 0; j < tabButtons.length; j++) { + tabButtons[j].classList.remove("active"); + } + const activeTabButton = document.querySelector(`.tab-button[onclick*="${tabId}"]`); + if (activeTabButton) { + activeTabButton.classList.add("active"); } - var tab = document.getElementById(tabId); - if (tab) { - tab.classList.add("active"); - tab.style.display = "block"; - console.log(`Activated tab with ID: ${tab.id}`); - - var tabButtons = document.getElementsByClassName("tab-button"); - for (var j = 0; j < tabButtons.length; j++) { - tabButtons[j].classList.remove("active"); - } - var activeTabButton = document.querySelector(`.tab-button[onclick*="${tabId}"]`); - if (activeTabButton) { - activeTabButton.classList.add("active"); - } - if (tabId === "tab2") { - showLoadWorkflowList(tabId); - } else if (tabId === "tab1") { - console.log('Loading Gallery Workflow List'); - showGalleryWorkflowList(tabId); - } + if (tabId === "tab2") { + showLoadWorkflowList(tabId); + } else if (tabId === "tab1") { + console.log("Loading Gallery Workflow List"); + showGalleryWorkflowList(tabId); } + } } function sendWorkflow(fileName) { - if (confirm('Are you sure you want to import this workflow?')) { - const workstationUrl = '/workstation?filename=' + encodeURIComponent(fileName); - window.location.href = workstationUrl; - } + if (confirm("Are you sure you want to import this workflow?")) { + const workstationUrl = "/workstation?filename=" + encodeURIComponent(fileName); + window.location.href = workstationUrl; + } } function importGalleryWorkflow(data) { - try { - const parsedData = JSON.parse(data); - addHtmlAndReplacePlaceHolderBeforeImport(parsedData) - .then(() => { - editor.clear(); - editor.import(parsedData); - importSetupNodes(parsedData); - - if (confirm('Imported!')) { - const workstationUrl = '/workstation'; - window.location.href = workstationUrl; - } - }) - .catch(error => { - alert(`Import error: ${error}`); - }); - } catch (error) { + try { + const parsedData = JSON.parse(data); + addHtmlAndReplacePlaceHolderBeforeImport(parsedData) + .then(() => { + editor.clear(); + editor.import(parsedData); + importSetupNodes(parsedData); + + if (confirm("Imported!")) { + const workstationUrl = "/workstation"; + window.location.href = workstationUrl; + } + }) + .catch(error => { alert(`Import error: ${error}`); - } + }); + } catch (error) { + alert(`Import error: ${error}`); + } } function deleteWorkflow(fileName) { - if (confirm('Workflow has been deleted?')) { - fetch('/delete-workflow', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - filename: fileName, - }) - }).then(response => response.json()) - .then(data => { - if (data.error) { - alert(data.error); - } else { - showLoadWorkflowList('tab2'); - } - }) - .catch(error => { - console.error('Error:', error); - alert('delete workflow error.'); - }); - } + if (confirm("Workflow has been deleted?")) { + fetch("/delete-workflow", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + filename: fileName, + }) + }).then(response => response.json()) + .then(data => { + if (data.error) { + alert(data.error); + } else { + showLoadWorkflowList("tab2"); + } + }) + .catch(error => { + console.error("Error:", error); + alert("delete workflow error."); + }); + } } -function createGridItem(workflowName, container, thumbnail, author = '', time = '', showDeleteButton = false, index) { - var gridItem = document.createElement('div'); - gridItem.className = 'grid-item'; - gridItem.style.borderRadius = '15px'; - gridItem.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)'; - - - var img = document.createElement('div'); - img.className = 'thumbnail'; - img.style.backgroundImage = `url('${thumbnail}')`; - img.style.backgroundSize = 'cover'; - img.style.backgroundPosition = 'center'; - gridItem.appendChild(img); - - var caption = document.createElement('div'); - caption.className = 'caption'; - caption.style.backgroundColor = 'white'; - - var h6 = document.createElement('h6'); - h6.textContent = workflowName; - h6.style.margin = '1px 0'; - - var pAuthor = document.createElement('p'); - pAuthor.textContent = `Author: ${author}`; - pAuthor.style.margin = '1px 0'; - pAuthor.style.fontSize = '10px'; - - var pTime = document.createElement('p'); - pTime.textContent = `Date: ${time}`; - pTime.style.margin = '1px 0'; - pTime.style.fontSize = '10px'; - - var button = document.createElement('button'); - button.textContent = 'Load'; - button.className = 'button'; - button.style.marginRight = '5px'; - button.style.backgroundColor = '#007aff'; - button.style.backgroundImage = 'linear-gradient(to right, #6e48aa, #9d50bb)'; - button.style.color = 'white'; - button.style.padding = '2px 7px'; - button.style.border = 'none'; - button.style.borderRadius = '8px'; - button.style.fontSize = '12px'; - button.style.cursor = 'pointer'; - button.style.transition = 'background 0.3s'; - - button.addEventListener('mouseover', function () { - button.style.backgroundColor = '#005bb5'; +function createGridItem(workflowName, container, thumbnail, author = "", time = "", showDeleteButton = false, index) { + const gridItem = document.createElement("div"); + gridItem.className = "grid-item"; + gridItem.style.borderRadius = "15px"; + gridItem.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.2)"; + + + const img = document.createElement("div"); + img.className = "thumbnail"; + img.style.backgroundImage = `url('${thumbnail}')`; + img.style.backgroundSize = "cover"; + img.style.backgroundPosition = "center"; + gridItem.appendChild(img); + + const caption = document.createElement("div"); + caption.className = "caption"; + caption.style.backgroundColor = "white"; + + const h6 = document.createElement("h6"); + h6.textContent = workflowName; + h6.style.margin = "1px 0"; + + const pAuthor = document.createElement("p"); + pAuthor.textContent = `Author: ${author}`; + pAuthor.style.margin = "1px 0"; + pAuthor.style.fontSize = "10px"; + + const pTime = document.createElement("p"); + pTime.textContent = `Date: ${time}`; + pTime.style.margin = "1px 0"; + pTime.style.fontSize = "10px"; + + const button = document.createElement("button"); + button.textContent = "Load"; + button.className = "button"; + button.style.marginRight = "5px"; + button.style.backgroundColor = "#007aff"; + button.style.backgroundImage = "linear-gradient(to right, #6e48aa, #9d50bb)"; + button.style.color = "white"; + button.style.padding = "2px 7px"; + button.style.border = "none"; + button.style.borderRadius = "8px"; + button.style.fontSize = "12px"; + button.style.cursor = "pointer"; + button.style.transition = "background 0.3s"; + + button.addEventListener("mouseover", function () { + button.style.backgroundColor = "#005bb5"; + }); + + button.addEventListener("mouseout", function () { + button.style.backgroundColor = "#007aff"; + }); + button.onclick = function (e) { + e.preventDefault(); + if (showDeleteButton) { + sendWorkflow(workflowName); + } else { + const workflowData = galleryWorkflows[index]; + importGalleryWorkflow(JSON.stringify(workflowData)); + } + }; + + + caption.appendChild(h6); + if (author) { + caption.appendChild(pAuthor); + } + if (time) { + caption.appendChild(pTime); + } + caption.appendChild(button); + + if (showDeleteButton) { + const deleteButton = document.createElement("button"); + deleteButton.textContent = "Delete"; + deleteButton.className = "button"; + deleteButton.style.backgroundColor = "#007aff"; + deleteButton.style.backgroundImage = "linear-gradient(to right, #6e48aa, #9d50bb)"; + deleteButton.style.color = "white"; + deleteButton.style.padding = "2px 3px"; + deleteButton.style.border = "none"; + deleteButton.style.borderRadius = "8px"; + deleteButton.style.fontSize = "12px"; + deleteButton.style.cursor = "pointer"; + deleteButton.style.transition = "background 0.3s"; + + deleteButton.addEventListener("mouseover", function () { + deleteButton.style.backgroundColor = "#005bb5"; }); - - button.addEventListener('mouseout', function () { - button.style.backgroundColor = '#007aff'; + deleteButton.addEventListener("mouseout", function () { + deleteButton.style.backgroundColor = "#007aff"; }); - button.onclick = function (e) { - e.preventDefault(); - if (showDeleteButton) { - sendWorkflow(workflowName); - } else { - const workflowData = galleryWorkflows[index]; - importGalleryWorkflow(JSON.stringify(workflowData)); - } - }; + deleteButton.onclick = function (e) { + e.preventDefault(); + deleteWorkflow(workflowName); + }; - caption.appendChild(h6); - if (author) caption.appendChild(pAuthor); - if (time) caption.appendChild(pTime); - caption.appendChild(button); + caption.appendChild(deleteButton); + } - if (showDeleteButton) { - var deleteButton = document.createElement('button'); - deleteButton.textContent = 'Delete'; - deleteButton.className = 'button'; - deleteButton.style.backgroundColor = '#007aff'; - deleteButton.style.backgroundImage = 'linear-gradient(to right, #6e48aa, #9d50bb)'; - deleteButton.style.color = 'white'; - deleteButton.style.padding = '2px 3px'; - deleteButton.style.border = 'none'; - deleteButton.style.borderRadius = '8px'; - deleteButton.style.fontSize = '12px'; - deleteButton.style.cursor = 'pointer'; - deleteButton.style.transition = 'background 0.3s'; - - deleteButton.addEventListener('mouseover', function () { - deleteButton.style.backgroundColor = '#005bb5'; - }); - deleteButton.addEventListener('mouseout', function () { - deleteButton.style.backgroundColor = '#007aff'; - }); - - deleteButton.onclick = function (e) { - e.preventDefault(); - deleteWorkflow(workflowName); - }; - - caption.appendChild(deleteButton); - } - - gridItem.appendChild(caption); - container.appendChild(gridItem); - console.log('Grid item appended:', gridItem); + gridItem.appendChild(caption); + container.appendChild(gridItem); + console.log("Grid item appended:", gridItem); } // let galleryWorkflows = []; function showGalleryWorkflowList(tabId) { - const container = document.getElementById(tabId).querySelector('.grid-container'); - container.innerHTML = ''; - - fetch('/fetch-gallery', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({}) + const container = document.getElementById(tabId).querySelector(".grid-container"); + container.innerHTML = ""; + + fetch("/fetch-gallery", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({}) + }) + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.json(); + }) + .then(data => { + console.log("Fetched gallery data:", data); + + const workflows = data.json || []; + + if (!Array.isArray(workflows)) { + console.error("The server did not return an array as expected.", data); + workflows = [workflows]; + } + + workflows.forEach(workflow => { + const meta = workflow.meta; + const title = meta.title; + const author = meta.author; + const time = meta.time; + const thumbnail = meta.thumbnail || generateThumbnailFromContent(meta); + createGridItem(title, container, thumbnail, author, time, false); + }); }) - .then(response => { - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - return response.json(); - }) - .then(data => { - console.log('Fetched gallery data:', data); - - const workflows = data.json || []; - - if (!Array.isArray(workflows)) { - console.error('The server did not return an array as expected.', data); - workflows = [workflows]; - } - - workflows.forEach(workflow => { - const meta = workflow.meta; - const title = meta.title; - const author = meta.author; - const time = meta.time; - const thumbnail = meta.thumbnail || generateThumbnailFromContent(meta); - createGridItem(title, container, thumbnail, author, time, false); - }); - }) - .catch(error => { - console.error('Error fetching gallery workflows:', error); - alert('Failed to load gallery workflows.'); - }); + .catch(error => { + console.error("Error fetching gallery workflows:", error); + alert("Failed to load gallery workflows."); + }); } function showLoadWorkflowList(tabId) { - fetch('/list-workflows', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({}) + fetch("/list-workflows", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({}) + }) + .then(response => response.json()) + .then(data => { + if (!Array.isArray(data.files)) { + throw new TypeError("The return data is not an array"); + } + + const container = document.getElementById(tabId).querySelector(".grid-container"); + container.innerHTML = ""; + + data.files.forEach(workflowName => { + const title = workflowName.replace(/\.json$/, ""); + const thumbnail = generateThumbnailFromContent({ title }); + createGridItem(title, container, thumbnail, "", "", true); + }); }) - .then(response => response.json()) - .then(data => { - if (!Array.isArray(data.files)) { - throw new TypeError('The return data is not an array'); - } - - const container = document.getElementById(tabId).querySelector('.grid-container'); - container.innerHTML = ''; - - data.files.forEach(workflowName => { - const title = workflowName.replace(/\.json$/, ''); - const thumbnail = generateThumbnailFromContent({ title }); - createGridItem(title, container, thumbnail, '', '', true); - }); - }) - .catch(error => { - console.error('Error fetching workflow list:', error); - alert('Fetch workflow list error.'); - }); + .catch(error => { + console.error("Error fetching workflow list:", error); + alert("Fetch workflow list error."); + }); } function generateThumbnailFromContent(content) { - const canvas = document.createElement('canvas'); - canvas.width = 150; - canvas.height = 150; - const ctx = canvas.getContext('2d'); + const canvas = document.createElement("canvas"); + canvas.width = 150; + canvas.height = 150; + const ctx = canvas.getContext("2d"); - ctx.fillStyle = '#f0f0f0'; - ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "#f0f0f0"; + ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.font = 'italic bold 14px "Helvetica Neue", sans-serif'; - ctx.textAlign = 'center'; - ctx.fillStyle = '#333'; + ctx.font = "italic bold 14px \"Helvetica Neue\", sans-serif"; + ctx.textAlign = "center"; + ctx.fillStyle = "#333"; - ctx.fillText(content.title, canvas.width / 2, canvas.height / 2 + 20); + ctx.fillText(content.title, canvas.width / 2, canvas.height / 2 + 20); - return canvas.toDataURL(); + return canvas.toDataURL(); } diff --git a/src/agentscope/studio/static/js/index.js b/src/agentscope/studio/static/js/index.js index 6202a7b8c..b318f79f8 100644 --- a/src/agentscope/studio/static/js/index.js +++ b/src/agentscope/studio/static/js/index.js @@ -3,7 +3,7 @@ const workstationTabBtn = document.getElementById("workstation-tab-btn"); const marketTabBtn = document.getElementById("market-tab-btn"); const serverTabBtn = document.getElementById("server-tab-btn"); const navigationBar = document.getElementById("navigation-bar"); -const suspendedBallDom = document.querySelector('.navbar') +const suspendedBallDom = document.querySelector(".navbar"); let currentPageUrl = null; let inGuidePage = true; // When navigation bar collapsed, only when the mouse leaves the navigation bar, then navigation bar will be able to be expanded @@ -11,312 +11,320 @@ let activeExpanded = false; // Check if the script is already loaded function isScriptLoaded(src) { - if(src == 'static/js/gallery.js')return; - let curURL = new URL(src, window.location.href).pathname; - return Array.from(document.scripts).some((script) => { - try { - let existURL = new URL(script.src).pathname; - return existURL === curURL; - } catch (error) { - console.warn( - "Error occurred when checking if the script is loaded: ", - error - ); - return false; - } - }); + if (src == "static/js/gallery.js") { + return; + } + const curURL = new URL(src, window.location.href).pathname; + return Array.from(document.scripts).some((script) => { + try { + const existURL = new URL(script.src).pathname; + return existURL === curURL; + } catch (error) { + console.warn( + "Error occurred when checking if the script is loaded: ", + error + ); + return false; + } + }); } // After loading different pages, we need to call the initialization function of this page function initializeTabPageByUrl(pageUrl) { - switch (pageUrl) { - case "static/html/dashboard.html": - initializeDashboardPage(); - break; - case "static/html/workstation_iframe.html": - let script = document.createElement("script"); - script.src = "static/js/workstation_iframe.js"; - document.head.appendChild(script); - break; - case "static/html/server.html": - initializeServerPage(); - break; - } + switch (pageUrl) { + case "static/html/dashboard.html": + initializeDashboardPage(); + break; + case "static/html/workstation_iframe.html": + const script = document.createElement("script"); + script.src = "static/js/workstation_iframe.js"; + document.head.appendChild(script); + break; + case "static/html/server.html": + initializeServerPage(); + break; + } } // Loading different pages in index.html function loadTabPage(pageUrl, javascriptUrl) { - fetch(pageUrl) - .then((response) => { - if (!response.ok) { - throw new Error("Connection error, cannot load the web page."); - } - return response.text(); - }) - .then((html) => { - currentPageUrl = pageUrl; - - // Hide the sidebar for other pages except the guide page - if (pageUrl === "static/html/index-guide.html") { - navigationBar.classList.remove("collapsed"); - inGuidePage = true; - } else { - navigationBar.classList.add("collapsed"); - inGuidePage = false; - activeExpanded = false; - } - - // Load the page content - document.getElementById("content").innerHTML = html; - - if(!localStorage.getItem('currentLanguage')){ - localStorage.setItem('currentLanguage', 'en'); - } - // Load the javascript file - if (javascriptUrl && !isScriptLoaded(javascriptUrl)) { - let script = document.createElement("script"); - script.src = javascriptUrl; - script.onload = function () { - // The first time we must initialize the page within the onload function to ensure the script is loaded - initializeTabPageByUrl(pageUrl); - }; - document.head.appendChild(script); - } else { - console.log("Script already loaded for " + javascriptUrl); - // If is not the first time, we can directly call the initialization function - initializeTabPageByUrl(pageUrl); - } - - // switch selected status of the tab buttons - switch (pageUrl) { - case "static/html/dashboard.html": - dashboardTabBtn.classList.add("selected"); - workstationTabBtn.classList.remove("selected"); - marketTabBtn.classList.remove("selected"); - serverTabBtn.classList.remove("selected"); - break; - - case "static/html/workstation_iframe.html": - dashboardTabBtn.classList.remove("selected"); - workstationTabBtn.classList.add("selected"); - marketTabBtn.classList.remove("selected"); - serverTabBtn.classList.remove("selected"); - break; - - case "static/html/gallery.html": - dashboardTabBtn.classList.remove("selected"); - workstationTabBtn.classList.remove("selected"); - marketTabBtn.classList.add("selected"); - serverTabBtn.classList.remove("selected"); - break; - - case "static/html/server.html": - dashboardTabBtn.classList.remove("selected"); - workstationTabBtn.classList.remove("selected"); - marketTabBtn.classList.remove("selected"); - serverTabBtn.classList.add("selected"); - break; - } - }) - .catch((error) => { - console.error("Error encountered while loading page: ", error); - document.getElementById("content").innerHTML = + fetch(pageUrl) + .then((response) => { + if (!response.ok) { + throw new Error("Connection error, cannot load the web page."); + } + return response.text(); + }) + .then((html) => { + currentPageUrl = pageUrl; + + // Hide the sidebar for other pages except the guide page + if (pageUrl === "static/html/index-guide.html") { + navigationBar.classList.remove("collapsed"); + inGuidePage = true; + } else { + navigationBar.classList.add("collapsed"); + inGuidePage = false; + activeExpanded = false; + } + + // Load the page content + document.getElementById("content").innerHTML = html; + + if (!localStorage.getItem("currentLanguage")) { + localStorage.setItem("currentLanguage", "en"); + } + // Load the javascript file + if (javascriptUrl && !isScriptLoaded(javascriptUrl)) { + const script = document.createElement("script"); + script.src = javascriptUrl; + script.onload = function () { + // The first time we must initialize the page within the onload function to ensure the script is loaded + initializeTabPageByUrl(pageUrl); + }; + document.head.appendChild(script); + } else { + console.log("Script already loaded for " + javascriptUrl); + // If is not the first time, we can directly call the initialization function + initializeTabPageByUrl(pageUrl); + } + + // switch selected status of the tab buttons + switch (pageUrl) { + case "static/html/dashboard.html": + dashboardTabBtn.classList.add("selected"); + workstationTabBtn.classList.remove("selected"); + marketTabBtn.classList.remove("selected"); + serverTabBtn.classList.remove("selected"); + break; + + case "static/html/workstation_iframe.html": + dashboardTabBtn.classList.remove("selected"); + workstationTabBtn.classList.add("selected"); + marketTabBtn.classList.remove("selected"); + serverTabBtn.classList.remove("selected"); + break; + + case "static/html/gallery.html": + dashboardTabBtn.classList.remove("selected"); + workstationTabBtn.classList.remove("selected"); + marketTabBtn.classList.add("selected"); + serverTabBtn.classList.remove("selected"); + break; + + case "static/html/server.html": + dashboardTabBtn.classList.remove("selected"); + workstationTabBtn.classList.remove("selected"); + marketTabBtn.classList.remove("selected"); + serverTabBtn.classList.add("selected"); + break; + } + }) + .catch((error) => { + console.error("Error encountered while loading page: ", error); + document.getElementById("content").innerHTML = "

    Loading failed.

    " + error; - }); + }); } loadTabPage("static/html/index-guide.html", null); document.addEventListener("DOMContentLoaded", function () { - const urlParams = new URLSearchParams(window.location.search); - if (urlParams.has("run_id")) { - loadTabPage("static/html/dashboard.html", "static/js/dashboard.js"); - } + const urlParams = new URLSearchParams(window.location.search); + if (urlParams.has("run_id")) { + loadTabPage("static/html/dashboard.html", "static/js/dashboard.js"); + } }); navigationBar.addEventListener("mouseenter", function () { - if (activeExpanded) { - navigationBar.classList.remove("collapsed"); - } + if (activeExpanded) { + navigationBar.classList.remove("collapsed"); + } }); navigationBar.addEventListener("mouseleave", function () { - // In guide page, the navigation bar will not be collapsed - if (!inGuidePage) { - // Collapse the navigation bar when the mouse leaves the navigation bar - navigationBar.classList.add("collapsed"); - // Allow the navigation bar to be expanded when the mouse leaves the navigation bar to avoid expanding right after collapsing (when not finished collapsing yet) - activeExpanded = true; - } + // In guide page, the navigation bar will not be collapsed + if (!inGuidePage) { + // Collapse the navigation bar when the mouse leaves the navigation bar + navigationBar.classList.add("collapsed"); + // Allow the navigation bar to be expanded when the mouse leaves the navigation bar to avoid expanding right after collapsing (when not finished collapsing yet) + activeExpanded = true; + } }); class SuspensionBall { - constructor(dom,callback = null) { - this.callback = callback; - this.startEvt = ''; - this.moveEvt = ''; - this.endEvt = ''; - this.drag = dom; - this.isClick = true; - this.disX = 0; - this.disY = 0; - this.left = 0; - this.top = 0; - this.starX = 0; - this.starY = 0; - } + constructor(dom, callback = null) { + this.callback = callback; + this.startEvt = ""; + this.moveEvt = ""; + this.endEvt = ""; + this.drag = dom; + this.isClick = true; + this.disX = 0; + this.disY = 0; + this.left = 0; + this.top = 0; + this.starX = 0; + this.starY = 0; - init() { - this.initEvent(); - } + // 绑定 this + this.startFun = this.startFun.bind(this); + this.moveFun = this.moveFun.bind(this); + this.endFun = this.endFun.bind(this); + } - initEvent() { - if ('ontouchstart' in window) { - this.startEvt = 'touchstart'; - this.moveEvt = 'touchmove'; - this.endEvt = 'touchend'; - } else { - this.startEvt = 'mousedown'; - this.moveEvt = 'mousemove'; - this.endEvt = 'mouseup'; - } - this.drag.addEventListener(this.startEvt, this.startFun); - } + init() { + this.initEvent(); + } - startFun = (e) => { - e.preventDefault(); - e = e || window.event; - this.isClick = true; - this.starX = e.touches ? e.touches[0].clientX : e.clientX; - this.starY = e.touches ? e.touches[0].clientY : e.clientY; - this.disX = this.starX - this.drag?.offsetLeft; - this.disY = this.starY - this.drag?.offsetTop; - document.addEventListener(this.moveEvt, this.moveFun); - document.addEventListener(this.endEvt, this.endFun); + initEvent() { + if ("ontouchstart" in window) { + this.startEvt = "touchstart"; + this.moveEvt = "touchmove"; + this.endEvt = "touchend"; + } else { + this.startEvt = "mousedown"; + this.moveEvt = "mousemove"; + this.endEvt = "mouseup"; } + this.drag.addEventListener(this.startEvt, this.startFun); + } - moveFun = (e) => { - e.preventDefault(); - e = e || window.event; - if ( - Math.abs(this.starX - (e.touches ? e.touches[0].clientX : e.clientX)) > 20 || - Math.abs(this.starY - (e.touches ? e.touches[0].clientY : e.clientY)) > 20 - ) { - this.isClick = false; - } - this.left = (e.touches ? e.touches[0].clientX : e.clientX) - this.disX; - this.top = (e.touches ? e.touches[0].clientY : e.clientY) - this.disY; - if (this.left < 0) { - this.left = 0; - } else if (this.left > document.documentElement.clientWidth - this.drag.offsetWidth) { - this.left = document.documentElement.clientWidth - this.drag.offsetWidth; - } - if (this.top < 0) { - this.top = 0; - } else if (this.top > document.documentElement.clientHeight - this.drag.offsetHeight) { - this.top = document.documentElement.clientHeight - this.drag.offsetHeight; - } - this.drag.style.left = this.left + 'px'; - this.drag.style.top = this.top + 'px'; - } + startFun(e) { + e.preventDefault(); + e = e || window.event; + this.isClick = true; + this.starX = e.touches ? e.touches[0].clientX : e.clientX; + this.starY = e.touches ? e.touches[0].clientY : e.clientY; + this.disX = this.starX - this.drag?.offsetLeft; + this.disY = this.starY - this.drag?.offsetTop; + document.addEventListener(this.moveEvt, this.moveFun); + document.addEventListener(this.endEvt, this.endFun); + } - endFun = (e)=> { - document.removeEventListener(this.moveEvt, this.moveFun); - document.removeEventListener(this.endEvt, this.endFun); - if (this.isClick && this.callback) { // 点击 - this.callback() - } + moveFun(e) { + e.preventDefault(); + e = e || window.event; + if ( + Math.abs(this.starX - (e.touches ? e.touches[0].clientX : e.clientX)) > 20 || + Math.abs(this.starY - (e.touches ? e.touches[0].clientY : e.clientY)) > 20 + ) { + this.isClick = false; + } + this.left = (e.touches ? e.touches[0].clientX : e.clientX) - this.disX; + this.top = (e.touches ? e.touches[0].clientY : e.clientY) - this.disY; + if (this.left < 0) { + this.left = 0; + } else if (this.left > document.documentElement.clientWidth - this.drag.offsetWidth) { + this.left = document.documentElement.clientWidth - this.drag.offsetWidth; + } + if (this.top < 0) { + this.top = 0; + } else if (this.top > document.documentElement.clientHeight - this.drag.offsetHeight) { + this.top = document.documentElement.clientHeight - this.drag.offsetHeight; } - removeDrag = () => { - this.drag.remove(); + this.drag.style.left = this.left + "px"; + this.drag.style.top = this.top + "px"; + } + + endFun(e) { + document.removeEventListener(this.moveEvt, this.moveFun); + document.removeEventListener(this.endEvt, this.endFun); + if (this.isClick && this.callback) { // 点击 + this.callback(); } } + removeDrag() { + this.drag.remove(); + } +} + const suspensionBall = new SuspensionBall(suspendedBallDom); suspensionBall.init(); const observer = new MutationObserver((mutations) => { - mutations.forEach((mutation) => { - if (mutation.type === 'childList') { - debounceFun(); - } - }); + mutations.forEach((mutation) => { + if (mutation.type === "childList") { + debounceFun(); + } + }); }); observer.observe(document.body, { - childList: true, - subtree: true, + childList: true, + subtree: true, }); const debounceFun = debounce(function refreshI18n() { - let currentLang = getCookie('locale') || 'en'; - observer.disconnect(); - $("[i18n]").i18n({ - defaultLang: currentLang, - filePath: "../static/i18n/", - filePrefix: "i18n_", - fileSuffix: "", - forever: true, - callback: function() { - observer.observe(document.body, { - childList: true, - subtree: true, - }); - } - }); -},100) - -document.addEventListener('DOMContentLoaded', function() { - let currentLang = getCookie('locale') || 'en'; - switch (currentLang){ - case 'en': - document.getElementById('translate').innerText = 'en' - break; - case 'zh': - document.getElementById('translate').innerText = '中' - break; + const currentLang = getCookie("locale") || "en"; + observer.disconnect(); + $("[i18n]").i18n({ + defaultLang: currentLang, + filePath: "../static/i18n/", + filePrefix: "i18n_", + fileSuffix: "", + forever: true, + callback: function () { + observer.observe(document.body, { + childList: true, + subtree: true, + }); } + }); +}, 100); + +document.addEventListener("DOMContentLoaded", function () { + const currentLang = getCookie("locale") || "en"; + switch (currentLang) { + case "en": + document.getElementById("translate").innerText = "en"; + break; + case "zh": + document.getElementById("translate").innerText = "中"; + break; + } }); -function changeLanguage(){ - let currentLang = getCookie('locale') || 'en'; - switch (currentLang){ - case 'en': - document.getElementById('translate').innerText = '中' - localStorage.setItem('locale', 'zh'); - setCookie('locale', 'zh'); - break; - case 'zh': - document.getElementById('translate').innerText = 'en' - localStorage.setItem('locale', 'en'); - setCookie('locale', 'en'); - break; - } +function changeLanguage() { + const currentLang = getCookie("locale") || "en"; + switch (currentLang) { + case "en": + document.getElementById("translate").innerText = "中"; + localStorage.setItem("locale", "zh"); + setCookie("locale", "zh"); + break; + case "zh": + document.getElementById("translate").innerText = "en"; + localStorage.setItem("locale", "en"); + setCookie("locale", "en"); + break; + } } function debounce(func, delay) { - let timeout; + let timeout; - return function(...args) { - clearTimeout(timeout); - timeout = setTimeout(() => func(...args), delay); - }; + return function (...args) { + clearTimeout(timeout); + timeout = setTimeout(() => func(...args), delay); + }; } function getCookie(name) { - var matches = document.cookie.match(new RegExp( - "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)" - )); - return matches ? decodeURIComponent(matches[1]) : undefined; + const matches = document.cookie.match(new RegExp( + "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, "\\$1") + "=([^;]*)" + )); + return matches ? decodeURIComponent(matches[1]) : undefined; } function setCookie(name, value, days) { - var expires = ""; - if (days) { - var date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = "; expires=" + date.toUTCString(); - } - document.cookie = name + "=" + (value || "") + expires + "; path=/"; + let expires = ""; + if (days) { + const date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = "; expires=" + date.toUTCString(); + } + document.cookie = name + "=" + (value || "") + expires + "; path=/"; } \ No newline at end of file diff --git a/src/agentscope/studio/static/js/server.js b/src/agentscope/studio/static/js/server.js index bdf1ede12..16e3288fd 100644 --- a/src/agentscope/studio/static/js/server.js +++ b/src/agentscope/studio/static/js/server.js @@ -8,485 +8,485 @@ var messageEditor; // Sever table functions function deleteServer(row) { - fetch("/api/servers/delete", { - method: "POST", - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - body: JSON.stringify({ - server_id: row.getData().id, - stop: row.getData().status == "running", - }), + fetch("/api/servers/delete", { + method: "POST", + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + body: JSON.stringify({ + server_id: row.getData().id, + stop: row.getData().status == "running", + }), + }) + .then((response) => { + if (!response.ok) { + throw new Error("Failed to delete server"); + } + return response.json(); }) - .then((response) => { - if (!response.ok) { - throw new Error("Failed to delete server"); - } - return response.json(); - }) - .then((data) => { - row.delete(); - }); + .then((data) => { + row.delete(); + }); } function deleteServerBtn(e, cell) { - const serverId = cell.getData().id; - if (confirm(`Are you sure to stop server ${serverId} ?`)) { - deleteServer(cell.getRow()); - } + const serverId = cell.getData().id; + if (confirm(`Are you sure to stop server ${serverId} ?`)) { + deleteServer(cell.getRow()); + } } function newServer() { - console.log("new Server"); + console.log("new Server"); } function flushServerTable(data) { - if (serversTable) { - serversTable.setData(data); - console.log("Flush Server Table"); - } else { - console.error("Server Table is not initialized."); - } + if (serversTable) { + serversTable.setData(data); + console.log("Flush Server Table"); + } else { + console.error("Server Table is not initialized."); + } } function deleteDeadServer() { - let deadServerIds = []; - if (serversTable) { - let rows = serversTable.getRows(); - for (let i = 0; i < rows.length; i++) { - let row = rows[i]; - if (row.getData().status == "dead") { - deadServerIds.push(row.getData().id); - deleteServer(row); - } - } - } else { - console.error("Server Table is not initialized."); + const deadServerIds = []; + if (serversTable) { + const rows = serversTable.getRows(); + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + if (row.getData().status == "dead") { + deadServerIds.push(row.getData().id); + deleteServer(row); + } } - console.log("Delete dead servers: ", deadServerIds); - return deadServerIds; + } else { + console.error("Server Table is not initialized."); + } + console.log("Delete dead servers: ", deadServerIds); + return deadServerIds; } function deleteIcon(cell, formatterParams, onRendered) { - return ''; + return ""; } function getServerStatus(cell, formatterParams, onRendered) { - cell.getElement().innerHTML = - '
    loading
    '; + cell.getElement().innerHTML = + "
    loading
    "; - const serverId = cell.getRow().getData().id; + const serverId = cell.getRow().getData().id; - fetch(`/api/servers/status/${serverId}`) - .then((response) => { - if (!response.ok) { - throw new Error("Failed to get server status"); - } - return response.json(); - }) - .then((data) => { - let row = cell.getRow(); - if (data.status == "running") { - cell.getElement().innerHTML = - '
    running
    '; - row.update({ - status: data.status, - cpu: data.cpu, - mem: data.mem, - size: data.size, - }); - } else { - cell.getElement().innerHTML = - '
    dead
    '; - row.update({ - status: "dead", - }); - } - }) - .catch((error) => { - console.error("Error fetching server status:", error); - cell.getElement().innerHTML = - '
    unknown
    '; + fetch(`/api/servers/status/${serverId}`) + .then((response) => { + if (!response.ok) { + throw new Error("Failed to get server status"); + } + return response.json(); + }) + .then((data) => { + const row = cell.getRow(); + if (data.status == "running") { + cell.getElement().innerHTML = + "
    running
    "; + row.update({ + status: data.status, + cpu: data.cpu, + mem: data.mem, + size: data.size, + }); + } else { + cell.getElement().innerHTML = + "
    dead
    "; + row.update({ + status: "dead", }); + } + }) + .catch((error) => { + console.error("Error fetching server status:", error); + cell.getElement().innerHTML = + "
    unknown
    "; + }); } function cpuUsage(cell, formatterParams, onRendered) { - const cpu = cell.getData().cpu; - if (!cpu && cpu !== 0) { - return '
    unknown
    '; - } else { - return `
    ${cell.getData().cpu} %
    `; - } + const cpu = cell.getData().cpu; + if (!cpu && cpu !== 0) { + return "
    unknown
    "; + } else { + return `
    ${cell.getData().cpu} %
    `; + } } function memoryUsage(cell, formatterParams, onRendered) { - if (cell.getData().mem) { - return `
    ${cell - .getData() - .mem.toFixed(2)} MB
    `; - } else { - return '
    unknown
    '; - } + if (cell.getData().mem) { + return `
    ${cell + .getData() + .mem.toFixed(2)} MB
    `; + } else { + return "
    unknown
    "; + } } function getServerTableData(callback) { - fetch("/api/servers/all") - .then((response) => { - if (!response.ok) { - throw new Error("Failed to fetch servers data"); - } - return response.json(); - }) - .then((data) => { - callback(data); - }); + fetch("/api/servers/all") + .then((response) => { + if (!response.ok) { + throw new Error("Failed to fetch servers data"); + } + return response.json(); + }) + .then((data) => { + callback(data); + }); } function initServerTable(data) { - serversTable = new Tabulator("#server-table", { - data: data, - columns: [ - { - title: "", - field: "status", - vertAlign: "middle", - visible: false, - }, - { - title: "ID", - field: "id", - vertAlign: "middle", - }, - { - title: "Host", - field: "host", - vertAlign: "middle", - }, - { - title: "Port", - field: "port", - vertAlign: "middle", - }, - { - title: "Created Time", - field: "create_time", - vertAlign: "middle", - }, - { - title: "Status", - vertAlign: "middle", - formatter: getServerStatus, - }, - { - title: "Agent Number", - field: "size", - vertAlign: "middle", - }, - { - title: "CPU Usage", - field: "cpu", - vertAlign: "middle", - formatter: cpuUsage, - }, - { - title: "Memory Usage", - field: "mem", - vertAlign: "middle", - formatter: memoryUsage, - }, - { - title: "Delete", - formatter: deleteIcon, - width: 75, - vertAlign: "middle", - cellClick: deleteServerBtn, - }, - ], - layout: "fitColumns", - }); - serversTable.on("rowClick", function (e, row) { - if (row.getData().status != "running") { - return; - } - if (e.target.classList.contains("cell-btn")) { - return; - } - loadAgentDetails(row.getData()); - }); + serversTable = new Tabulator("#server-table", { + data: data, + columns: [ + { + title: "", + field: "status", + vertAlign: "middle", + visible: false, + }, + { + title: "ID", + field: "id", + vertAlign: "middle", + }, + { + title: "Host", + field: "host", + vertAlign: "middle", + }, + { + title: "Port", + field: "port", + vertAlign: "middle", + }, + { + title: "Created Time", + field: "create_time", + vertAlign: "middle", + }, + { + title: "Status", + vertAlign: "middle", + formatter: getServerStatus, + }, + { + title: "Agent Number", + field: "size", + vertAlign: "middle", + }, + { + title: "CPU Usage", + field: "cpu", + vertAlign: "middle", + formatter: cpuUsage, + }, + { + title: "Memory Usage", + field: "mem", + vertAlign: "middle", + formatter: memoryUsage, + }, + { + title: "Delete", + formatter: deleteIcon, + width: 75, + vertAlign: "middle", + cellClick: deleteServerBtn, + }, + ], + layout: "fitColumns", + }); + serversTable.on("rowClick", function (e, row) { + if (row.getData().status != "running") { + return; + } + if (e.target.classList.contains("cell-btn")) { + return; + } + loadAgentDetails(row.getData()); + }); } // Agent table functions function getAgentTableData(serverId, callback) { - fetch(`/api/servers/agent_info/${serverId}`) - .then((response) => { - if (!response.ok) { - throw new Error("Failed to fetch agents data"); - } - return response.json(); - }) - .then((data) => { - callback(serverId, data); - }); + fetch(`/api/servers/agent_info/${serverId}`) + .then((response) => { + if (!response.ok) { + throw new Error("Failed to fetch agents data"); + } + return response.json(); + }) + .then((data) => { + callback(serverId, data); + }); } function flushAgentTable(serverId, data) { - if (agentsTable) { - agentsTable.setData(data); - console.log("Flush Agent Table"); - } else { - console.error("Agent Table is not initialized."); - } + if (agentsTable) { + agentsTable.setData(data); + console.log("Flush Agent Table"); + } else { + console.error("Agent Table is not initialized."); + } } function deleteAllAgent() { - let serverId = curServerId; - if (agentsTable) { - if (confirm(`Are you sure to delete all agent on ${serverId} ?`)) { - fetch(`/api/servers/agents/delete`, { - method: "POST", - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - body: JSON.stringify({ - server_id: serverId, - }), - }) - .then((response) => { - return response.json(); - }) - .then((data) => { - agentsTable.clearData(); - }) - .catch((error) => { - console.error("Error when deleting all agent:", error); - }); - } - } else { - console.error("Agent Table is not initialized."); + const serverId = curServerId; + if (agentsTable) { + if (confirm(`Are you sure to delete all agent on ${serverId} ?`)) { + fetch("/api/servers/agents/delete", { + method: "POST", + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + body: JSON.stringify({ + server_id: serverId, + }), + }) + .then((response) => { + return response.json(); + }) + .then((data) => { + agentsTable.clearData(); + }) + .catch((error) => { + console.error("Error when deleting all agent:", error); + }); } + } else { + console.error("Agent Table is not initialized."); + } } function initAgentTable(serverId, data) { - curServerId = serverId; - agentsTable = new Tabulator("#agent-table", { - data: data, - columns: [ - { - title: "ID", - field: "agent_id", - vertAlign: "middle", - }, - { - title: "Name", - field: "name", - vertAlign: "middle", - }, - { - title: "Class", - field: "type", - vertAlign: "middle", - }, - { - title: "System prompt", - field: "sys_prompt", - vertAlign: "middle", - }, - { - title: "Model", - field: "model", - vertAlign: "middle", - formatter: function (cell, formatterParams, onRendered) { - if (cell.getData().model == null) { - return `
    None
    `; - } - return `
    [${ - cell.getData().model.model_type - }]: ${cell.getData().model.config_name}
    `; - }, - }, - { - title: "Delete", - formatter: deleteIcon, - width: 75, - hozAlign: "center", - vertAlign: "middle", - cellClick: function (e, cell) { - if ( - confirm( - `Are you sure to delete agent ${ - cell.getData().id - } ?` - ) - ) { - fetch(`/api/servers/agents/delete`, { - method: "POST", - headers: { - "Content-Type": + curServerId = serverId; + agentsTable = new Tabulator("#agent-table", { + data: data, + columns: [ + { + title: "ID", + field: "agent_id", + vertAlign: "middle", + }, + { + title: "Name", + field: "name", + vertAlign: "middle", + }, + { + title: "Class", + field: "type", + vertAlign: "middle", + }, + { + title: "System prompt", + field: "sys_prompt", + vertAlign: "middle", + }, + { + title: "Model", + field: "model", + vertAlign: "middle", + formatter: function (cell, formatterParams, onRendered) { + if (cell.getData().model == null) { + return "
    None
    "; + } + return `
    [${ + cell.getData().model.model_type + }]: ${cell.getData().model.config_name}
    `; + }, + }, + { + title: "Delete", + formatter: deleteIcon, + width: 75, + hozAlign: "center", + vertAlign: "middle", + cellClick: function (e, cell) { + if ( + confirm( + `Are you sure to delete agent ${ + cell.getData().id + } ?` + ) + ) { + fetch("/api/servers/agents/delete", { + method: "POST", + headers: { + "Content-Type": "application/json; charset=utf-8", - }, - body: JSON.stringify({ - agent_id: cell.getData().agent_id, - server_id: serverId, - }), - }) - .then((response) => { - return response.json(); - }) - .then((data) => { - cell.getRow().delete(); - }) - .catch((error) => { - console.error( - "Error when deleting agent:", - error - ); - }); - } - }, - }, - ], - layout: "fitColumns", - }); - agentsTable.on("rowClick", function (e, row) { - if (e.target.classList.contains("cell-btn")) { - return; - } - loadAgentMemory(serverId, row.getData().agent_id, row.getData().name); - }); + }, + body: JSON.stringify({ + agent_id: cell.getData().agent_id, + server_id: serverId, + }), + }) + .then((response) => { + return response.json(); + }) + .then((data) => { + cell.getRow().delete(); + }) + .catch((error) => { + console.error( + "Error when deleting agent:", + error + ); + }); + } + }, + }, + ], + layout: "fitColumns", + }); + agentsTable.on("rowClick", function (e, row) { + if (e.target.classList.contains("cell-btn")) { + return; + } + loadAgentMemory(serverId, row.getData().agent_id, row.getData().name); + }); } function loadAgentDetails(serverData) { - var serverDetail = document.getElementById("server-detail"); - var serverDetailTitle = serverDetail.querySelector(".server-section-title"); - serverDetailTitle.textContent = `Agents on (${serverData.host}:${serverData.port})[${serverData.id}]`; - serverDetail.classList.remove("collapsed"); - var agentMemory = document.getElementById("agent-memory"); - if (!agentMemory.classList.contains("collapsed")) { - agentMemory.classList.add("collapsed"); - } - getAgentTableData(serverData.id, initAgentTable); + const serverDetail = document.getElementById("server-detail"); + const serverDetailTitle = serverDetail.querySelector(".server-section-title"); + serverDetailTitle.textContent = `Agents on (${serverData.host}:${serverData.port})[${serverData.id}]`; + serverDetail.classList.remove("collapsed"); + const agentMemory = document.getElementById("agent-memory"); + if (!agentMemory.classList.contains("collapsed")) { + agentMemory.classList.add("collapsed"); + } + getAgentTableData(serverData.id, initAgentTable); } // agent memory functions function showMessage(message) { - if (messageEditor) { - messageEditor.setValue(JSON.stringify(message, null, 2)); - } else { - console.error("Message Editor is not initialized."); - } + if (messageEditor) { + messageEditor.setValue(JSON.stringify(message, null, 2)); + } else { + console.error("Message Editor is not initialized."); + } } function loadAgentMemory(serverId, agentId, agentName) { - var agentMemory = document.getElementById("agent-memory"); - var agentMemoryTitle = agentMemory.querySelector(".server-section-title"); - agentMemoryTitle.textContent = `Memory of (${agentName})[${agentId}]`; - agentMemory.classList.remove("collapsed"); - getAgentMemoryData(serverId, agentId, initAgentMemoryTable); + const agentMemory = document.getElementById("agent-memory"); + const agentMemoryTitle = agentMemory.querySelector(".server-section-title"); + agentMemoryTitle.textContent = `Memory of (${agentName})[${agentId}]`; + agentMemory.classList.remove("collapsed"); + getAgentMemoryData(serverId, agentId, initAgentMemoryTable); } function getAgentMemoryData(serverId, agentId, callback) { - fetch(`/api/servers/agents/memory`, { - method: "POST", - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - body: JSON.stringify({ - server_id: serverId, - agent_id: agentId, - }), + fetch("/api/servers/agents/memory", { + method: "POST", + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + body: JSON.stringify({ + server_id: serverId, + agent_id: agentId, + }), + }) + .then((response) => { + if (!response.ok) { + throw new Error("Failed to fetch agent memory data"); + } + return response.json(); }) - .then((response) => { - if (!response.ok) { - throw new Error("Failed to fetch agent memory data"); - } - return response.json(); - }) - .then((data) => { - // Update the agent memory table with the fetched data - callback(agentId, data); - }); + .then((data) => { + // Update the agent memory table with the fetched data + callback(agentId, data); + }); } function initAgentMemoryTable(agentId, memoryData) { - agentMemoryTable = new Tabulator("#agent-memory-table", { - data: memoryData, - columns: [ - { - title: "Name", - field: "name", - vertAlign: "middle", - }, - { - title: "Role", - field: "role", - vertAlign: "middle", - }, - ], - layout: "fitColumns", - }); - agentMemoryTable.on("rowClick", function (e, row) { - showMessage(row.getData()); - }); - require.config({ - paths: { - vs: "https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs", + agentMemoryTable = new Tabulator("#agent-memory-table", { + data: memoryData, + columns: [ + { + title: "Name", + field: "name", + vertAlign: "middle", + }, + { + title: "Role", + field: "role", + vertAlign: "middle", + }, + ], + layout: "fitColumns", + }); + agentMemoryTable.on("rowClick", function (e, row) { + showMessage(row.getData()); + }); + require.config({ + paths: { + vs: "https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs", + }, + }); + require(["vs/editor/editor.main"], function () { + if (messageEditor) { + messageEditor.dispose(); + messageEditor = null; + } + messageEditor = monaco.editor.create( + document.getElementById("agent-memory-raw"), + { + language: "json", + theme: "vs-light", + minimap: { + enabled: false, }, - }); - require(["vs/editor/editor.main"], function () { - if (messageEditor) { - messageEditor.dispose(); - messageEditor = null; - } - messageEditor = monaco.editor.create( - document.getElementById("agent-memory-raw"), - { - language: "json", - theme: "vs-light", - minimap: { - enabled: false, - }, - wordWrap: "on", - scrollBeyondLastLine: false, - readOnly: true, - } - ); - }); + wordWrap: "on", + scrollBeyondLastLine: false, + readOnly: true, + } + ); + }); } function flushAgentMemoryTable(agentId, data) { - if (agentMemoryTable) { - agentMemoryTable.setData(data); - console.log("Flush Agent Memory Table"); - } else { - console.error("Agent Memory Table is not initialized."); - } + if (agentMemoryTable) { + agentMemoryTable.setData(data); + console.log("Flush Agent Memory Table"); + } else { + console.error("Agent Memory Table is not initialized."); + } } // Initialize the server page with a table of servers function initializeServerPage() { - // init servers - console.log("init server manager script"); - getServerTableData(initServerTable); - let serverflushBtn = document.getElementById("flush-server-btn"); - serverflushBtn.onclick = function () { - getServerTableData(flushServerTable); - }; - let deleteDeadServerBtn = document.getElementById("delete-dead-server-btn"); - deleteDeadServerBtn.onclick = deleteDeadServer; - let agentflushBtn = document.getElementById("flush-agent-btn"); - agentflushBtn.onclick = function () { - let serverId = curServerId; - getAgentTableData(serverId, flushAgentTable); - }; - let deleteAllAgentBtn = document.getElementById("delete-all-agent-btn"); - deleteAllAgentBtn.onclick = deleteAllAgent; - let memoryflushBtn = document.getElementById("flush-memory-btn"); - memoryflushBtn.onclick = flushAgentMemoryTable; - window.addEventListener("resize", () => { - if (messageEditor) { - messageEditor.layout(); - } - }); + // init servers + console.log("init server manager script"); + getServerTableData(initServerTable); + const serverflushBtn = document.getElementById("flush-server-btn"); + serverflushBtn.onclick = function () { + getServerTableData(flushServerTable); + }; + const deleteDeadServerBtn = document.getElementById("delete-dead-server-btn"); + deleteDeadServerBtn.onclick = deleteDeadServer; + const agentflushBtn = document.getElementById("flush-agent-btn"); + agentflushBtn.onclick = function () { + const serverId = curServerId; + getAgentTableData(serverId, flushAgentTable); + }; + const deleteAllAgentBtn = document.getElementById("delete-all-agent-btn"); + deleteAllAgentBtn.onclick = deleteAllAgent; + const memoryflushBtn = document.getElementById("flush-memory-btn"); + memoryflushBtn.onclick = flushAgentMemoryTable; + window.addEventListener("resize", () => { + if (messageEditor) { + messageEditor.layout(); + } + }); } diff --git a/src/agentscope/studio/static/js/workstation.js b/src/agentscope/studio/static/js/workstation.js index 4995b63d0..32e6381db 100644 --- a/src/agentscope/studio/static/js/workstation.js +++ b/src/agentscope/studio/static/js/workstation.js @@ -11,3232 +11,3231 @@ let accumulatedImportData; let descriptionStep; -let nameToHtmlFile = { - 'welcome': 'welcome.html', - 'dashscope_chat': 'model-dashscope-chat.html', - 'openai_chat': 'model-openai-chat.html', - 'post_api_chat': 'model-post-api-chat.html', - 'post_api_dall_e': 'model-post-api-dall-e.html', - 'dashscope_image_synthesis': 'model-wanx.html', - 'Message': 'message-msg.html', - 'DialogAgent': 'agent-dialogagent.html', - 'UserAgent': 'agent-useragent.html', - 'TextToImageAgent': 'agent-texttoimageagent.html', - 'DictDialogAgent': 'agent-dictdialogagent.html', - 'ReActAgent': 'agent-reactagent.html', - 'Placeholder': 'pipeline-placeholder.html', - 'MsgHub': 'pipeline-msghub.html', - 'SequentialPipeline': 'pipeline-sequentialpipeline.html', - 'ForLoopPipeline': 'pipeline-forlooppipeline.html', - 'WhileLoopPipeline': 'pipeline-whilelooppipeline.html', - 'IfElsePipeline': 'pipeline-ifelsepipeline.html', - 'SwitchPipeline': 'pipeline-switchpipeline.html', - 'BingSearchService': 'service-bing-search.html', - 'GoogleSearchService': 'service-google-search.html', - 'PythonService': 'service-execute-python.html', - 'ReadTextService': 'service-read-text.html', - 'WriteTextService': 'service-write-text.html', - 'Post': 'tool-post.html', - 'TextToAudioService': 'service-text-to-audio.html', - 'TextToImageService': 'service-text-to-image.html', - 'ImageComposition': 'tool-image-composition.html', - 'Code': 'tool-code.html', - // 'IF/ELSE': 'tool-if-else.html', - 'ImageMotion': 'tool-image-motion.html', - 'VideoComposition': 'tool-video-composition.html', -} +const nameToHtmlFile = { + "welcome": "welcome.html", + "dashscope_chat": "model-dashscope-chat.html", + "openai_chat": "model-openai-chat.html", + "post_api_chat": "model-post-api-chat.html", + "post_api_dall_e": "model-post-api-dall-e.html", + "dashscope_image_synthesis": "model-wanx.html", + "Message": "message-msg.html", + "DialogAgent": "agent-dialogagent.html", + "UserAgent": "agent-useragent.html", + "TextToImageAgent": "agent-texttoimageagent.html", + "DictDialogAgent": "agent-dictdialogagent.html", + "ReActAgent": "agent-reactagent.html", + "Placeholder": "pipeline-placeholder.html", + "MsgHub": "pipeline-msghub.html", + "SequentialPipeline": "pipeline-sequentialpipeline.html", + "ForLoopPipeline": "pipeline-forlooppipeline.html", + "WhileLoopPipeline": "pipeline-whilelooppipeline.html", + "IfElsePipeline": "pipeline-ifelsepipeline.html", + "SwitchPipeline": "pipeline-switchpipeline.html", + "BingSearchService": "service-bing-search.html", + "GoogleSearchService": "service-google-search.html", + "PythonService": "service-execute-python.html", + "ReadTextService": "service-read-text.html", + "WriteTextService": "service-write-text.html", + "Post": "tool-post.html", + "TextToAudioService": "service-text-to-audio.html", + "TextToImageService": "service-text-to-image.html", + "ImageComposition": "tool-image-composition.html", + "Code": "tool-code.html", + // 'IF/ELSE': 'tool-if-else.html', + "ImageMotion": "tool-image-motion.html", + "VideoComposition": "tool-video-composition.html", +}; const ModelNames48k = [ - 'sambert-zhinan-v1', - "sambert-zhiqi-v1", - "sambert-zhichu-v1", - "sambert-zhide-v1", - "sambert-zhijia-v1", - "sambert-zhiru-v1", - "sambert-zhiqian-v1", - "sambert-zhixiang-v1", - "sambert-zhiwei-v1", -] + "sambert-zhinan-v1", + "sambert-zhiqi-v1", + "sambert-zhichu-v1", + "sambert-zhide-v1", + "sambert-zhijia-v1", + "sambert-zhiru-v1", + "sambert-zhiqian-v1", + "sambert-zhixiang-v1", + "sambert-zhiwei-v1", +]; // Cache the loaded html files -let htmlCache = {}; +const htmlCache = {}; // When clicking the sidebar item, it will expand/collapse the next content function onClickSidebarSubItem(element) { - element.classList.toggle("active"); - let content = element.nextElementSibling; - if (content.style.display === "block") { - content.style.display = "none"; - } else { - content.style.display = "block"; - } + element.classList.toggle("active"); + const content = element.nextElementSibling; + if (content.style.display === "block") { + content.style.display = "none"; + } else { + content.style.display = "block"; + } } // Load html source code dynamically async function fetchHtml(fileName) { - try { - let filePath = 'static/html-drag-components/' + fileName; - const response = await fetch(filePath); - if (!response.ok) { - throw new Error('Fail to load ' + filePath); - } - return await response.text(); - } catch (error) { - return error; + try { + const filePath = "static/html-drag-components/" + fileName; + const response = await fetch(filePath); + if (!response.ok) { + throw new Error("Fail to load " + filePath); } + return await response.text(); + } catch (error) { + return error; + } } async function initializeWorkstationPage() { - console.log("Initialize Workstation Page") - // Initialize the Drawflow editor - let id = document.getElementById("drawflow"); - editor = new Drawflow(id); - editor.reroute = true; - editor.createCurvature = function createCurvature(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value, type) { - var line_x = start_pos_x; - var line_y = start_pos_y; - var x = end_pos_x; - var y = end_pos_y; - var curvature = curvature_value; - //type openclose open close other - switch (type) { - case 'open': - if (start_pos_x >= end_pos_x) { - var hx1 = line_x + Math.abs(x - line_x) * curvature; - var hx2 = x - Math.abs(x - line_x) * (curvature * -1); - } else { - var hx1 = line_x + Math.abs(x - line_x) * curvature; - var hx2 = x - Math.abs(x - line_x) * curvature; - } - return ' M ' + line_x + ' ' + line_y + ' C ' + hx1 + ' ' + line_y + ' ' + hx2 + ' ' + y + ' ' + x + ' ' + y; - - case 'close': - if (start_pos_x >= end_pos_x) { - var hx1 = line_x + Math.abs(x - line_x) * (curvature * -1); - var hx2 = x - Math.abs(x - line_x) * curvature; - } else { - var hx1 = line_x + Math.abs(x - line_x) * curvature; - var hx2 = x - Math.abs(x - line_x) * curvature; - } //M0 75H10L5 80L0 75Z - return ' M ' + line_x + ' ' + line_y + ' C ' + hx1 + ' ' + line_y + ' ' + hx2 + ' ' + y + ' ' + x + ' ' + y + ' M ' + (x - 11) + ' ' + y + ' L' + (x - 20) + ' ' + (y - 5) + ' L' + (x - 20) + ' ' + (y + 5) + 'Z'; - - case 'other': - if (start_pos_x >= end_pos_x) { - var hx1 = line_x + Math.abs(x - line_x) * (curvature * -1); - var hx2 = x - Math.abs(x - line_x) * (curvature * -1); - } else { - var hx1 = line_x + Math.abs(x - line_x) * curvature; - var hx2 = x - Math.abs(x - line_x) * curvature; - } - return ' M ' + line_x + ' ' + line_y + ' C ' + hx1 + ' ' + line_y + ' ' + hx2 + ' ' + y + ' ' + x + ' ' + y; - - default: - var hx1 = line_x + Math.abs(x - line_x) * curvature; - var hx2 = x - Math.abs(x - line_x) * curvature; - - return ' M ' + line_x + ' ' + line_y + ' C ' + hx1 + ' ' + line_y + ' ' + hx2 + ' ' + y + ' ' + x + ' ' + y + ' M ' + (x - 11) + ' ' + y + ' L' + (x - 20) + ' ' + (y - 5) + ' L' + (x - 20) + ' ' + (y + 5) + 'Z'; - } - } - editor.start(); - editor.zoom_out(); - - let welcome = await fetchHtml('welcome.html'); - const welcomeID = editor.addNode('welcome', 0, 0, 50, 50, 'welcome', {}, welcome); - setupNodeListeners(welcomeID); - - editor.on('nodeCreated', function (id) { - console.log("Node created " + id); - disableButtons(); - makeNodeTop(id); - setupNodeListeners(id); - setupNodeCopyListens(id); - addEventListenersToNumberInputs(id); - setupTextInputListeners(id); - reloadi18n(); - }) - - editor.on('nodeRemoved', function (id) { - console.log("Node removed " + id); - disableButtons(); - Object.keys(editor.drawflow.drawflow[editor.module].data).forEach(nodeKey => { - var node = editor.drawflow.drawflow[editor.module].data[nodeKey]; - var nodeData = + console.log("Initialize Workstation Page"); + // Initialize the Drawflow editor + const id = document.getElementById("drawflow"); + editor = new Drawflow(id); + editor.reroute = true; + editor.createCurvature = function createCurvature(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value, type) { + const line_x = start_pos_x; + const line_y = start_pos_y; + const x = end_pos_x; + const y = end_pos_y; + const curvature = curvature_value; + //type openclose open close other + switch (type) { + case "open": + if (start_pos_x >= end_pos_x) { + var hx1 = line_x + Math.abs(x - line_x) * curvature; + var hx2 = x - Math.abs(x - line_x) * (curvature * -1); + } else { + var hx1 = line_x + Math.abs(x - line_x) * curvature; + var hx2 = x - Math.abs(x - line_x) * curvature; + } + return " M " + line_x + " " + line_y + " C " + hx1 + " " + line_y + " " + hx2 + " " + y + " " + x + " " + y; + + case "close": + if (start_pos_x >= end_pos_x) { + var hx1 = line_x + Math.abs(x - line_x) * (curvature * -1); + var hx2 = x - Math.abs(x - line_x) * curvature; + } else { + var hx1 = line_x + Math.abs(x - line_x) * curvature; + var hx2 = x - Math.abs(x - line_x) * curvature; + } //M0 75H10L5 80L0 75Z + return " M " + line_x + " " + line_y + " C " + hx1 + " " + line_y + " " + hx2 + " " + y + " " + x + " " + y + " M " + (x - 11) + " " + y + " L" + (x - 20) + " " + (y - 5) + " L" + (x - 20) + " " + (y + 5) + "Z"; + + case "other": + if (start_pos_x >= end_pos_x) { + var hx1 = line_x + Math.abs(x - line_x) * (curvature * -1); + var hx2 = x - Math.abs(x - line_x) * (curvature * -1); + } else { + var hx1 = line_x + Math.abs(x - line_x) * curvature; + var hx2 = x - Math.abs(x - line_x) * curvature; + } + return " M " + line_x + " " + line_y + " C " + hx1 + " " + line_y + " " + hx2 + " " + y + " " + x + " " + y; + + default: + var hx1 = line_x + Math.abs(x - line_x) * curvature; + var hx2 = x - Math.abs(x - line_x) * curvature; + + return " M " + line_x + " " + line_y + " C " + hx1 + " " + line_y + " " + hx2 + " " + y + " " + x + " " + y + " M " + (x - 11) + " " + y + " L" + (x - 20) + " " + (y - 5) + " L" + (x - 20) + " " + (y + 5) + "Z"; + } + }; + editor.start(); + editor.zoom_out(); + + const welcome = await fetchHtml("welcome.html"); + const welcomeID = editor.addNode("welcome", 0, 0, 50, 50, "welcome", {}, welcome); + setupNodeListeners(welcomeID); + + editor.on("nodeCreated", function (id) { + console.log("Node created " + id); + disableButtons(); + makeNodeTop(id); + setupNodeListeners(id); + setupNodeCopyListens(id); + addEventListenersToNumberInputs(id); + setupTextInputListeners(id); + reloadi18n(); + }); + + editor.on("nodeRemoved", function (id) { + console.log("Node removed " + id); + disableButtons(); + Object.keys(editor.drawflow.drawflow[editor.module].data).forEach(nodeKey => { + const node = editor.drawflow.drawflow[editor.module].data[nodeKey]; + const nodeData = editor.drawflow.drawflow[editor.module].data[nodeKey].data; - console.log("nodeKey", nodeKey); - console.log("node", node); - console.log("nodeData", nodeData); - console.log("id", id); - - if (nodeData && nodeData.copies) { - console.log("Array.isArray(nodeData.copies)", Array.isArray(nodeData.copies)) - if (nodeData.copies.includes(id)) { - console.log("nodeData.copies", nodeData.copies); - console.log("nodeData.copies.includes(id)", - nodeData.copies.includes(id)); - var index = nodeData.copies.indexOf(id); - console.log("index", index); - if (index > -1) { - nodeData.copies.splice(index, 1); - editor.updateNodeDataFromId(nodeKey, nodeData); - } - } - } - }) - }) - - editor.on('nodeSelected', function (id) { - console.log("Node selected " + id); - makeNodeTop(id); - }) - - editor.on('moduleCreated', function (name) { - console.log("Module Created " + name); - }) - - editor.on('moduleChanged', function (name) { - console.log("Module Changed " + name); - }) - - editor.on('connectionCreated', function (connection) { - console.log('Connection created'); - console.log(connection); - disableButtons(); - }) - - editor.on('connectionRemoved', function (connection) { - console.log('Connection removed'); - console.log(connection); - disableButtons(); - }) - - editor.on('mouseMove', function (position) { - // console.log('Position mouse x:' + position.x + ' y:' + position.y); - }) - - editor.on('zoom', function (zoom) { - console.log('Zoom level ' + zoom); - }) - - editor.on('translate', function (position) { - console.log('Translate x:' + position.x + ' y:' + position.y); - }) - - editor.on('addReroute', function (id) { - console.log("Reroute added " + id); - }) - - editor.on('removeReroute', function (id) { - console.log("Reroute removed " + id); - }) - - editor.selectNode = function (id) { - if (this.node_selected != null) { - this.node_selected.classList.remove("selected"); - if (this.node_selected !== this.ele_selected) { - this.dispatch('nodeUnselected', true); - } - } - const element = document.querySelector(`#node-${id}`); - this.ele_selected = element; - this.node_selected = element; - this.node_selected.classList.add("selected"); - if (this.node_selected !== this.ele_selected) { - this.node_selected = element; - this.node_selected.classList.add('selected'); - this.dispatch('nodeSelected', this.ele_selected.id.slice(5)); - } - console.log(id) - } - - let last_x = 0; - let last_y = 0; - let dragElementHover = null; - - editor.on("mouseMove", ({x, y}) => { - const hoverEles = document.elementsFromPoint(x, y); - const nextGroup = hoverEles.find(ele => ele.classList.contains('GROUP') && (!editor.node_selected || ele.id !== editor.node_selected.id)); - - if (nextGroup) { - if (dragElementHover !== nextGroup) { - if (dragElementHover) { - dragElementHover.classList.remove("hover-drop"); - } - dragElementHover = nextGroup; - dragElementHover.classList.add("hover-drop"); - } - } else if (dragElementHover) { - dragElementHover.classList.remove("hover-drop"); - dragElementHover = null; - } - - if (editor.node_selected && editor.drag) { - const selectedNodeId = editor.node_selected.id.slice(5); - var dx = Math.ceil((last_x - x) * editor.precanvas.clientWidth / (editor.precanvas.clientWidth * editor.zoom)); - var dy = Math.ceil((last_y - y) * editor.precanvas.clientHeight / (editor.precanvas.clientHeight * editor.zoom)); - - if (editor.node_selected.classList.contains("GROUP")) { - moveGroupNodes(selectedNodeId, -dx, -dy); - } - } else { - if (dragElementHover) { - dragElementHover.classList.remove("hover-drop"); - dragElementHover = null; - } - } - - last_x = x; - last_y = y; + console.log("nodeKey", nodeKey); + console.log("node", node); + console.log("nodeData", nodeData); + console.log("id", id); + + if (nodeData && nodeData.copies) { + console.log("Array.isArray(nodeData.copies)", Array.isArray(nodeData.copies)); + if (nodeData.copies.includes(id)) { + console.log("nodeData.copies", nodeData.copies); + console.log("nodeData.copies.includes(id)", + nodeData.copies.includes(id)); + const index = nodeData.copies.indexOf(id); + console.log("index", index); + if (index > -1) { + nodeData.copies.splice(index, 1); + editor.updateNodeDataFromId(nodeKey, nodeData); + } + } + } }); + }); + + editor.on("nodeSelected", function (id) { + console.log("Node selected " + id); + makeNodeTop(id); + }); + + editor.on("moduleCreated", function (name) { + console.log("Module Created " + name); + }); + + editor.on("moduleChanged", function (name) { + console.log("Module Changed " + name); + }); + + editor.on("connectionCreated", function (connection) { + console.log("Connection created"); + console.log(connection); + disableButtons(); + }); + + editor.on("connectionRemoved", function (connection) { + console.log("Connection removed"); + console.log(connection); + disableButtons(); + }); + + editor.on("mouseMove", function (position) { + // console.log('Position mouse x:' + position.x + ' y:' + position.y); + }); + + editor.on("zoom", function (zoom) { + console.log("Zoom level " + zoom); + }); + + editor.on("translate", function (position) { + console.log("Translate x:" + position.x + " y:" + position.y); + }); + + editor.on("addReroute", function (id) { + console.log("Reroute added " + id); + }); + + editor.on("removeReroute", function (id) { + console.log("Reroute removed " + id); + }); + + editor.selectNode = function (id) { + if (this.node_selected != null) { + this.node_selected.classList.remove("selected"); + if (this.node_selected !== this.ele_selected) { + this.dispatch("nodeUnselected", true); + } + } + const element = document.querySelector(`#node-${id}`); + this.ele_selected = element; + this.node_selected = element; + this.node_selected.classList.add("selected"); + if (this.node_selected !== this.ele_selected) { + this.node_selected = element; + this.node_selected.classList.add("selected"); + this.dispatch("nodeSelected", this.ele_selected.id.slice(5)); + } + console.log(id); + }; + + let last_x = 0; + let last_y = 0; + let dragElementHover = null; + + editor.on("mouseMove", ({x, y}) => { + const hoverEles = document.elementsFromPoint(x, y); + const nextGroup = hoverEles.find(ele => ele.classList.contains("GROUP") && (!editor.node_selected || ele.id !== editor.node_selected.id)); + + if (nextGroup) { + if (dragElementHover !== nextGroup) { + if (dragElementHover) { + dragElementHover.classList.remove("hover-drop"); + } + dragElementHover = nextGroup; + dragElementHover.classList.add("hover-drop"); + } + } else if (dragElementHover) { + dragElementHover.classList.remove("hover-drop"); + dragElementHover = null; + } + + if (editor.node_selected && editor.drag) { + const selectedNodeId = editor.node_selected.id.slice(5); + const dx = Math.ceil((last_x - x) * editor.precanvas.clientWidth / (editor.precanvas.clientWidth * editor.zoom)); + const dy = Math.ceil((last_y - y) * editor.precanvas.clientHeight / (editor.precanvas.clientHeight * editor.zoom)); + + if (editor.node_selected.classList.contains("GROUP")) { + moveGroupNodes(selectedNodeId, -dx, -dy); + } + } else { + if (dragElementHover) { + dragElementHover.classList.remove("hover-drop"); + dragElementHover = null; + } + } + + last_x = x; + last_y = y; + }); + + editor.on("nodeMoved", (id) => { + const dragNode = id; + if (dragElementHover !== null) { + const dropNode = dragElementHover.id.slice(5); + if (dragNode !== dropNode) { + removeOfGroupNode(dragNode); + dragElementHover.classList.remove("hover-drop"); + const dropNodeInfo = editor.getNodeFromId(dropNode); + const dropNodeInfoData = dropNodeInfo.data; + if (dropNodeInfoData.elements.indexOf(dragNode) === -1) { + dropNodeInfoData.elements.push(dragNode); + editor.updateNodeDataFromId(dropNode, dropNodeInfoData); + // remove connections + editor.removeConnectionNodeId("node-" + id); + // Hide the ports when node is inside the group + togglePortsDisplay(dragNode, "none"); + const dragNodeData = editor.getNodeFromId(dragNode); + if (dragNodeData.class !== "GROUP") { + collapseNode(dragNode); + } + } + } + dragElementHover = null; + } else { + // If the node is moved outside of any group, show the ports + togglePortsDisplay(dragNode, ""); + removeOfGroupNode(dragNode); + } + disableButtons(); + }); - editor.on("nodeMoved", (id) => { - const dragNode = id; - if (dragElementHover !== null) { - const dropNode = dragElementHover.id.slice(5); - if (dragNode !== dropNode) { - removeOfGroupNode(dragNode); - dragElementHover.classList.remove("hover-drop"); - const dropNodeInfo = editor.getNodeFromId(dropNode); - const dropNodeInfoData = dropNodeInfo.data; - if (dropNodeInfoData.elements.indexOf(dragNode) === -1) { - dropNodeInfoData.elements.push(dragNode); - editor.updateNodeDataFromId(dropNode, dropNodeInfoData); - // remove connections - editor.removeConnectionNodeId('node-' + id); - // Hide the ports when node is inside the group - togglePortsDisplay(dragNode, 'none'); - const dragNodeData = editor.getNodeFromId(dragNode); - if (dragNodeData.class !== "GROUP") { - collapseNode(dragNode); - } - } - } - dragElementHover = null; - } else { - // If the node is moved outside of any group, show the ports - togglePortsDisplay(dragNode, ''); - removeOfGroupNode(dragNode); - } - disableButtons(); - }) - - editor.on("nodeRemoved", (id) => { - removeOfGroupNode(id); - }); + editor.on("nodeRemoved", (id) => { + removeOfGroupNode(id); + }); - /* DRAG EVENT */ + /* DRAG EVENT */ - /* Mouse and Touch Actions */ + /* Mouse and Touch Actions */ - var elements = document.getElementsByClassName('workstation-sidebar-dragitem'); - for (var i = 0; i < elements.length; i++) { - elements[i].addEventListener('touchend', drop, false); - elements[i].addEventListener('touchmove', positionMobile, false); - elements[i].addEventListener('touchstart', drag, false); - } + const elements = document.getElementsByClassName("workstation-sidebar-dragitem"); + for (let i = 0; i < elements.length; i++) { + elements[i].addEventListener("touchend", drop, false); + elements[i].addEventListener("touchmove", positionMobile, false); + elements[i].addEventListener("touchstart", drag, false); + } - mobile_item_selec = ''; - mobile_last_move = null; + mobile_item_selec = ""; + mobile_last_move = null; - importQueue = []; - currentImportIndex = 0; - accumulatedImportData = {}; - descriptionStep = []; - console.log("importQueue", importQueue) + importQueue = []; + currentImportIndex = 0; + accumulatedImportData = {}; + descriptionStep = []; + console.log("importQueue", importQueue); - document.getElementById('surveyButton').addEventListener('click', function () { - window.open('https://survey.aliyun.com/apps/zhiliao/vgpTppn22', '_blank'); - }); + document.getElementById("surveyButton").addEventListener("click", function () { + window.open("https://survey.aliyun.com/apps/zhiliao/vgpTppn22", "_blank"); + }); - document.getElementById('surveyClose').addEventListener('click', function () { - hideSurveyModal(); - }); + document.getElementById("surveyClose").addEventListener("click", function () { + hideSurveyModal(); + }); - setTimeout(showSurveyModal, 30000); + setTimeout(showSurveyModal, 30000); - if (!localStorage.getItem('firstGuide')) { - startGuide(); - } - reloadi18n(); + if (!localStorage.getItem("firstGuide")) { + startGuide(); + } + reloadi18n(); } function makeNodeTop(id) { - const node = document.getElementById(`node-${id}`); - const nodeInfo = editor.getNodeFromId(id); + const node = document.getElementById(`node-${id}`); + const nodeInfo = editor.getNodeFromId(id); - if (nodeInfo) { - console.log("currentZIndex: " + currentZIndex); - currentZIndex += 1; - node.style.zIndex = currentZIndex; + if (nodeInfo) { + console.log("currentZIndex: " + currentZIndex); + currentZIndex += 1; + node.style.zIndex = currentZIndex; - if (nodeInfo.class === 'GROUP') { - nodeInfo.data.elements.forEach((elementId) => { - makeNodeTop(elementId); - }); - } + if (nodeInfo.class === "GROUP") { + nodeInfo.data.elements.forEach((elementId) => { + makeNodeTop(elementId); + }); } + } } function moveGroupNodes(groupId, dx, dy) { - const groupInfo = editor.getNodeFromId(groupId); - const elements = groupInfo.data.elements || []; - elements.forEach(eleId => { - const eleNode = document.getElementById(`node-${eleId}`); - const eleNodeInfo = editor.getNodeFromId(eleId); + const groupInfo = editor.getNodeFromId(groupId); + const elements = groupInfo.data.elements || []; + elements.forEach(eleId => { + const eleNode = document.getElementById(`node-${eleId}`); + const eleNodeInfo = editor.getNodeFromId(eleId); - if (eleNode) { - const nodeData = editor.drawflow.drawflow[editor.module].data[eleId]; - const newPosX = nodeData.pos_x + dx; - const newPosY = nodeData.pos_y + dy; + if (eleNode) { + const nodeData = editor.drawflow.drawflow[editor.module].data[eleId]; + const newPosX = nodeData.pos_x + dx; + const newPosY = nodeData.pos_y + dy; - eleNode.style.left = newPosX + "px"; - eleNode.style.top = newPosY + "px"; + eleNode.style.left = newPosX + "px"; + eleNode.style.top = newPosY + "px"; - if (editor.drawflow.drawflow[editor.module] && + if (editor.drawflow.drawflow[editor.module] && editor.drawflow.drawflow[editor.module].data && editor.drawflow.drawflow[editor.module].data[eleId]) { - editor.drawflow.drawflow[editor.module].data[eleId].pos_x = newPosX; - editor.drawflow.drawflow[editor.module].data[eleId].pos_y = newPosY; - } + editor.drawflow.drawflow[editor.module].data[eleId].pos_x = newPosX; + editor.drawflow.drawflow[editor.module].data[eleId].pos_y = newPosY; + } - editor.updateConnectionNodes(`node-${eleId}`); - } + editor.updateConnectionNodes(`node-${eleId}`); + } - if (eleNodeInfo.class && eleNodeInfo.class === "GROUP") { - moveGroupNodes(eleId, dx, dy); - } - }); + if (eleNodeInfo.class && eleNodeInfo.class === "GROUP") { + moveGroupNodes(eleId, dx, dy); + } + }); } function collapseNode(nodeId) { - const nodeElement = document.getElementById(`node-${nodeId}`); - const contentBox = nodeElement.querySelector('.box'); - const toggleArrow = nodeElement.querySelector('.toggle-arrow'); + const nodeElement = document.getElementById(`node-${nodeId}`); + const contentBox = nodeElement.querySelector(".box"); + const toggleArrow = nodeElement.querySelector(".toggle-arrow"); - contentBox.classList.add('hidden'); - toggleArrow.textContent = "\u25BC"; + contentBox.classList.add("hidden"); + toggleArrow.textContent = "\u25BC"; } function togglePortsDisplay(nodeId, displayStyle) { - const nodeElement = document.querySelector(`#node-${nodeId}`); - if (nodeElement) { - const inputs = nodeElement.querySelectorAll('.inputs .input'); - const outputs = nodeElement.querySelectorAll('.outputs .output'); - inputs.forEach(input => { - input.style.display = displayStyle; - }); - outputs.forEach(output => { - output.style.display = displayStyle; - }); - } + const nodeElement = document.querySelector(`#node-${nodeId}`); + if (nodeElement) { + const inputs = nodeElement.querySelectorAll(".inputs .input"); + const outputs = nodeElement.querySelectorAll(".outputs .output"); + inputs.forEach(input => { + input.style.display = displayStyle; + }); + outputs.forEach(output => { + output.style.display = displayStyle; + }); + } } function removeOfGroupNode(id) { - Object.keys(editor.drawflow.drawflow[editor.module].data).forEach(ele => { - if (editor.drawflow.drawflow[editor.module].data[ele].class === "GROUP") { - const findIndex = editor.drawflow.drawflow[editor.module].data[ele].data.elements.indexOf(id); - if (findIndex !== -1) { - editor.drawflow.drawflow[editor.module].data[ele].data.elements.splice(findIndex, 1); - } - } - }) + Object.keys(editor.drawflow.drawflow[editor.module].data).forEach(ele => { + if (editor.drawflow.drawflow[editor.module].data[ele].class === "GROUP") { + const findIndex = editor.drawflow.drawflow[editor.module].data[ele].data.elements.indexOf(id); + if (findIndex !== -1) { + editor.drawflow.drawflow[editor.module].data[ele].data.elements.splice(findIndex, 1); + } + } + }); } function positionMobile(ev) { - mobile_last_move = ev; + mobile_last_move = ev; } function allowDrop(ev) { - ev.preventDefault(); + ev.preventDefault(); } function drag(ev) { - if (ev.type === "touchstart") { - mobile_item_selec = ev.target.closest(".workstation-sidebar-dragitem").getAttribute('data-node'); - } else { - ev.dataTransfer.setData("node", ev.target.getAttribute('data-node')); - } + if (ev.type === "touchstart") { + mobile_item_selec = ev.target.closest(".workstation-sidebar-dragitem").getAttribute("data-node"); + } else { + ev.dataTransfer.setData("node", ev.target.getAttribute("data-node")); + } } function drop(ev) { - if (ev.type === "touchend") { - var parentdrawflow = document.elementFromPoint(mobile_last_move.touches[0].clientX, mobile_last_move.touches[0].clientY).closest("#drawflow"); - if (parentdrawflow != null) { - addNodeToDrawFlow(mobile_item_selec, mobile_last_move.touches[0].clientX, mobile_last_move.touches[0].clientY); - } - mobile_item_selec = ''; - } else { - ev.preventDefault(); - var data = ev.dataTransfer.getData("node"); - addNodeToDrawFlow(data, ev.clientX, ev.clientY); + if (ev.type === "touchend") { + const parentdrawflow = document.elementFromPoint(mobile_last_move.touches[0].clientX, mobile_last_move.touches[0].clientY).closest("#drawflow"); + if (parentdrawflow != null) { + addNodeToDrawFlow(mobile_item_selec, mobile_last_move.touches[0].clientX, mobile_last_move.touches[0].clientY); } + mobile_item_selec = ""; + } else { + ev.preventDefault(); + const data = ev.dataTransfer.getData("node"); + addNodeToDrawFlow(data, ev.clientX, ev.clientY); + } } async function addNodeToDrawFlow(name, pos_x, pos_y) { - if (editor.editor_mode === 'fixed') { - return false; - } - pos_x = Math.ceil(pos_x * (editor.precanvas.clientWidth / (editor.precanvas.clientWidth * editor.zoom)) - (editor.precanvas.getBoundingClientRect().x * (editor.precanvas.clientWidth / (editor.precanvas.clientWidth * editor.zoom)))); - pos_y = Math.ceil(pos_y * (editor.precanvas.clientHeight / (editor.precanvas.clientHeight * editor.zoom)) - (editor.precanvas.getBoundingClientRect().y * (editor.precanvas.clientHeight / (editor.precanvas.clientHeight * editor.zoom)))); - - var htmlSourceCode = await fetchHtmlSourceCodeByName(name); - - switch (name) { - // Workflow-Model - case 'dashscope_chat': - editor.addNode('dashscope_chat', 0, 0, pos_x, - pos_y, - 'dashscope_chat', { - "args": + if (editor.editor_mode === "fixed") { + return false; + } + pos_x = Math.ceil(pos_x * (editor.precanvas.clientWidth / (editor.precanvas.clientWidth * editor.zoom)) - (editor.precanvas.getBoundingClientRect().x * (editor.precanvas.clientWidth / (editor.precanvas.clientWidth * editor.zoom)))); + pos_y = Math.ceil(pos_y * (editor.precanvas.clientHeight / (editor.precanvas.clientHeight * editor.zoom)) - (editor.precanvas.getBoundingClientRect().y * (editor.precanvas.clientHeight / (editor.precanvas.clientHeight * editor.zoom)))); + + const htmlSourceCode = await fetchHtmlSourceCodeByName(name); + + switch (name) { + // Workflow-Model + case "dashscope_chat": + editor.addNode("dashscope_chat", 0, 0, pos_x, + pos_y, + "dashscope_chat", { + "args": { - "config_name": '', - "model_name": '', - "api_key": '', - "temperature": 0.0, - "seed": 0, - "model_type": 'dashscope_chat' + "config_name": "", + "model_name": "", + "api_key": "", + "temperature": 0.0, + "seed": 0, + "model_type": "dashscope_chat" } - }, - htmlSourceCode); - break; - - case 'openai_chat': - editor.addNode('openai_chat', 0, 0, pos_x, - pos_y, - 'openai_chat', { - "args": + }, + htmlSourceCode); + break; + + case "openai_chat": + editor.addNode("openai_chat", 0, 0, pos_x, + pos_y, + "openai_chat", { + "args": { - "config_name": '', - "model_name": '', - "api_key": '', - "temperature": 0.0, - "seed": 0, - "model_type": 'openai_chat' + "config_name": "", + "model_name": "", + "api_key": "", + "temperature": 0.0, + "seed": 0, + "model_type": "openai_chat" } - }, - htmlSourceCode); - break; - - case 'post_api_chat': - editor.addNode('post_api_chat', 0, 0, pos_x, pos_y, - 'post_api_chat', { - "args": + }, + htmlSourceCode); + break; + + case "post_api_chat": + editor.addNode("post_api_chat", 0, 0, pos_x, pos_y, + "post_api_chat", { + "args": { - "config_name": '', - "api_url": '', - "headers": { - "content_type": 'application/json', - "authorization": '', - }, - "json_args": { - "model": '', - "temperature": 0.0, - "seed": 0, - }, - "model_type": 'post_api_chat', - "messages_key": 'messages' + "config_name": "", + "api_url": "", + "headers": { + "content_type": "application/json", + "authorization": "", + }, + "json_args": { + "model": "", + "temperature": 0.0, + "seed": 0, + }, + "model_type": "post_api_chat", + "messages_key": "messages" } - }, - htmlSourceCode); - break; - - case 'post_api_dall_e': - editor.addNode('post_api_dall_e', 0, - 0, - pos_x, pos_y, - 'post_api_dall_e', { - "args": + }, + htmlSourceCode); + break; + + case "post_api_dall_e": + editor.addNode("post_api_dall_e", 0, + 0, + pos_x, pos_y, + "post_api_dall_e", { + "args": { - "config_name": '', - "api_url": '', - "headers": { - "content_type": 'application/json', - "authorization": '', - }, - "json_args": { - "model": '', - "n": 1, - "size": "", - "temperature": 0.0, - "seed": 0, - }, - "model_type": 'post_api_dall_e', - "messages_key": 'prompt' + "config_name": "", + "api_url": "", + "headers": { + "content_type": "application/json", + "authorization": "", + }, + "json_args": { + "model": "", + "n": 1, + "size": "", + "temperature": 0.0, + "seed": 0, + }, + "model_type": "post_api_dall_e", + "messages_key": "prompt" } - }, - htmlSourceCode); - break; - - case 'dashscope_image_synthesis': - editor.addNode('dashscope_image_synthesis', 0, - 0, - pos_x, pos_y, - 'dashscope_image_synthesis', { - "args": + }, + htmlSourceCode); + break; + + case "dashscope_image_synthesis": + editor.addNode("dashscope_image_synthesis", 0, + 0, + pos_x, pos_y, + "dashscope_image_synthesis", { + "args": { - "config_name": '', - "model_name": '', - "generate_args": { - "n": 1, - "size": "", - "temperature": 0.0, - "seed": 0, - }, - "model_type": 'dashscope_image_synthesis' + "config_name": "", + "model_name": "", + "generate_args": { + "n": 1, + "size": "", + "temperature": 0.0, + "seed": 0, + }, + "model_type": "dashscope_image_synthesis" } - }, htmlSourceCode); - break; - - // Message - case 'Message': - editor.addNode('Message', 1, 1, pos_x, - pos_y, 'Message', { - "args": + }, htmlSourceCode); + break; + + // Message + case "Message": + editor.addNode("Message", 1, 1, pos_x, + pos_y, "Message", { + "args": { - "name": '', - "content": '', - "url": '' - } - }, htmlSourceCode); - break; - - // Workflow-Agent - case 'DialogAgent': - const DialogAgentID = editor.addNode('DialogAgent', 1, 1, - pos_x, - pos_y, - 'DialogAgent', { - "args": { - "name": '', - "sys_prompt": '', - "model_config_name": '' - } - }, htmlSourceCode); - var nodeElement = document.querySelector(`#node-${DialogAgentID} .node-id`); - if (nodeElement) { - nodeElement.textContent = DialogAgentID; - } - break; - - case 'UserAgent': - const UserAgentID = editor.addNode('UserAgent', 1, 1, pos_x, - pos_y, 'UserAgent', { - "args": {"name": 'User'} - }, htmlSourceCode); - var nodeElement = document.querySelector(`#node-${UserAgentID} .node-id`); - if (nodeElement) { - nodeElement.textContent = UserAgentID; - } - break; - - case 'TextToImageAgent': - const TextToImageAgentID = - editor.addNode('TextToImageAgent', 1, - 1, pos_x, pos_y, - 'TextToImageAgent', { - "args": { - "name": '', - "model_config_name": '' - } - }, htmlSourceCode); - var nodeElement = document.querySelector(`#node-${TextToImageAgentID} .node-id`); - if (nodeElement) { - nodeElement.textContent = TextToImageAgentID; - } - break; - - case 'DictDialogAgent': - const DictDialogAgentID = editor.addNode('DictDialogAgent', 1, - 1, pos_x, pos_y, - 'DictDialogAgent', { - "args": { - "name": '', - "sys_prompt": '', - "model_config_name": '', - "parse_func": '', - "fault_handler": '', - "max_retries": 3, - } - }, htmlSourceCode); - var nodeElement = document.querySelector(`#node-${DictDialogAgentID} .node-id`); - if (nodeElement) { - nodeElement.textContent = DictDialogAgentID; - } - break; - - case 'ReActAgent': - const ReActAgentID = editor.addNode('ReActAgent', 1, 1, pos_x, pos_y, - 'GROUP', { - elements: [], - "args": { - "name": '', - "sys_prompt": '', - "model_config_name": '', - "max_iters": 10, - "verbose": '', - } - }, htmlSourceCode); - var nodeElement = document.querySelector(`#node-${ReActAgentID} .node-id`); - if (nodeElement) { - nodeElement.textContent = ReActAgentID; - } - break; - - // Workflow-Pipeline - case 'Placeholder': - editor.addNode('Placeholder', 1, 1, - pos_x, pos_y, 'Placeholder', {}, htmlSourceCode); - break; - - case 'MsgHub': - editor.addNode('MsgHub', 1, 1, pos_x, pos_y, - 'GROUP', { - elements: [], - "args": { - "announcement": { - "name": '', - "content": '' + "name": "", + "content": "", + "url": "" } - } - }, htmlSourceCode); - break; - - case 'SequentialPipeline': - editor.addNode('SequentialPipeline', 1, 1, pos_x, pos_y, - 'GROUP', {elements: []}, htmlSourceCode); - break; - - case 'ForLoopPipeline': - editor.addNode('ForLoopPipeline', 1, 1, pos_x, pos_y, - 'GROUP', { - elements: [], - "args": { - "max_loop": 3, - "condition_op": "", - "target_value": "", - } - }, htmlSourceCode); - break; - - case 'WhileLoopPipeline': - editor.addNode('WhileLoopPipeline', 1, 1, pos_x, pos_y, - 'GROUP', { - elements: [], - "args": { - "condition_func": '' - } - }, htmlSourceCode); - break; - - case 'IfElsePipeline': - editor.addNode('IfElsePipeline', 1, - 1, pos_x, pos_y, 'GROUP', { - elements: [], args: { - "condition_op": "", - "target_value": "", - } - }, htmlSourceCode); - break; - - case 'SwitchPipeline': - const SwitchPipelineID = editor.addNode('SwitchPipeline', 1, 1, pos_x, pos_y, 'GROUP', { - elements: [], args: { - "condition_func": '', - "cases": [], - } - }, htmlSourceCode); - break; - - // Workflow-Service - case 'BingSearchService': - editor.addNode('BingSearchService', 0, 0, - pos_x, pos_y, 'BingSearchService', { - "args": { - "api_key": "", - "num_results": 3, - } - }, htmlSourceCode); - break; - - case 'GoogleSearchService': - editor.addNode('GoogleSearchService', 0, 0, - pos_x, pos_y, 'GoogleSearchService', { - "args": { - "api_key": "", - "cse_id": "", - "num_results": 3, - } - }, htmlSourceCode); - break; - - case 'PythonService': - editor.addNode('PythonService', 0, 0, - pos_x, pos_y, 'PythonService', {}, htmlSourceCode); - break; - - case 'ReadTextService': - editor.addNode('ReadTextService', 0, 0, - pos_x, pos_y, 'ReadTextService', {}, htmlSourceCode); - break; - - case 'WriteTextService': - editor.addNode('WriteTextService', 0, 0, - pos_x, pos_y, 'WriteTextService', {}, htmlSourceCode); - break; - - case 'TextToAudioService': - const TextToAudioServiceID = editor.addNode('TextToAudioService', 0, 0, - pos_x, pos_y, 'TextToAudioService', { - "args": { - "model": "", - "api_key": "", - "sample_rate": "" - } - }, htmlSourceCode); - break; - case 'TextToImageService': - editor.addNode('TextToImageService', 0, 0, - pos_x, pos_y, 'TextToImageService', { - "args": { - "model": "", - "api_key": "", - "n": 1, - "size": "" - } - }, htmlSourceCode); - break; - - case 'ImageComposition': - editor.addNode('ImageComposition', 1, 1, - pos_x, pos_y, 'ImageComposition', { - "args": { - "titles": "", - "output_path": "", - "row": 1, - "column": 1, - "spacing": 10, - "title_height": 100, - "font_name": "PingFang", - } - }, htmlSourceCode); - break; - case 'Code': - const CodeID = editor.addNode('Code', 1, 1, - pos_x, pos_y, 'Code', { - "args": { - "code": "def function(msg1: Msg) -> Msg:\n content1 = msg1.get(\"content\", \"\")\n return {\n \"role\": \"assistant\",\n \"content\": content1,\n \"name\": \"function\",\n }" - } - }, htmlSourceCode); - break; - // case 'IF/ELSE': - // const IfelseID = editor.addNode('IF/ELSE', 1, 2, - // pos_x, pos_y, 'IF/ELSE', { - // "args": { - // "condition_op": "", - // "target_value": "", - // } - // }, htmlSourceCode); - // break; - - case 'ImageMotion': - editor.addNode('ImageMotion', 1, 1, - pos_x, pos_y, 'ImageMotion', { - "args": { - "output_path": "", - "output_format": "", - "duration": "", - } - }, htmlSourceCode); - break; + }, htmlSourceCode); + break; + + // Workflow-Agent + case "DialogAgent": + const DialogAgentID = editor.addNode("DialogAgent", 1, 1, + pos_x, + pos_y, + "DialogAgent", { + "args": { + "name": "", + "sys_prompt": "", + "model_config_name": "" + } + }, htmlSourceCode); + var nodeElement = document.querySelector(`#node-${DialogAgentID} .node-id`); + if (nodeElement) { + nodeElement.textContent = DialogAgentID; + } + break; - case 'VideoComposition': - editor.addNode('VideoComposition', 1, 1, - pos_x, pos_y, 'VideoComposition', { - "args": { - "output_path": "", - "target_width": "", - "target_height": "", - "fps": "", - } - }, htmlSourceCode); - break; + case "UserAgent": + const UserAgentID = editor.addNode("UserAgent", 1, 1, pos_x, + pos_y, "UserAgent", { + "args": {"name": "User"} + }, htmlSourceCode); + var nodeElement = document.querySelector(`#node-${UserAgentID} .node-id`); + if (nodeElement) { + nodeElement.textContent = UserAgentID; + } + break; - case 'Post': - editor.addNode('Post', 1, 1, - pos_x, pos_y, 'Post', { + case "TextToImageAgent": + const TextToImageAgentID = + editor.addNode("TextToImageAgent", 1, + 1, pos_x, pos_y, + "TextToImageAgent", { "args": { - "url": "", - "headers": '', - "data": '', - "json": '', - "kwargs": '', - "output_path": "", - "output_type": "", + "name": "", + "model_config_name": "" } - }, htmlSourceCode); - break; - - default: - } + }, htmlSourceCode); + var nodeElement = document.querySelector(`#node-${TextToImageAgentID} .node-id`); + if (nodeElement) { + nodeElement.textContent = TextToImageAgentID; + } + break; + + case "DictDialogAgent": + const DictDialogAgentID = editor.addNode("DictDialogAgent", 1, + 1, pos_x, pos_y, + "DictDialogAgent", { + "args": { + "name": "", + "sys_prompt": "", + "model_config_name": "", + "parse_func": "", + "fault_handler": "", + "max_retries": 3, + } + }, htmlSourceCode); + var nodeElement = document.querySelector(`#node-${DictDialogAgentID} .node-id`); + if (nodeElement) { + nodeElement.textContent = DictDialogAgentID; + } + break; + + case "ReActAgent": + const ReActAgentID = editor.addNode("ReActAgent", 1, 1, pos_x, pos_y, + "GROUP", { + elements: [], + "args": { + "name": "", + "sys_prompt": "", + "model_config_name": "", + "max_iters": 10, + "verbose": "", + } + }, htmlSourceCode); + var nodeElement = document.querySelector(`#node-${ReActAgentID} .node-id`); + if (nodeElement) { + nodeElement.textContent = ReActAgentID; + } + break; + + // Workflow-Pipeline + case "Placeholder": + editor.addNode("Placeholder", 1, 1, + pos_x, pos_y, "Placeholder", {}, htmlSourceCode); + break; + + case "MsgHub": + editor.addNode("MsgHub", 1, 1, pos_x, pos_y, + "GROUP", { + elements: [], + "args": { + "announcement": { + "name": "", + "content": "" + } + } + }, htmlSourceCode); + break; + + case "SequentialPipeline": + editor.addNode("SequentialPipeline", 1, 1, pos_x, pos_y, + "GROUP", {elements: []}, htmlSourceCode); + break; + + case "ForLoopPipeline": + editor.addNode("ForLoopPipeline", 1, 1, pos_x, pos_y, + "GROUP", { + elements: [], + "args": { + "max_loop": 3, + "condition_op": "", + "target_value": "", + } + }, htmlSourceCode); + break; + + case "WhileLoopPipeline": + editor.addNode("WhileLoopPipeline", 1, 1, pos_x, pos_y, + "GROUP", { + elements: [], + "args": { + "condition_func": "" + } + }, htmlSourceCode); + break; + + case "IfElsePipeline": + editor.addNode("IfElsePipeline", 1, + 1, pos_x, pos_y, "GROUP", { + elements: [], args: { + "condition_op": "", + "target_value": "", + } + }, htmlSourceCode); + break; + + case "SwitchPipeline": + const SwitchPipelineID = editor.addNode("SwitchPipeline", 1, 1, pos_x, pos_y, "GROUP", { + elements: [], args: { + "condition_func": "", + "cases": [], + } + }, htmlSourceCode); + break; + + // Workflow-Service + case "BingSearchService": + editor.addNode("BingSearchService", 0, 0, + pos_x, pos_y, "BingSearchService", { + "args": { + "api_key": "", + "num_results": 3, + } + }, htmlSourceCode); + break; + + case "GoogleSearchService": + editor.addNode("GoogleSearchService", 0, 0, + pos_x, pos_y, "GoogleSearchService", { + "args": { + "api_key": "", + "cse_id": "", + "num_results": 3, + } + }, htmlSourceCode); + break; + + case "PythonService": + editor.addNode("PythonService", 0, 0, + pos_x, pos_y, "PythonService", {}, htmlSourceCode); + break; + + case "ReadTextService": + editor.addNode("ReadTextService", 0, 0, + pos_x, pos_y, "ReadTextService", {}, htmlSourceCode); + break; + + case "WriteTextService": + editor.addNode("WriteTextService", 0, 0, + pos_x, pos_y, "WriteTextService", {}, htmlSourceCode); + break; + + case "TextToAudioService": + const TextToAudioServiceID = editor.addNode("TextToAudioService", 0, 0, + pos_x, pos_y, "TextToAudioService", { + "args": { + "model": "", + "api_key": "", + "sample_rate": "" + } + }, htmlSourceCode); + break; + case "TextToImageService": + editor.addNode("TextToImageService", 0, 0, + pos_x, pos_y, "TextToImageService", { + "args": { + "model": "", + "api_key": "", + "n": 1, + "size": "" + } + }, htmlSourceCode); + break; + + case "ImageComposition": + editor.addNode("ImageComposition", 1, 1, + pos_x, pos_y, "ImageComposition", { + "args": { + "titles": "", + "output_path": "", + "row": 1, + "column": 1, + "spacing": 10, + "title_height": 100, + "font_name": "PingFang", + } + }, htmlSourceCode); + break; + case "Code": + const CodeID = editor.addNode("Code", 1, 1, + pos_x, pos_y, "Code", { + "args": { + "code": "def function(msg1: Msg) -> Msg:\n content1 = msg1.get(\"content\", \"\")\n return {\n \"role\": \"assistant\",\n \"content\": content1,\n \"name\": \"function\",\n }" + } + }, htmlSourceCode); + break; + // case 'IF/ELSE': + // const IfelseID = editor.addNode('IF/ELSE', 1, 2, + // pos_x, pos_y, 'IF/ELSE', { + // "args": { + // "condition_op": "", + // "target_value": "", + // } + // }, htmlSourceCode); + // break; + + case "ImageMotion": + editor.addNode("ImageMotion", 1, 1, + pos_x, pos_y, "ImageMotion", { + "args": { + "output_path": "", + "output_format": "", + "duration": "", + } + }, htmlSourceCode); + break; + + case "VideoComposition": + editor.addNode("VideoComposition", 1, 1, + pos_x, pos_y, "VideoComposition", { + "args": { + "output_path": "", + "target_width": "", + "target_height": "", + "fps": "", + } + }, htmlSourceCode); + break; + + case "Post": + editor.addNode("Post", 1, 1, + pos_x, pos_y, "Post", { + "args": { + "url": "", + "headers": "", + "data": "", + "json": "", + "kwargs": "", + "output_path": "", + "output_type": "", + } + }, htmlSourceCode); + break; + + default: + } } function initializeMonacoEditor(nodeId) { - require.config({ - paths: { - vs: "https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs", - }, + require.config({ + paths: { + vs: "https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs", + }, + }); + + require(["vs/editor/editor.main"], function () { + const parentSelector = `#node-${nodeId}`; + const parentNode = document.querySelector(parentSelector); + + if (!parentNode) { + console.error(`Parent node with selector ${parentSelector} not found.`); + return; + } + + const codeContentElement = parentNode.querySelector(".code-content"); + if (!codeContentElement) { + return; + } + + const node = editor.getNodeFromId(nodeId); + if (!node) { + console.error(`Node with ID ${nodeId} not found.`); + return; + } + + const editorInstance = monaco.editor.create(codeContentElement, { + value: node.data.args.code, + language: "python", + theme: "vs-light", + minimap: { + enabled: false, + }, + wordWrap: "on", + lineNumbersMinChars: 1, + scrollBeyondLastLine: false, + readOnly: false, }); - require(["vs/editor/editor.main"], function () { - const parentSelector = `#node-${nodeId}`; - const parentNode = document.querySelector(parentSelector); - - if (!parentNode) { - console.error(`Parent node with selector ${parentSelector} not found.`); - return; - } - - const codeContentElement = parentNode.querySelector(`.code-content`); - if (!codeContentElement) { - return; - } - - const node = editor.getNodeFromId(nodeId); - if (!node) { - console.error(`Node with ID ${nodeId} not found.`); - return; - } - - const editorInstance = monaco.editor.create(codeContentElement, { - value: node.data.args.code, - language: "python", - theme: "vs-light", - minimap: { - enabled: false, - }, - wordWrap: "on", - lineNumbersMinChars: 1, - scrollBeyondLastLine: false, - readOnly: false, - }); - - editorInstance.onDidChangeModelContent(function () { - const updatedNode = editor.getNodeFromId(nodeId); - if (updatedNode) { - updatedNode.data.args.code = editorInstance.getValue().trim(); - editor.updateNodeDataFromId(nodeId, updatedNode.data); - } - }); - - const resizeObserver = new ResizeObserver(() => { - editorInstance.layout(); - }); - resizeObserver.observe(parentNode); - parentNode.addEventListener('DOMNodeRemoved', function () { - resizeObserver.disconnect(); - }); + editorInstance.onDidChangeModelContent(function () { + const updatedNode = editor.getNodeFromId(nodeId); + if (updatedNode) { + updatedNode.data.args.code = editorInstance.getValue().trim(); + editor.updateNodeDataFromId(nodeId, updatedNode.data); + } + }); - }, function (error) { - console.error("Error encountered while loading monaco editor: ", error); + const resizeObserver = new ResizeObserver(() => { + editorInstance.layout(); + }); + resizeObserver.observe(parentNode); + parentNode.addEventListener("DOMNodeRemoved", function () { + resizeObserver.disconnect(); }); -} + }, function (error) { + console.error("Error encountered while loading monaco editor: ", error); + }); +} function updateSampleRate(nodeId) { - const newNode = document.getElementById(`node-${nodeId}`); - if (!newNode) { - console.error(`Node with ID node-${nodeId} not found.`); - return; - } + const newNode = document.getElementById(`node-${nodeId}`); + if (!newNode) { + console.error(`Node with ID node-${nodeId} not found.`); + return; + } - const modelNameInput = newNode.querySelector('#model_name'); + const modelNameInput = newNode.querySelector("#model_name"); - function updateSampleRateValue() { - const modelName = modelNameInput ? modelNameInput.value : ''; + function updateSampleRateValue() { + const modelName = modelNameInput ? modelNameInput.value : ""; - if (ModelNames48k.includes(modelName)) { - sampleRate = 48000 - } else { - sampleRate = 16000 - } + if (ModelNames48k.includes(modelName)) { + sampleRate = 48000; + } else { + sampleRate = 16000; + } - const sampleRateInput = newNode.querySelector('#sample_rate'); + const sampleRateInput = newNode.querySelector("#sample_rate"); - if (sampleRateInput) { - sampleRateInput.value = sampleRate; - var nodeData = editor.getNodeFromId(nodeId).data; - nodeData.args.sample_rate = sampleRate - nodeData.args.model = modelName - editor.updateNodeDataFromId(nodeId, nodeData); + if (sampleRateInput) { + sampleRateInput.value = sampleRate; + const nodeData = editor.getNodeFromId(nodeId).data; + nodeData.args.sample_rate = sampleRate; + nodeData.args.model = modelName; + editor.updateNodeDataFromId(nodeId, nodeData); - console.log(`${modelName} sample rate updated to: ${sampleRate}`); - } else { - console.log(`Sample Rate input not found.`); - } + console.log(`${modelName} sample rate updated to: ${sampleRate}`); + } else { + console.log("Sample Rate input not found."); } + } - if (modelNameInput) { - modelNameInput.addEventListener('input', updateSampleRateValue); - } + if (modelNameInput) { + modelNameInput.addEventListener("input", updateSampleRateValue); + } } function setupTextInputListeners(nodeId) { - const newNode = document.getElementById(`node-${nodeId}`); - if (newNode) { - const stopPropagation = function (event) { - event.stopPropagation(); - }; - newNode.addEventListener('mousedown', function (event) { - const target = event.target; - if (target.tagName === 'TEXTAREA' || target.tagName === 'INPUT' || target.closest('.code-content')) { - stopPropagation(event); - } - }, false); - } + const newNode = document.getElementById(`node-${nodeId}`); + if (newNode) { + const stopPropagation = function (event) { + event.stopPropagation(); + }; + newNode.addEventListener("mousedown", function (event) { + const target = event.target; + if (target.tagName === "TEXTAREA" || target.tagName === "INPUT" || target.closest(".code-content")) { + stopPropagation(event); + } + }, false); + } } function toggleAdvanced() { - var advancedBox = document.querySelector('.advanced-box'); - if (advancedBox.style.display === "none") { - advancedBox.style.display = "block"; - } else { - advancedBox.style.display = "none"; - } + const advancedBox = document.querySelector(".advanced-box"); + if (advancedBox.style.display === "none") { + advancedBox.style.display = "block"; + } else { + advancedBox.style.display = "none"; + } } function handleInputChange(event) { - const input = event.target; + const input = event.target; - if (input.type === 'number') { - const value = input.value; - const floatValue = parseFloat(value); - const nodeId = input.closest('.drawflow_content_node').parentElement.id.slice(5); + if (input.type === "number") { + const value = input.value; + const floatValue = parseFloat(value); + const nodeId = input.closest(".drawflow_content_node").parentElement.id.slice(5); - if (!isNaN(floatValue)) { - const node = editor.getNodeFromId(nodeId); - const dataAttributes = + if (!isNaN(floatValue)) { + const node = editor.getNodeFromId(nodeId); + const dataAttributes = Array.from(input.attributes).filter(attr => - attr.name.startsWith('df-args-')); - dataAttributes.forEach(attr => { - const attrName = attr.name; - if (attrName.startsWith('df-args-json_args-')) { - const dataAttribute = attrName.substring(18) - if - (node.data.args.json_args.hasOwnProperty(dataAttribute)) { - node.data.args.json_args[dataAttribute] = floatValue; - editor.updateNodeDataFromId(nodeId, node.data); - } - } else { - const dataAttribute = attrName.substring(8); - if (node.data.args.hasOwnProperty(dataAttribute)) { - node.data.args[dataAttribute] = floatValue; - editor.updateNodeDataFromId(nodeId, node.data); - } - } - }); + attr.name.startsWith("df-args-")); + dataAttributes.forEach(attr => { + const attrName = attr.name; + if (attrName.startsWith("df-args-json_args-")) { + const dataAttribute = attrName.substring(18); + if + (node.data.args.json_args.hasOwnProperty(dataAttribute)) { + node.data.args.json_args[dataAttribute] = floatValue; + editor.updateNodeDataFromId(nodeId, node.data); + } } else { - console.error("Invalid input value:", value); + const dataAttribute = attrName.substring(8); + if (node.data.args.hasOwnProperty(dataAttribute)) { + node.data.args[dataAttribute] = floatValue; + editor.updateNodeDataFromId(nodeId, node.data); + } } + }); + } else { + console.error("Invalid input value:", value); } + } } function addEventListenersToNumberInputs(nodeId) { - const nodeElement = document.getElementById(`node-${nodeId}`); - if (nodeElement) { - const numberInputs = nodeElement.querySelectorAll('input[type=number]'); - numberInputs.forEach(input => { - input.addEventListener('change', handleInputChange); - }); - } + const nodeElement = document.getElementById(`node-${nodeId}`); + if (nodeElement) { + const numberInputs = nodeElement.querySelectorAll("input[type=number]"); + numberInputs.forEach(input => { + input.addEventListener("change", handleInputChange); + }); + } } function validateTemperature(input) { - const value = input.valueAsNumber; - if (isNaN(value) || value < 0 || value >= 2) { - input.setCustomValidity('Temperature must be greater or equal than 0 and less than 2!'); - } else { - input.setCustomValidity(''); - } - input.reportValidity(); + const value = input.valueAsNumber; + if (isNaN(value) || value < 0 || value >= 2) { + input.setCustomValidity("Temperature must be greater or equal than 0 and less than 2!"); + } else { + input.setCustomValidity(""); + } + input.reportValidity(); } function validateSeed(input) { - const value = parseInt(input.value, 10); // Parse the value as an integer. - if (isNaN(value) || value < 0 || !Number.isInteger(parseFloat(input.value))) { - input.setCustomValidity('Seed must be a non-negative integer!'); - } else { - input.setCustomValidity(''); - } - input.reportValidity(); + const value = parseInt(input.value, 10); // Parse the value as an integer. + if (isNaN(value) || value < 0 || !Number.isInteger(parseFloat(input.value))) { + input.setCustomValidity("Seed must be a non-negative integer!"); + } else { + input.setCustomValidity(""); + } + input.reportValidity(); } function validateDuration(input) { - const value = parseInt(input.value, 10); // Parse the value as an integer. - if (isNaN(value) || value < 0 || !Number.isInteger(parseFloat(input.value))) { - input.setCustomValidity('Duration must be a non-negative integer!'); - } else { - input.setCustomValidity(''); - } - input.reportValidity(); + const value = parseInt(input.value, 10); // Parse the value as an integer. + if (isNaN(value) || value < 0 || !Number.isInteger(parseFloat(input.value))) { + input.setCustomValidity("Duration must be a non-negative integer!"); + } else { + input.setCustomValidity(""); + } + input.reportValidity(); } -document.addEventListener('input', function (event) { - const input = event.target; +document.addEventListener("input", function (event) { + const input = event.target; - if (input.getAttribute('df-args-temperature') !== null || - input.getAttribute('df-args-json_args-temperature') !== null) { - validateTemperature(input); - } + if (input.getAttribute("df-args-temperature") !== null || + input.getAttribute("df-args-json_args-temperature") !== null) { + validateTemperature(input); + } - if (input.getAttribute('df-args-seed') !== null || - input.getAttribute('df-args-json_args-seed') !== null) { - validateSeed(input); - } + if (input.getAttribute("df-args-seed") !== null || + input.getAttribute("df-args-json_args-seed") !== null) { + validateSeed(input); + } - if (input.getAttribute('df-args-duration') !== null) { - validateDuration(input) - } + if (input.getAttribute("df-args-duration") !== null) { + validateDuration(input); + } }); -var transform = ''; +var transform = ""; function updateReadmeAndTrimExtrasInHTML(htmlString, nodeId) { - const parser = new DOMParser(); - const doc = parser.parseFromString(htmlString, 'text/html'); - const containerDiv = doc.body.firstChild; + const parser = new DOMParser(); + const doc = parser.parseFromString(htmlString, "text/html"); + const containerDiv = doc.body.firstChild; - removeNonReadmeChildren(containerDiv); - updateReadmeContent(containerDiv, nodeId); + removeNonReadmeChildren(containerDiv); + updateReadmeContent(containerDiv, nodeId); - return containerDiv.innerHTML; + return containerDiv.innerHTML; } function updateReadmeContent(containerDiv, nodeId) { - const readmeDiv = containerDiv.querySelector('.readme'); - if (readmeDiv) { - console.log("readmeDiv", readmeDiv); + const readmeDiv = containerDiv.querySelector(".readme"); + if (readmeDiv) { + console.log("readmeDiv", readmeDiv); - let newDiv = document.createElement('div'); - newDiv.innerHTML = `Copy from Node ID: ${nodeId}`; - readmeDiv.appendChild(newDiv); + const newDiv = document.createElement("div"); + newDiv.innerHTML = `Copy from Node ID: ${nodeId}`; + readmeDiv.appendChild(newDiv); - console.log("readmeDiv after", readmeDiv); - } + console.log("readmeDiv after", readmeDiv); + } } function removeNonReadmeChildren(containerDiv) { - const boxDiv = containerDiv.querySelector('.box'); - if (boxDiv) { - boxDiv.querySelectorAll('*:not(.readme)').forEach(child => child.remove()); - } + const boxDiv = containerDiv.querySelector(".box"); + if (boxDiv) { + boxDiv.querySelectorAll("*:not(.readme)").forEach(child => child.remove()); + } } function createNodeHTML(node, isCopy, originalNodeId) { - let modifiedHtml = isCopy ? processNodeCopyHTML(node.html) : node.html; - return updateReadmeAndTrimExtrasInHTML(modifiedHtml, originalNodeId); + const modifiedHtml = isCopy ? processNodeCopyHTML(node.html) : node.html; + return updateReadmeAndTrimExtrasInHTML(modifiedHtml, originalNodeId); } function processNodeCopyHTML(htmlString) { - const parser = new DOMParser(); - const doc = parser.parseFromString(htmlString, 'text/html'); + const parser = new DOMParser(); + const doc = parser.parseFromString(htmlString, "text/html"); - ['.copy-button', 'div .node-id'].forEach(selector => { - const element = doc.querySelector(selector); - if (element) element.remove(); - }); + [".copy-button", "div .node-id"].forEach(selector => { + const element = doc.querySelector(selector); + if (element) { + element.remove(); + } + }); - return doc.body.innerHTML; + return doc.body.innerHTML; } function copyNode(originalNodeId) { - const originalNode = editor.getNodeFromId(originalNodeId); - originalNode.data.copies = originalNode.data.copies || []; + const originalNode = editor.getNodeFromId(originalNodeId); + originalNode.data.copies = originalNode.data.copies || []; - const newNodeHTML = createNodeHTML(originalNode, true, originalNodeId); - const [posX, posY] = [originalNode.pos_x + 30, originalNode.pos_y + 30]; + const newNodeHTML = createNodeHTML(originalNode, true, originalNodeId); + const [posX, posY] = [originalNode.pos_x + 30, originalNode.pos_y + 30]; - editor.addNode("CopyNode", - Object.keys(originalNode.inputs).length, - Object.keys(originalNode.outputs).length, - posX, posY, 'node-' + originalNode.name, {elements: [originalNodeId.toString()]}, - newNodeHTML); + editor.addNode("CopyNode", + Object.keys(originalNode.inputs).length, + Object.keys(originalNode.outputs).length, + posX, posY, "node-" + originalNode.name, {elements: [originalNodeId.toString()]}, + newNodeHTML); } function setupNodeCopyListens(nodeId) { - const newNode = document.getElementById(`node-${nodeId}`); - if (newNode) { - const copyButton = newNode.querySelector('.copy-button'); - if (copyButton) { - copyButton.addEventListener('click', function () { - copyNode(nodeId); - }); - } + const newNode = document.getElementById(`node-${nodeId}`); + if (newNode) { + const copyButton = newNode.querySelector(".copy-button"); + if (copyButton) { + copyButton.addEventListener("click", function () { + copyNode(nodeId); + }); } + } } function hideShowGroupNodes(groupId, show) { - const groupInfo = editor.getNodeFromId(groupId); - if (groupInfo && groupInfo.class === 'GROUP') { - groupInfo.data.elements.forEach(elementNodeId => { - const elementNode = document.getElementById(`node-${elementNodeId}`); - const childNodeInfo = editor.getNodeFromId(elementNodeId); - const contentBox = elementNode.querySelector('.box') || - elementNode.querySelector('.box-highlight'); - if (elementNode) { - elementNode.style.display = show ? '' : 'none'; - } - if (childNodeInfo.class === 'GROUP') { - if (!show || (contentBox && !contentBox.classList.contains('hidden'))) { - hideShowGroupNodes(elementNodeId, show); - } - } - }); - } + const groupInfo = editor.getNodeFromId(groupId); + if (groupInfo && groupInfo.class === "GROUP") { + groupInfo.data.elements.forEach(elementNodeId => { + const elementNode = document.getElementById(`node-${elementNodeId}`); + const childNodeInfo = editor.getNodeFromId(elementNodeId); + const contentBox = elementNode.querySelector(".box") || + elementNode.querySelector(".box-highlight"); + if (elementNode) { + elementNode.style.display = show ? "" : "none"; + } + if (childNodeInfo.class === "GROUP") { + if (!show || (contentBox && !contentBox.classList.contains("hidden"))) { + hideShowGroupNodes(elementNodeId, show); + } + } + }); + } } function setupConditionListeners(nodeId) { - const newNode = document.getElementById(`node-${nodeId}`); - if (newNode) { - const conditionOp = newNode.querySelector('#condition_op'); - const targetContainer = newNode.querySelector('#target-container'); - console.log(conditionOp, targetContainer); - - function updateTargetVisibility() { - const condition_op = conditionOp ? conditionOp.value : ''; - const hideConditions = ['', 'is empty', 'is null', 'is not empty', 'is not null']; - if (hideConditions.includes(condition_op)) { - targetContainer.style.display = 'none'; - } else { - targetContainer.style.display = 'block'; - } - } + const newNode = document.getElementById(`node-${nodeId}`); + if (newNode) { + const conditionOp = newNode.querySelector("#condition_op"); + const targetContainer = newNode.querySelector("#target-container"); + console.log(conditionOp, targetContainer); - if (conditionOp) { - conditionOp.addEventListener('input', updateTargetVisibility); - updateTargetVisibility(); - } + function updateTargetVisibility() { + const condition_op = conditionOp ? conditionOp.value : ""; + const hideConditions = ["", "is empty", "is null", "is not empty", "is not null"]; + if (hideConditions.includes(condition_op)) { + targetContainer.style.display = "none"; + } else { + targetContainer.style.display = "block"; + } + } + + if (conditionOp) { + conditionOp.addEventListener("input", updateTargetVisibility); + updateTargetVisibility(); } + } } function setupNodeListeners(nodeId) { - const newNode = document.getElementById(`node-${nodeId}`); - if (newNode) { + const newNode = document.getElementById(`node-${nodeId}`); + if (newNode) { - initializeMonacoEditor(nodeId); - setupConditionListeners(nodeId); - updateSampleRate(nodeId); - setupSwitchPipelineListeners(nodeId); + initializeMonacoEditor(nodeId); + setupConditionListeners(nodeId); + updateSampleRate(nodeId); + setupSwitchPipelineListeners(nodeId); - const titleBox = newNode.querySelector('.title-box'); - const contentBox = newNode.querySelector('.box') || - newNode.querySelector('.box-highlight'); + const titleBox = newNode.querySelector(".title-box"); + const contentBox = newNode.querySelector(".box") || + newNode.querySelector(".box-highlight"); - // Add resize handle to the bottom right corner of the node - const resizeHandleSE = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + // Add resize handle to the bottom right corner of the node + const resizeHandleSE = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', 'M932.37602347 512.88874453l-420.37602347 420.37602347 56.43525867 56.43525867 420.37602453-420.37602347-56.43525973-56.43525867z m-3.55497707-474.58942293L34.29997333 933.264768l56.43525867 56.43525867L985.25630613 95.1789536l-56.43525973-56.879632z'); + const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); + path.setAttribute("d", "M932.37602347 512.88874453l-420.37602347 420.37602347 56.43525867 56.43525867 420.37602453-420.37602347-56.43525973-56.43525867z m-3.55497707-474.58942293L34.29997333 933.264768l56.43525867 56.43525867L985.25630613 95.1789536l-56.43525973-56.879632z"); - resizeHandleSE.setAttribute('viewBox', '0 0 1024 1024'); - resizeHandleSE.appendChild(path); + resizeHandleSE.setAttribute("viewBox", "0 0 1024 1024"); + resizeHandleSE.appendChild(path); - resizeHandleSE.classList.add('resize-handle-se'); + resizeHandleSE.classList.add("resize-handle-se"); - contentBox.appendChild(resizeHandleSE); + contentBox.appendChild(resizeHandleSE); - const toggleArrow = newNode.querySelector('.toggle-arrow'); + const toggleArrow = newNode.querySelector(".toggle-arrow"); - if (toggleArrow && contentBox && titleBox) { - toggleArrow.addEventListener('click', function () { - contentBox.classList.toggle('hidden'); + if (toggleArrow && contentBox && titleBox) { + toggleArrow.addEventListener("click", function () { + contentBox.classList.toggle("hidden"); - if (contentBox.classList.contains('hidden')) { - toggleArrow.textContent = "\u25BC"; - hideShowGroupNodes(nodeId, false); - } else { - toggleArrow.textContent = "\u25B2"; - hideShowGroupNodes(nodeId, true); - } - editor.updateConnectionNodes('node-' + nodeId); - }); + if (contentBox.classList.contains("hidden")) { + toggleArrow.textContent = "\u25BC"; + hideShowGroupNodes(nodeId, false); + } else { + toggleArrow.textContent = "\u25B2"; + hideShowGroupNodes(nodeId, true); + } + editor.updateConnectionNodes("node-" + nodeId); + }); - let startX, startY, startWidth, startHeight; + let startX, startY, startWidth, startHeight; - resizeHandleSE.addEventListener('mousedown', function (e) { - e.stopPropagation(); - document.addEventListener('mousemove', doDragSE, false); - document.addEventListener('mouseup', stopDragSE, false); + resizeHandleSE.addEventListener("mousedown", function (e) { + e.stopPropagation(); + document.addEventListener("mousemove", doDragSE, false); + document.addEventListener("mouseup", stopDragSE, false); - startX = e.clientX; - startY = e.clientY; - startWidth = parseInt(document.defaultView.getComputedStyle(contentBox).width, 10); - startHeight = parseInt(document.defaultView.getComputedStyle(contentBox).height, 10); - }); + startX = e.clientX; + startY = e.clientY; + startWidth = parseInt(document.defaultView.getComputedStyle(contentBox).width, 10); + startHeight = parseInt(document.defaultView.getComputedStyle(contentBox).height, 10); + }); - function doDragSE(e) { - newNode.style.width = 'auto'; + function doDragSE(e) { + newNode.style.width = "auto"; - const newWidth = (startWidth + e.clientX - startX); - if (newWidth > 200) { - contentBox.style.width = newWidth + 'px'; - titleBox.style.width = newWidth + 'px'; - } + const newWidth = (startWidth + e.clientX - startX); + if (newWidth > 200) { + contentBox.style.width = newWidth + "px"; + titleBox.style.width = newWidth + "px"; + } - const newHeight = (startHeight + e.clientY - startY); - contentBox.style.height = newHeight + 'px'; + const newHeight = (startHeight + e.clientY - startY); + contentBox.style.height = newHeight + "px"; - editor.updateConnectionNodes('node-' + nodeId); - } + editor.updateConnectionNodes("node-" + nodeId); + } - function stopDragSE(e) { - document.removeEventListener('mousemove', doDragSE, false); - document.removeEventListener('mouseup', stopDragSE, false); - } + function stopDragSE(e) { + document.removeEventListener("mousemove", doDragSE, false); + document.removeEventListener("mouseup", stopDragSE, false); + } - } } + } } function setupSwitchPipelineListeners(nodeId) { - const newNode = document.getElementById(`node-${nodeId}`); - if (!newNode) { - console.error(`Node with ID node-${nodeId} not found.`); - return; - } - const addCaseButton = newNode.querySelector('.add-case'); - if (!addCaseButton) { - return; - } - addCaseButton.addEventListener('click', function () { - var caseContainer = newNode.querySelector('.case-container'); - if (!caseContainer) { - console.error(`Case container not found in node-${nodeId}.`); - return; - } - var defaultCaseElement = caseContainer.querySelector('.default-case'); - if (defaultCaseElement) { - caseContainer.removeChild(defaultCaseElement); - } - var caseCount = caseContainer.getElementsByClassName('case-placeholder').length; - var caseElement = document.createElement('div'); - caseElement.classList.add('case-placeholder'); - - var caseText = document.createTextNode(`Case ${caseCount + 1}: `); - caseElement.appendChild(caseText); - - var inputElement = document.createElement('input'); - inputElement.type = 'text'; - inputElement.placeholder = `Case Pattern`; - - inputElement.dataset.caseIndex = caseCount; - - caseElement.appendChild(inputElement); - caseContainer.appendChild(caseElement); - - inputElement.addEventListener('input', function (e) { - var nodeData = editor.getNodeFromId(nodeId).data; - console.log("nodeData", nodeData); - var index = e.target.dataset.caseIndex; - console.log("index", index); - nodeData.args.cases[index] = e.target.value; - editor.updateNodeDataFromId(nodeId, nodeData); - }); - - editor.getNodeFromId(nodeId).data.args.cases.push(''); - - addDefaultCase(caseContainer); - editor.updateConnectionNodes('node-' + nodeId); - }); - - const removeCaseButton = newNode.querySelector('.remove-case'); - if (!removeCaseButton) { - return; - } - removeCaseButton.addEventListener('click', function () { - var caseContainer = newNode.querySelector('.case-container'); - var cases = caseContainer.getElementsByClassName('case-placeholder'); - if (cases.length > 1) { - caseContainer.removeChild(cases[cases.length - 2]); - var nodeData = editor.getNodeFromId(nodeId).data; - nodeData.args.cases.splice(nodeData.args.cases.length - 1, 1); - editor.updateNodeDataFromId(nodeId, nodeData); - } - editor.updateConnectionNodes('node-' + nodeId); - }); - - var caseContainer = newNode.querySelector('.case-container'); + const newNode = document.getElementById(`node-${nodeId}`); + if (!newNode) { + console.error(`Node with ID node-${nodeId} not found.`); + return; + } + const addCaseButton = newNode.querySelector(".add-case"); + if (!addCaseButton) { + return; + } + addCaseButton.addEventListener("click", function () { + const caseContainer = newNode.querySelector(".case-container"); if (!caseContainer) { - console.error(`Case container not found in node-${nodeId}.`); - return; + console.error(`Case container not found in node-${nodeId}.`); + return; } - - var defaultCaseElement = caseContainer.querySelector('.default-case'); + const defaultCaseElement = caseContainer.querySelector(".default-case"); if (defaultCaseElement) { - caseContainer.removeChild(defaultCaseElement); + caseContainer.removeChild(defaultCaseElement); } + const caseCount = caseContainer.getElementsByClassName("case-placeholder").length; + const caseElement = document.createElement("div"); + caseElement.classList.add("case-placeholder"); - var cases = editor.getNodeFromId(nodeId).data.args.cases; - for (var caseCount = 0; caseCount < cases.length; caseCount++) { + const caseText = document.createTextNode(`Case ${caseCount + 1}: `); + caseElement.appendChild(caseText); - var caseElement = document.createElement('div'); - caseElement.classList.add('case-placeholder'); + const inputElement = document.createElement("input"); + inputElement.type = "text"; + inputElement.placeholder = "Case Pattern"; - var caseText = document.createTextNode(`Case ${caseCount + 1}: `); - caseElement.appendChild(caseText); + inputElement.dataset.caseIndex = caseCount; - var inputElement = document.createElement('input'); - inputElement.type = 'text'; - inputElement.placeholder = `Case Pattern`; - inputElement.value = cases[caseCount]; + caseElement.appendChild(inputElement); + caseContainer.appendChild(caseElement); - inputElement.dataset.caseIndex = caseCount; + inputElement.addEventListener("input", function (e) { + const nodeData = editor.getNodeFromId(nodeId).data; + console.log("nodeData", nodeData); + const index = e.target.dataset.caseIndex; + console.log("index", index); + nodeData.args.cases[index] = e.target.value; + editor.updateNodeDataFromId(nodeId, nodeData); + }); - caseElement.appendChild(inputElement); - caseContainer.appendChild(caseElement); + editor.getNodeFromId(nodeId).data.args.cases.push(""); - inputElement.addEventListener('input', function (e) { - var nodeData = editor.getNodeFromId(nodeId).data; - console.log("nodeData", nodeData); - var index = e.target.dataset.caseIndex; - console.log("index", index); - nodeData.args.cases[index] = e.target.value; - editor.updateNodeDataFromId(nodeId, nodeData); - }); - } addDefaultCase(caseContainer); + editor.updateConnectionNodes("node-" + nodeId); + }); + + const removeCaseButton = newNode.querySelector(".remove-case"); + if (!removeCaseButton) { + return; + } + removeCaseButton.addEventListener("click", function () { + const caseContainer = newNode.querySelector(".case-container"); + const cases = caseContainer.getElementsByClassName("case-placeholder"); + if (cases.length > 1) { + caseContainer.removeChild(cases[cases.length - 2]); + const nodeData = editor.getNodeFromId(nodeId).data; + nodeData.args.cases.splice(nodeData.args.cases.length - 1, 1); + editor.updateNodeDataFromId(nodeId, nodeData); + } + editor.updateConnectionNodes("node-" + nodeId); + }); + + const caseContainer = newNode.querySelector(".case-container"); + if (!caseContainer) { + console.error(`Case container not found in node-${nodeId}.`); + return; + } + + const defaultCaseElement = caseContainer.querySelector(".default-case"); + if (defaultCaseElement) { + caseContainer.removeChild(defaultCaseElement); + } + + const cases = editor.getNodeFromId(nodeId).data.args.cases; + for (let caseCount = 0; caseCount < cases.length; caseCount++) { + + const caseElement = document.createElement("div"); + caseElement.classList.add("case-placeholder"); + + const caseText = document.createTextNode(`Case ${caseCount + 1}: `); + caseElement.appendChild(caseText); + + const inputElement = document.createElement("input"); + inputElement.type = "text"; + inputElement.placeholder = "Case Pattern"; + inputElement.value = cases[caseCount]; + + inputElement.dataset.caseIndex = caseCount; + + caseElement.appendChild(inputElement); + caseContainer.appendChild(caseElement); + + inputElement.addEventListener("input", function (e) { + const nodeData = editor.getNodeFromId(nodeId).data; + console.log("nodeData", nodeData); + const index = e.target.dataset.caseIndex; + console.log("index", index); + nodeData.args.cases[index] = e.target.value; + editor.updateNodeDataFromId(nodeId, nodeData); + }); + } + addDefaultCase(caseContainer); } function addDefaultCase(caseContainer) { - var defaultCaseElement = document.createElement('div'); - defaultCaseElement.classList.add('case-placeholder', 'default-case'); - defaultCaseElement.textContent = `Default Case`; - caseContainer.appendChild(defaultCaseElement); + const defaultCaseElement = document.createElement("div"); + defaultCaseElement.classList.add("case-placeholder", "default-case"); + defaultCaseElement.textContent = "Default Case"; + caseContainer.appendChild(defaultCaseElement); } function closemodal(e) { - e.target.closest(".drawflow-node").style.zIndex = "2"; - e.target.parentElement.parentElement.style.display = "none"; - editor.precanvas.style.transform = transform; - editor.precanvas.style.left = '0px'; - editor.precanvas.style.top = '0px'; - editor.editor_mode = "edit"; + e.target.closest(".drawflow-node").style.zIndex = "2"; + e.target.parentElement.parentElement.style.display = "none"; + editor.precanvas.style.transform = transform; + editor.precanvas.style.left = "0px"; + editor.precanvas.style.top = "0px"; + editor.editor_mode = "edit"; } function changeModule(event) { - var all = document.querySelectorAll(".menu ul li"); - for (var i = 0; i < all.length; i++) { - all[i].classList.remove('selected'); - } - event.target.classList.add('selected'); + const all = document.querySelectorAll(".menu ul li"); + for (let i = 0; i < all.length; i++) { + all[i].classList.remove("selected"); + } + event.target.classList.add("selected"); } function changeLockMode(option) { - let lockSvg = document.getElementById('lock-svg'); - let unlockSvg = document.getElementById('unlock-svg'); - if (option === 'lock') { - editor.editor_mode = 'edit'; - lockSvg.style.display = 'none'; - unlockSvg.style.display = 'block'; - } else { - editor.editor_mode = 'fixed'; - lockSvg.style.display = 'block'; - unlockSvg.style.display = 'none'; - } + const lockSvg = document.getElementById("lock-svg"); + const unlockSvg = document.getElementById("unlock-svg"); + if (option === "lock") { + editor.editor_mode = "edit"; + lockSvg.style.display = "none"; + unlockSvg.style.display = "block"; + } else { + editor.editor_mode = "fixed"; + lockSvg.style.display = "block"; + unlockSvg.style.display = "none"; + } } function toggleDraggable(element) { - var content = element.nextElementSibling; - if (content.classList.contains('visible')) { - content.classList.remove('visible'); - } else { - content.classList.add('visible'); - } + const content = element.nextElementSibling; + if (content.classList.contains("visible")) { + content.classList.remove("visible"); + } else { + content.classList.add("visible"); + } } function filterEmptyValues(obj) { - return Object.entries(obj).reduce((acc, [key, value]) => { - if (typeof value === 'object' && value !== null) { - const filteredNestedObj = filterEmptyValues(value); - if (Object.keys(filteredNestedObj).length > 0) { - acc[key] = filteredNestedObj; - } - } else if (value !== '') { - acc[key] = value; - } - return acc; - }, {}); + return Object.entries(obj).reduce((acc, [key, value]) => { + if (typeof value === "object" && value !== null) { + const filteredNestedObj = filterEmptyValues(value); + if (Object.keys(filteredNestedObj).length > 0) { + acc[key] = filteredNestedObj; + } + } else if (value !== "") { + acc[key] = value; + } + return acc; + }, {}); } // This function is the most important to AgentScope config. function reorganizeAndFilterConfigForAgentScope(inputData) { - // Assuming there's only one tab ('Home'), but adjust if there are more - const homeTab = inputData.drawflow.Home; - // Create a new object to hold the reorganized and filtered nodes - const filteredNodes = {}; - - // Iterate through the nodes and copy them to the filteredNodes object - Object.entries(homeTab.data).forEach(([key, node]) => { - // Skip the node if the name is 'welcome' or 'readme' - const nodeName = node.name.toLowerCase(); - if (nodeName === 'welcome' || nodeName === 'readme') { - return; - } + // Assuming there's only one tab ('Home'), but adjust if there are more + const homeTab = inputData.drawflow.Home; + // Create a new object to hold the reorganized and filtered nodes + const filteredNodes = {}; - // Create a copy of the node without 'html', 'typenode', 'class', 'id', and 'name' fields - const { - html, - typenode, - pos_x, - pos_y, - class: classField, - id, - ...cleanNode - } = node; - - if (cleanNode.data && cleanNode.data.args) { - cleanNode.data.args = filterEmptyValues(cleanNode.data.args); - } + // Iterate through the nodes and copy them to the filteredNodes object + Object.entries(homeTab.data).forEach(([key, node]) => { + // Skip the node if the name is 'welcome' or 'readme' + const nodeName = node.name.toLowerCase(); + if (nodeName === "welcome" || nodeName === "readme") { + return; + } - // Add the cleaned node to the filteredNodes object using its id as the key - filteredNodes[key] = cleanNode; - }); + // Create a copy of the node without 'html', 'typenode', 'class', 'id', and 'name' fields + const { + html, + typenode, + pos_x, + pos_y, + class: classField, + id, + ...cleanNode + } = node; + + if (cleanNode.data && cleanNode.data.args) { + cleanNode.data.args = filterEmptyValues(cleanNode.data.args); + } + + // Add the cleaned node to the filteredNodes object using its id as the key + filteredNodes[key] = cleanNode; + }); - // Return the filtered and reorganized nodes instead of the original structure - return filteredNodes; + // Return the filtered and reorganized nodes instead of the original structure + return filteredNodes; } function sortElementsByPosition(inputData) { - let hasError = false; - - Object.keys(inputData.drawflow).forEach((moduleKey) => { - const moduleData = inputData.drawflow[moduleKey]; - Object.entries(moduleData.data).forEach(([nodeId, node]) => { - if (node.class === 'GROUP') { - let elements = node.data.elements; - let elementsWithPosition = elements.map(elementId => { - const elementNode = document.querySelector(`#node-${elementId}`); - return elementNode ? { - id: elementId, - position: { - x: elementNode.style.left, - y: elementNode.style.top - } - } : null; - }).filter(el => el); - - try { - elementsWithPosition.sort((a, b) => { - let y1 = parseInt(a.position.y, 10); - let y2 = parseInt(b.position.y, 10); - if (y1 === y2) { - throw new Error(`Two elements have the same y position: Element ${a.id} and Element ${b.id}`); - } - return y1 - y2; - }); - } catch (error) { - alert(error.message); - hasError = true; - } - node.data.elements = elementsWithPosition.map(el => el.id); + let hasError = false; + + Object.keys(inputData.drawflow).forEach((moduleKey) => { + const moduleData = inputData.drawflow[moduleKey]; + Object.entries(moduleData.data).forEach(([nodeId, node]) => { + if (node.class === "GROUP") { + const elements = node.data.elements; + const elementsWithPosition = elements.map(elementId => { + const elementNode = document.querySelector(`#node-${elementId}`); + return elementNode ? { + id: elementId, + position: { + x: elementNode.style.left, + y: elementNode.style.top } - }); + } : null; + }).filter(el => el); + + try { + elementsWithPosition.sort((a, b) => { + const y1 = parseInt(a.position.y, 10); + const y2 = parseInt(b.position.y, 10); + if (y1 === y2) { + throw new Error(`Two elements have the same y position: Element ${a.id} and Element ${b.id}`); + } + return y1 - y2; + }); + } catch (error) { + alert(error.message); + hasError = true; + } + node.data.elements = elementsWithPosition.map(el => el.id); + } }); - return hasError; + }); + return hasError; } function checkConditions() { - let hasModelTypeError = false; - let hasAgentError = false; - let agentModelConfigNames = new Set(); - let modelConfigNames = new Set(); - let isApiKeyEmpty = false; - const nodesData = editor.export().drawflow.Home.data; - - for (let nodeId in nodesData) { - let node = nodesData[nodeId]; - console.log("node", node); - console.log("node.inputs", node.inputs); - - let nodeElement = document.getElementById('node-' + nodeId); - const requiredInputs = nodeElement.querySelectorAll('input[data-required="true"]'); - - let titleBox = nodeElement.querySelector('.title-box'); - - let titleText = titleBox.getAttribute("data-class"); - - for (const input of requiredInputs) { - if (input.value.trim() === '') { - let inputLabel = input.previousElementSibling; - if (inputLabel && inputLabel.tagName.toLowerCase() === "label") { - let labelText = inputLabel.textContent.trim(); - - Swal.fire({ - title: 'Value Missing!', - text: `${labelText} is missing in ${titleText}.`, - icon: 'error', - confirmButtonText: 'Ok' - }); - return false; - } - } - } - - if (node.data && node.data.args && node.data.args.model_type) { - hasModelTypeError = false; - modelConfigNames.add(node.data.args.config_name); - if (node.data.args.api_key === "") { - isApiKeyEmpty = isApiKeyEmpty || true; - } - } - if (node.name.includes('Agent') && "model_config_name" in node.data.args) { - hasAgentError = false; - if (node.data && node.data.args) { - agentModelConfigNames.add(node.data.args.model_config_name); - } - } - if (node.name === 'ReActAgent') { - const elements = node.data.elements; - for (const nodeId of elements) { - const childNode = nodesData[nodeId] - if (!childNode || !childNode.name.includes('Service')) { - Swal.fire({ - title: 'Invalid ReActAgent Configuration', - text: - `ReActAgent must only contain Tool nodes as child nodes.`, - icon: 'error', - confirmButtonText: 'Ok' - }); - return false; - } - } - } - if (node.name === 'IfElsePipeline') { - const elementsSize = node.data.elements.length; - if (elementsSize !== 1 && elementsSize !== 2) { - Swal.fire({ - title: 'Invalid IfElsePipeline Configuration', - text: `IfElsePipeline should have 1 or 2 elements, but has ${elementsSize}.`, - icon: 'error', - confirmButtonText: 'Ok' - }); - return false; - } - } - if (['ForLoopPipeline', 'WhileLoopPipeline', 'MsgHub'].includes(node.name)) { - if (node.data.elements.length !== 1) { - hasError = true; - Swal.fire({ - title: 'Invalid Configuration', - text: `${node.name} must have exactly one element.`, - icon: 'error', - confirmButtonText: 'Ok' - }); - return false; - } - let childNodeId = node.data.elements[0]; - let childNode = nodesData[childNodeId]; - if (!childNode || !childNode.name.includes('Pipeline')) { - Swal.fire({ - title: 'Invalid Configuration', - text: - ` ${childNode.name} contained in ${node.name} is not a Pipeline node.`, - icon: 'error', - confirmButtonText: 'Ok' - }); - return false; - } - } - if (node.name === 'Code') { - const code = node.data.args.code; - const pattern = /\bdef\s+function\s*\(/; - - if (!pattern.test(code)) { - Swal.fire({ - title: 'Invalid Code Function Name', - text: `${node.name} only support "function" as the function name.`, - icon: 'error', - confirmButtonText: 'Ok' - }); - return false; - } + let hasModelTypeError = false; + let hasAgentError = false; + const agentModelConfigNames = new Set(); + const modelConfigNames = new Set(); + let isApiKeyEmpty = false; + const nodesData = editor.export().drawflow.Home.data; + + for (const nodeId in nodesData) { + const node = nodesData[nodeId]; + console.log("node", node); + console.log("node.inputs", node.inputs); + + const nodeElement = document.getElementById("node-" + nodeId); + const requiredInputs = nodeElement.querySelectorAll("input[data-required=\"true\"]"); + + const titleBox = nodeElement.querySelector(".title-box"); + + const titleText = titleBox.getAttribute("data-class"); + + for (const input of requiredInputs) { + if (input.value.trim() === "") { + const inputLabel = input.previousElementSibling; + if (inputLabel && inputLabel.tagName.toLowerCase() === "label") { + const labelText = inputLabel.textContent.trim(); + + Swal.fire({ + title: "Value Missing!", + text: `${labelText} is missing in ${titleText}.`, + icon: "error", + confirmButtonText: "Ok" + }); + return false; + } + } + } + + if (node.data && node.data.args && node.data.args.model_type) { + hasModelTypeError = false; + modelConfigNames.add(node.data.args.config_name); + if (node.data.args.api_key === "") { + isApiKeyEmpty = isApiKeyEmpty || true; + } + } + if (node.name.includes("Agent") && "model_config_name" in node.data.args) { + hasAgentError = false; + if (node.data && node.data.args) { + agentModelConfigNames.add(node.data.args.model_config_name); + } + } + if (node.name === "ReActAgent") { + const elements = node.data.elements; + for (const nodeId of elements) { + const childNode = nodesData[nodeId]; + if (!childNode || !childNode.name.includes("Service")) { + Swal.fire({ + title: "Invalid ReActAgent Configuration", + text: + "ReActAgent must only contain Tool nodes as child nodes.", + icon: "error", + confirmButtonText: "Ok" + }); + return false; } + } } - - let unmatchedConfigNames = [...agentModelConfigNames].filter(name => !modelConfigNames.has(name)); - console.log("modelConfigNames", modelConfigNames); - console.log("agentModelConfigNames", agentModelConfigNames); - console.log("unmatchedConfigNames", unmatchedConfigNames); - if (hasModelTypeError) { + if (node.name === "IfElsePipeline") { + const elementsSize = node.data.elements.length; + if (elementsSize !== 1 && elementsSize !== 2) { Swal.fire({ - title: 'Error!', - text: - 'Error: At least one Model node must be present.', - icon: 'error', - confirmButtonText: 'Ok' + title: "Invalid IfElsePipeline Configuration", + text: `IfElsePipeline should have 1 or 2 elements, but has ${elementsSize}.`, + icon: "error", + confirmButtonText: "Ok" }); - } else if (hasAgentError) { + return false; + } + } + if (["ForLoopPipeline", "WhileLoopPipeline", "MsgHub"].includes(node.name)) { + if (node.data.elements.length !== 1) { + hasError = true; Swal.fire({ - title: 'No Agent Nodes Found', - text: "Error: At least one Agent node must be present.", - icon: 'error', - confirmButtonText: 'Ok' + title: "Invalid Configuration", + text: `${node.name} must have exactly one element.`, + icon: "error", + confirmButtonText: "Ok" }); - } else if (unmatchedConfigNames.length > 0) { + return false; + } + const childNodeId = node.data.elements[0]; + const childNode = nodesData[childNodeId]; + if (!childNode || !childNode.name.includes("Pipeline")) { Swal.fire({ - title: 'Configuration Mismatch', - html: - "Each Agent's 'Model config name' must match a Model node's 'Config Name'.
    Unmatched: " + unmatchedConfigNames.join(', '), - icon: 'error', - confirmButtonText: 'Ok' + title: "Invalid Configuration", + text: + ` ${childNode.name} contained in ${node.name} is not a Pipeline node.`, + icon: "error", + confirmButtonText: "Ok" }); - } else if (isApiKeyEmpty) { + return false; + } + } + if (node.name === "Code") { + const code = node.data.args.code; + const pattern = /\bdef\s+function\s*\(/; + + if (!pattern.test(code)) { Swal.fire({ - title: 'API KEY Missing', - text: - "API KEY is missing in your model nodes. Please either enter the API KEY in the corresponding position, or enter a random bit of content and replace it with the real value in the exported files.", - icon: 'error', - confirmButtonText: 'Ok' + title: "Invalid Code Function Name", + text: `${node.name} only support "function" as the function name.`, + icon: "error", + confirmButtonText: "Ok" }); - } else { - return true; + return false; + } } + } + + const unmatchedConfigNames = [...agentModelConfigNames].filter(name => !modelConfigNames.has(name)); + console.log("modelConfigNames", modelConfigNames); + console.log("agentModelConfigNames", agentModelConfigNames); + console.log("unmatchedConfigNames", unmatchedConfigNames); + if (hasModelTypeError) { + Swal.fire({ + title: "Error!", + text: + "Error: At least one Model node must be present.", + icon: "error", + confirmButtonText: "Ok" + }); + } else if (hasAgentError) { + Swal.fire({ + title: "No Agent Nodes Found", + text: "Error: At least one Agent node must be present.", + icon: "error", + confirmButtonText: "Ok" + }); + } else if (unmatchedConfigNames.length > 0) { + Swal.fire({ + title: "Configuration Mismatch", + html: + "Each Agent's 'Model config name' must match a Model node's 'Config Name'.
    Unmatched: " + unmatchedConfigNames.join(", "), + icon: "error", + confirmButtonText: "Ok" + }); + } else if (isApiKeyEmpty) { + Swal.fire({ + title: "API KEY Missing", + text: + "API KEY is missing in your model nodes. Please either enter the API KEY in the corresponding position, or enter a random bit of content and replace it with the real value in the exported files.", + icon: "error", + confirmButtonText: "Ok" + }); + } else { + return true; + } } function showCheckPopup() { - var btnCovers = document.querySelectorAll('.btn-cover'); - if (checkConditions()) { - Swal.fire({ - title: 'Validation Success', - text: "All checks are passed!", - icon: 'success', - confirmButtonText: 'Great!' - }); - btnCovers.forEach(function (btnCover) { - var button = btnCover.querySelector('.btn-disabled'); - if (button) { - button.classList.remove('btn-disabled'); - } - btnCover.removeAttribute('data-title'); - }); - } + const btnCovers = document.querySelectorAll(".btn-cover"); + if (checkConditions()) { + Swal.fire({ + title: "Validation Success", + text: "All checks are passed!", + icon: "success", + confirmButtonText: "Great!" + }); + btnCovers.forEach(function (btnCover) { + const button = btnCover.querySelector(".btn-disabled"); + if (button) { + button.classList.remove("btn-disabled"); + } + btnCover.removeAttribute("data-title"); + }); + } } function disableButtons() { - var btnCovers = document.querySelectorAll('.btn-cover'); + const btnCovers = document.querySelectorAll(".btn-cover"); - btnCovers.forEach(function (btnCover) { - var button = btnCover.querySelector('div'); - if (button) { - button.classList.add('btn-disabled'); - } - btnCover.setAttribute('data-title', - 'Please click the "Check" button first.'); - }); + btnCovers.forEach(function (btnCover) { + const button = btnCover.querySelector("div"); + if (button) { + button.classList.add("btn-disabled"); + } + btnCover.setAttribute("data-title", + "Please click the \"Check\" button first."); + }); } function showExportPyPopup() { - if (checkConditions()) { - const rawData = editor.export(); + if (checkConditions()) { + const rawData = editor.export(); - const hasError = sortElementsByPosition(rawData); - if (hasError) { - return; - } + const hasError = sortElementsByPosition(rawData); + if (hasError) { + return; + } - const filteredData = reorganizeAndFilterConfigForAgentScope(rawData); + const filteredData = reorganizeAndFilterConfigForAgentScope(rawData); - Swal.fire({ - title: 'Processing...', - text: 'Please wait.', - allowOutsideClick: false, - willOpen: () => { - Swal.showLoading() - } - }); + Swal.fire({ + title: "Processing...", + text: "Please wait.", + allowOutsideClick: false, + willOpen: () => { + Swal.showLoading(); + } + }); - fetch('/convert-to-py', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - data: JSON.stringify(filteredData, null, 4), - }) - }).then(response => { - if (!response.ok) { - throw new Error('Network error.'); - } - return response.json(); - }) - .then(data => { - Swal.close(); - if (data.is_success === 'True') { - Swal.fire({ - title: 'Workflow Python Code', - html: - '

    Save as main.py
    ' + - 'Then run the following command in your terminal:
    ' + - '

    python main.py

    ' + - 'or
    as_gradio main.py

    ' + - '
    ' +
    +    fetch("/convert-to-py", {
    +      method: "POST",
    +      headers: {
    +        "Content-Type": "application/json",
    +      },
    +      body: JSON.stringify({
    +        data: JSON.stringify(filteredData, null, 4),
    +      })
    +    }).then(response => {
    +      if (!response.ok) {
    +        throw new Error("Network error.");
    +      }
    +      return response.json();
    +    })
    +      .then(data => {
    +        Swal.close();
    +        if (data.is_success === "True") {
    +          Swal.fire({
    +            title: "Workflow Python Code",
    +            html:
    +                            "

    Save as main.py
    " + + "Then run the following command in your terminal:
    " + + "

    python main.py

    " + + "or
    as_gradio main.py

    " + + "
    " +
                                 data.py_code +
    -                            '
    ', - showCloseButton: true, - showCancelButton: true, - confirmButtonText: 'Copy', - cancelButtonText: 'Close', - willOpen: (element) => { - const codeElement = element.querySelector('code'); - Prism.highlightElement(codeElement); - const copyButton = Swal.getConfirmButton(); - copyButton.addEventListener('click', () => { - copyToClipboard(codeElement.textContent); - }); - } - }); - } else { - const errorMessage = ` + "
    ", + showCloseButton: true, + showCancelButton: true, + confirmButtonText: "Copy", + cancelButtonText: "Close", + willOpen: (element) => { + const codeElement = element.querySelector("code"); + Prism.highlightElement(codeElement); + const copyButton = Swal.getConfirmButton(); + copyButton.addEventListener("click", () => { + copyToClipboard(codeElement.textContent); + }); + } + }); + } else { + const errorMessage = `

    An error occurred during the Python code generation process. Please check the following error:

    ${data.py_code}
    `; - Swal.fire({ - title: 'Error!', - html: errorMessage, - icon: 'error', - customClass: { - popup: 'error-popup' - }, - confirmButtonText: 'Close', - willOpen: (element) => { - const codeElement = element.querySelector('code'); - Prism.highlightElement(codeElement); - } - }); - } - }) - .catch(error => { - console.error('Error:', error); - Swal.fire('Failed!', - 'There was an error generating your code.', - 'error'); - }); - } + Swal.fire({ + title: "Error!", + html: errorMessage, + icon: "error", + customClass: { + popup: "error-popup" + }, + confirmButtonText: "Close", + willOpen: (element) => { + const codeElement = element.querySelector("code"); + Prism.highlightElement(codeElement); + } + }); + } + }) + .catch(error => { + console.error("Error:", error); + Swal.fire("Failed!", + "There was an error generating your code.", + "error"); + }); + } } function showExportRunPopup(version) { - if (version === "local") { - showExportRunLocalPopup(); - } else { - showExportRunMSPopup(); - } + if (version === "local") { + showExportRunLocalPopup(); + } else { + showExportRunMSPopup(); + } } function showExportRunLocalPopup() { - if (checkConditions()) { - const rawData = editor.export(); - const hasError = sortElementsByPosition(rawData); - if (hasError) { - return; - } - const filteredData = reorganizeAndFilterConfigForAgentScope(rawData); + if (checkConditions()) { + const rawData = editor.export(); + const hasError = sortElementsByPosition(rawData); + if (hasError) { + return; + } + const filteredData = reorganizeAndFilterConfigForAgentScope(rawData); - Swal.fire({ - title: 'Processing...', - text: 'Please wait.', - allowOutsideClick: false, - willOpen: () => { - Swal.showLoading() - } - }); + Swal.fire({ + title: "Processing...", + text: "Please wait.", + allowOutsideClick: false, + willOpen: () => { + Swal.showLoading(); + } + }); - fetch('/convert-to-py-and-run', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - data: JSON.stringify(filteredData, null, 4), - }) - }).then(response => { - if (!response.ok) { - throw new Error('Network error.'); - } - return response.json(); - }) - .then(data => { - Swal.close(); - if (data.is_success === 'True') { - Swal.fire({ - title: 'Application Running in Background', - html: - '

    Your application has been successfully run ' + - 'in background.
    ' + - '

    Task ID:' + - data.run_id + '

    ' + - '
    ' +
    +    fetch("/convert-to-py-and-run", {
    +      method: "POST",
    +      headers: {
    +        "Content-Type": "application/json",
    +      },
    +      body: JSON.stringify({
    +        data: JSON.stringify(filteredData, null, 4),
    +      })
    +    }).then(response => {
    +      if (!response.ok) {
    +        throw new Error("Network error.");
    +      }
    +      return response.json();
    +    })
    +      .then(data => {
    +        Swal.close();
    +        if (data.is_success === "True") {
    +          Swal.fire({
    +            title: "Application Running in Background",
    +            html:
    +                            "

    Your application has been successfully run " + + "in background.
    " + + "

    Task ID:" + + data.run_id + "

    " + + "
    " +
                                 data.py_code +
    -                            '
    ', - showCloseButton: true, - showCancelButton: true, - confirmButtonText: 'Copy Code', - cancelButtonText: 'Close', - willOpen: (element) => { - const codeElement = element.querySelector('code'); - Prism.highlightElement(codeElement); - const copyButton = Swal.getConfirmButton(); - copyButton.addEventListener('click', () => { - copyToClipboard(codeElement.textContent); - }); - } - }); - } else { - const errorMessage = ` + "
    ", + showCloseButton: true, + showCancelButton: true, + confirmButtonText: "Copy Code", + cancelButtonText: "Close", + willOpen: (element) => { + const codeElement = element.querySelector("code"); + Prism.highlightElement(codeElement); + const copyButton = Swal.getConfirmButton(); + copyButton.addEventListener("click", () => { + copyToClipboard(codeElement.textContent); + }); + } + }); + } else { + const errorMessage = `

    An error occurred during the Python code running process. Please check the following error:

    ${data.py_code}
    `; - Swal.fire({ - title: 'Error!', - html: errorMessage, - icon: 'error', - customClass: { - popup: 'error-popup' - }, - confirmButtonText: 'Close', - willOpen: (element) => { - const codeElement = element.querySelector('code'); - Prism.highlightElement(codeElement); - } - }); - } - }) - .catch(error => { - console.error('Error:', error); - Swal.close(); - Swal.fire('Failed!', - 'There was an error running your workflow.', - 'error'); - }); - } + Swal.fire({ + title: "Error!", + html: errorMessage, + icon: "error", + customClass: { + popup: "error-popup" + }, + confirmButtonText: "Close", + willOpen: (element) => { + const codeElement = element.querySelector("code"); + Prism.highlightElement(codeElement); + } + }); + } + }) + .catch(error => { + console.error("Error:", error); + Swal.close(); + Swal.fire("Failed!", + "There was an error running your workflow.", + "error"); + }); + } } function filterOutApiKey(obj) { - for (let key in obj) { - if (typeof obj[key] === 'object' && obj[key] !== null) { - filterOutApiKey(obj[key]); - } - if (key === 'api_key') { - delete obj[key]; - } + for (const key in obj) { + if (typeof obj[key] === "object" && obj[key] !== null) { + filterOutApiKey(obj[key]); + } + if (key === "api_key") { + delete obj[key]; } + } } function showExportRunMSPopup() { - if (checkConditions()) { - Swal.fire({ - title: 'Are you sure to run the workflow in ModelScope Studio?', - text: + if (checkConditions()) { + Swal.fire({ + title: "Are you sure to run the workflow in ModelScope Studio?", + text: "You are about to navigate to another page. " + "Please make sure all the configurations are set " + "besides your api-key " + "(your api-key should be set in ModelScope Studio page).", - icon: 'warning', - showCancelButton: true, - confirmButtonColor: '#3085d6', - cancelButtonColor: '#d33', - confirmButtonText: 'Yes, create it!', - cancelButtonText: 'Close' - }).then((result) => { - if (result.isConfirmed) { - const rawData = editor.export(); - const hasError = sortElementsByPosition(rawData); - if (hasError) { - return; - } - const filteredData = reorganizeAndFilterConfigForAgentScope(rawData); - filterOutApiKey(filteredData) - - Swal.fire({ - title: 'Processing...', - text: 'Please wait.', - allowOutsideClick: false, - willOpen: () => { - Swal.showLoading() - } - }); - fetch('/upload-to-oss', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - data: JSON.stringify(filteredData, null, 4), - }) - }) - .then(response => response.json()) - .then(data => { - const params = {'CONFIG_URL': data.config_url}; - const paramsStr = encodeURIComponent(JSON.stringify(params)); - const org = "agentscope"; - const fork_repo = "agentscope_workstation"; - const url = `https://www.modelscope.cn/studios/fork?target=${org}/${fork_repo}&overwriteEnv=${paramsStr}`; - window.open(url, '_blank'); - Swal.fire('Success!', '', 'success'); - }) - .catch(error => { - console.error('Error:', error); - Swal.fire('Failed', data.message || 'An error occurred while uploading to oss', 'error'); - }); - } + icon: "warning", + showCancelButton: true, + confirmButtonColor: "#3085d6", + cancelButtonColor: "#d33", + confirmButtonText: "Yes, create it!", + cancelButtonText: "Close" + }).then((result) => { + if (result.isConfirmed) { + const rawData = editor.export(); + const hasError = sortElementsByPosition(rawData); + if (hasError) { + return; + } + const filteredData = reorganizeAndFilterConfigForAgentScope(rawData); + filterOutApiKey(filteredData); + + Swal.fire({ + title: "Processing...", + text: "Please wait.", + allowOutsideClick: false, + willOpen: () => { + Swal.showLoading(); + } + }); + fetch("/upload-to-oss", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + data: JSON.stringify(filteredData, null, 4), + }) }) - } + .then(response => response.json()) + .then(data => { + const params = {"CONFIG_URL": data.config_url}; + const paramsStr = encodeURIComponent(JSON.stringify(params)); + const org = "agentscope"; + const fork_repo = "agentscope_workstation"; + const url = `https://www.modelscope.cn/studios/fork?target=${org}/${fork_repo}&overwriteEnv=${paramsStr}`; + window.open(url, "_blank"); + Swal.fire("Success!", "", "success"); + }) + .catch(error => { + console.error("Error:", error); + Swal.fire("Failed", data.message || "An error occurred while uploading to oss", "error"); + }); + } + }); + } } function showExportHTMLPopup() { - const rawData = editor.export(); - - // Remove the html attribute from the nodes to avoid inconsistencies in html - removeHtmlFromUsers(rawData); - const hasError = sortElementsByPosition(rawData); - if (hasError) { - return; - } - - const exportData = JSON.stringify(rawData, null, 4); + const rawData = editor.export(); + + // Remove the html attribute from the nodes to avoid inconsistencies in html + removeHtmlFromUsers(rawData); + const hasError = sortElementsByPosition(rawData); + if (hasError) { + return; + } + + const exportData = JSON.stringify(rawData, null, 4); + + const escapedExportData = exportData + .replace(//g, ">"); + + Swal.fire({ + title: "Workflow HTML", + html: + "

    This is used for generating HTML code, not for running.
    " + + "

    "
    +            + escapedExportData +
    +            "
    ", + showCloseButton: true, + showCancelButton: true, + confirmButtonText: "Copy", + cancelButtonText: "Close", + willOpen: (element) => { + // Find the code element inside the Swal content + const codeElement = element.querySelector("code"); - const escapedExportData = exportData - .replace(//g, '>'); + // Now highlight the code element with Prism + Prism.highlightElement(codeElement); - Swal.fire({ - title: 'Workflow HTML', - html: - '

    This is used for generating HTML code, not for running.
    ' + - '

    '
    -            + escapedExportData +
    -            '
    ', - showCloseButton: true, - showCancelButton: true, - confirmButtonText: 'Copy', - cancelButtonText: 'Close', - willOpen: (element) => { - // Find the code element inside the Swal content - const codeElement = element.querySelector('code'); - - // Now highlight the code element with Prism - Prism.highlightElement(codeElement); - - // Copy to clipboard logic - const content = codeElement.textContent; - const copyButton = Swal.getConfirmButton(); - copyButton.addEventListener('click', () => { - copyToClipboard(content); - }); - } - }); + // Copy to clipboard logic + const content = codeElement.textContent; + const copyButton = Swal.getConfirmButton(); + copyButton.addEventListener("click", () => { + copyToClipboard(content); + }); + } + }); } function isValidDataStructure(data) { - if ( - data.hasOwnProperty('drawflow') && - data.drawflow.hasOwnProperty('Home') && - data.drawflow.Home.hasOwnProperty('data') - ) { - - for (const nodeId in data.drawflow.Home.data) { - const node = data.drawflow.Home.data[nodeId]; - - if ( - !node.hasOwnProperty('id') || - typeof node.id !== 'number' || - !node.hasOwnProperty('name') || - typeof node.name !== 'string' || - !node.hasOwnProperty('class') || - typeof node.class !== 'string' - ) { - return false; - } - } - return true; + if ( + data.hasOwnProperty("drawflow") && + data.drawflow.hasOwnProperty("Home") && + data.drawflow.Home.hasOwnProperty("data") + ) { + + for (const nodeId in data.drawflow.Home.data) { + const node = data.drawflow.Home.data[nodeId]; + + if ( + !node.hasOwnProperty("id") || + typeof node.id !== "number" || + !node.hasOwnProperty("name") || + typeof node.name !== "string" || + !node.hasOwnProperty("class") || + typeof node.class !== "string" + ) { + return false; + } } - return false; + return true; + } + return false; } function showImportHTMLPopup() { - Swal.fire({ - title: 'Import Workflow Data', - html: + Swal.fire({ + title: "Import Workflow Data", + html: "

    Please paste your HTML data below. Ensure that the source of the HTML data is trusted, as importing HTML from unknown or untrusted sources may pose security risks.

    ", - input: 'textarea', - inputLabel: 'Paste your HTML data here:', - inputPlaceholder: - 'Paste your HTML data generated from `Export HTML` button...', - inputAttributes: { - 'aria-label': 'Paste your HTML data here', - 'class': 'code' - }, - customClass: { - input: 'code' - }, - showCancelButton: true, - confirmButtonText: 'Import', - cancelButtonText: 'Cancel', - inputValidator: (value) => { - if (!value) { - return 'You need to paste code generated from `Export HTML` button!'; - } - try { - const parsedData = JSON.parse(value); - if (isValidDataStructure(parsedData)) { - - } else { - return 'The data is invalid. Please check your data and try again.'; - } - } catch (e) { - return 'Invalid data! You need to paste code generated from `Export HTML` button!'; - } - }, - preConfirm: (data) => { - try { - const parsedData = JSON.parse(data); - - // Add html source code to the nodes data - addHtmlAndReplacePlaceHolderBeforeImport(parsedData) - .then(() => { - editor.clear(); - editor.import(parsedData); - importSetupNodes(parsedData); - Swal.fire('Imported!', '', 'success'); - }); - - } catch (error) { - Swal.showValidationMessage(`Import error: ${error}`); - } - } - }); + input: "textarea", + inputLabel: "Paste your HTML data here:", + inputPlaceholder: + "Paste your HTML data generated from `Export HTML` button...", + inputAttributes: { + "aria-label": "Paste your HTML data here", + "class": "code" + }, + customClass: { + input: "code" + }, + showCancelButton: true, + confirmButtonText: "Import", + cancelButtonText: "Cancel", + inputValidator: (value) => { + if (!value) { + return "You need to paste code generated from `Export HTML` button!"; + } + try { + const parsedData = JSON.parse(value); + if (isValidDataStructure(parsedData)) { + + } else { + return "The data is invalid. Please check your data and try again."; + } + } catch (e) { + return "Invalid data! You need to paste code generated from `Export HTML` button!"; + } + }, + preConfirm: (data) => { + try { + const parsedData = JSON.parse(data); + + // Add html source code to the nodes data + addHtmlAndReplacePlaceHolderBeforeImport(parsedData) + .then(() => { + editor.clear(); + editor.import(parsedData); + importSetupNodes(parsedData); + Swal.fire("Imported!", "", "success"); + }); + + } catch (error) { + Swal.showValidationMessage(`Import error: ${error}`); + } + } + }); } function showSaveWorkflowPopup() { - Swal.fire({ - title: 'Save Workflow', - input: 'text', - inputPlaceholder: 'Enter filename', - showCancelButton: true, - confirmButtonText: 'Save', - cancelButtonText: 'Cancel' - }).then(result => { - if (result.isConfirmed) { - const filename = result.value; - saveWorkflow(filename); - } - }); + Swal.fire({ + title: "Save Workflow", + input: "text", + inputPlaceholder: "Enter filename", + showCancelButton: true, + confirmButtonText: "Save", + cancelButtonText: "Cancel" + }).then(result => { + if (result.isConfirmed) { + const filename = result.value; + saveWorkflow(filename); + } + }); } function saveWorkflow(fileName) { - const rawData = editor.export(); - filterOutApiKey(rawData) - - // Remove the html attribute from the nodes to avoid inconsistencies in html - removeHtmlFromUsers(rawData); - - const exportData = JSON.stringify(rawData, null, 4); - fetch('/save-workflow', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - filename: fileName, - workflow: exportData, - overwrite: false, - }) - }).then(response => response.json()) - .then(data => { - if (data.message === "Workflow file saved successfully") { - Swal.fire('Success', data.message, 'success'); - } else { - Swal.fire('Error', data.message || 'An error occurred while saving the workflow.', 'error'); - } - }) - .catch(error => { - console.error('Error:', error); - Swal.fire('Error', 'An error occurred while saving the workflow.', 'error'); - }); + const rawData = editor.export(); + filterOutApiKey(rawData); + + // Remove the html attribute from the nodes to avoid inconsistencies in html + removeHtmlFromUsers(rawData); + + const exportData = JSON.stringify(rawData, null, 4); + fetch("/save-workflow", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + filename: fileName, + workflow: exportData, + overwrite: false, + }) + }).then(response => response.json()) + .then(data => { + if (data.message === "Workflow file saved successfully") { + Swal.fire("Success", data.message, "success"); + } else { + Swal.fire("Error", data.message || "An error occurred while saving the workflow.", "error"); + } + }) + .catch(error => { + console.error("Error:", error); + Swal.fire("Error", "An error occurred while saving the workflow.", "error"); + }); } function showLoadWorkflowPopup() { - fetch('/list-workflows', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({}) - }) - .then(response => response.json()) - .then(data => { - if (!Array.isArray(data.files)) { - throw new TypeError('The return data is not an array'); + fetch("/list-workflows", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({}) + }) + .then(response => response.json()) + .then(data => { + if (!Array.isArray(data.files)) { + throw new TypeError("The return data is not an array"); + } + const inputOptions = data.files.reduce((options, file) => { + options[file] = file; + return options; + }, {}); + Swal.fire({ + title: "Loading Workflow from Disks", + input: "select", + inputOptions: inputOptions, + inputPlaceholder: "Select", + showCancelButton: true, + showDenyButton: true, + confirmButtonText: "Load", + cancelButtonText: "Cancel", + denyButtonText: "Delete", + didOpen: () => { + const selectElement = Swal.getInput(); + selectElement.addEventListener("change", (event) => { + selectedFilename = event.target.value; + }); + } + }).then(result => { + if (result.isConfirmed) { + loadWorkflow(selectedFilename); + } else if (result.isDenied) { + Swal.fire({ + title: `Are you sure to delete ${selectedFilename}?`, + text: "This operation cannot be undone!", + icon: "warning", + showCancelButton: true, + confirmButtonColor: "#d33", + cancelButtonColor: "#3085d6", + confirmButtonText: "Delete", + cancelButtonText: "Cancel" + }).then((deleteResult) => { + if (deleteResult.isConfirmed) { + deleteWorkflow(selectedFilename); } - const inputOptions = data.files.reduce((options, file) => { - options[file] = file; - return options; - }, {}); - Swal.fire({ - title: 'Loading Workflow from Disks', - input: 'select', - inputOptions: inputOptions, - inputPlaceholder: 'Select', - showCancelButton: true, - showDenyButton: true, - confirmButtonText: 'Load', - cancelButtonText: 'Cancel', - denyButtonText: 'Delete', - didOpen: () => { - const selectElement = Swal.getInput(); - selectElement.addEventListener('change', (event) => { - selectedFilename = event.target.value; - }); - } - }).then(result => { - if (result.isConfirmed) { - loadWorkflow(selectedFilename); - } else if (result.isDenied) { - Swal.fire({ - title: `Are you sure to delete ${selectedFilename}?`, - text: "This operation cannot be undone!", - icon: 'warning', - showCancelButton: true, - confirmButtonColor: '#d33', - cancelButtonColor: '#3085d6', - confirmButtonText: 'Delete', - cancelButtonText: 'Cancel' - }).then((deleteResult) => { - if (deleteResult.isConfirmed) { - deleteWorkflow(selectedFilename); - } - }); - } - }); - }) - .catch(error => { - console.error('Error:', error); - Swal.fire('Error', 'An error occurred while loading the workflow.', 'error'); - }); + }); + } + }); + }) + .catch(error => { + console.error("Error:", error); + Swal.fire("Error", "An error occurred while loading the workflow.", "error"); + }); } function loadWorkflow(fileName) { - fetch('/load-workflow', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - filename: fileName, - }) - }).then(response => response.json()) - .then(data => { - if (data.error) { - Swal.fire('Error', data.error, 'error'); - } else { - console.log(data) - try { - // Add html source code to the nodes data - addHtmlAndReplacePlaceHolderBeforeImport(data) - .then(() => { - console.log(data) - editor.clear(); - editor.import(data); - importSetupNodes(data); - Swal.fire('Imported!', '', 'success'); - }); - - } catch (error) { - Swal.showValidationMessage(`Import error: ${error}`); - } - Swal.fire('Success', 'Workflow loaded successfully', 'success'); - } - }) - .catch(error => { - console.error('Error:', error); - Swal.fire('Error', 'An error occurred while loading the workflow.', 'error'); - }); + fetch("/load-workflow", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + filename: fileName, + }) + }).then(response => response.json()) + .then(data => { + if (data.error) { + Swal.fire("Error", data.error, "error"); + } else { + console.log(data); + try { + // Add html source code to the nodes data + addHtmlAndReplacePlaceHolderBeforeImport(data) + .then(() => { + console.log(data); + editor.clear(); + editor.import(data); + importSetupNodes(data); + Swal.fire("Imported!", "", "success"); + }); + + } catch (error) { + Swal.showValidationMessage(`Import error: ${error}`); + } + Swal.fire("Success", "Workflow loaded successfully", "success"); + } + }) + .catch(error => { + console.error("Error:", error); + Swal.fire("Error", "An error occurred while loading the workflow.", "error"); + }); } function deleteWorkflow(fileName) { - fetch('/delete-workflow', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - filename: fileName, - }) - }).then(response => response.json()) - .then(data => { - if (data.error) { - Swal.fire('Error', data.error, 'error'); - } else { - Swal.fire('Deleted!', 'Workflow has been deleted.', 'success'); - } - }) - .catch(error => { - console.error('Error:', error); - Swal.fire('Error', 'An error occurred while deleting the workflow.', 'error'); - }); + fetch("/delete-workflow", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + filename: fileName, + }) + }).then(response => response.json()) + .then(data => { + if (data.error) { + Swal.fire("Error", data.error, "error"); + } else { + Swal.fire("Deleted!", "Workflow has been deleted.", "success"); + } + }) + .catch(error => { + console.error("Error:", error); + Swal.fire("Error", "An error occurred while deleting the workflow.", "error"); + }); } function removeHtmlFromUsers(data) { - Object.keys(data.drawflow.Home.data).forEach((nodeId) => { - const node = data.drawflow.Home.data[nodeId]; - // Remove the html attribute from the node - delete node.html; - }); + Object.keys(data.drawflow.Home.data).forEach((nodeId) => { + const node = data.drawflow.Home.data[nodeId]; + // Remove the html attribute from the node + delete node.html; + }); } async function fetchHtmlSourceCodeByName(name) { - // Fetch the HTML source code from the cache if it exists - if (name in htmlCache) { - return htmlCache[name]; - } + // Fetch the HTML source code from the cache if it exists + if (name in htmlCache) { + return htmlCache[name]; + } - // Load the HTML source code - let htmlSourceCode = await fetchHtml(nameToHtmlFile[name]); - htmlCache[name] = htmlSourceCode; - return htmlSourceCode; + // Load the HTML source code + const htmlSourceCode = await fetchHtml(nameToHtmlFile[name]); + htmlCache[name] = htmlSourceCode; + return htmlSourceCode; } async function addHtmlAndReplacePlaceHolderBeforeImport(data) { - const idPlaceholderRegex = /ID_PLACEHOLDER/g; - for (const nodeId of Object.keys(data.drawflow.Home.data)) { - const node = data.drawflow.Home.data[nodeId]; - if (!node.html) { - if (node.name === "readme") { - // Remove the node if its name is "readme" - delete data.drawflow.Home.data[nodeId]; - continue; // Skip to the next iteration - } - console.log(node.name) - const sourceCode = await fetchHtmlSourceCodeByName(node.name); + const idPlaceholderRegex = /ID_PLACEHOLDER/g; + for (const nodeId of Object.keys(data.drawflow.Home.data)) { + const node = data.drawflow.Home.data[nodeId]; + if (!node.html) { + if (node.name === "readme") { + // Remove the node if its name is "readme" + delete data.drawflow.Home.data[nodeId]; + continue; // Skip to the next iteration + } + console.log(node.name); + const sourceCode = await fetchHtmlSourceCodeByName(node.name); - // Add new html attribute to the node - console.log(sourceCode) - node.html = sourceCode.replace(idPlaceholderRegex, nodeId); - } + // Add new html attribute to the node + console.log(sourceCode); + node.html = sourceCode.replace(idPlaceholderRegex, nodeId); } + } } function importSetupNodes(dataToImport) { - Object.keys(dataToImport.drawflow.Home.data).forEach((nodeId) => { - // import the node use addNode function - disableButtons(); - makeNodeTop(nodeId); - setupNodeListeners(nodeId); + Object.keys(dataToImport.drawflow.Home.data).forEach((nodeId) => { + // import the node use addNode function + disableButtons(); + makeNodeTop(nodeId); + setupNodeListeners(nodeId); + setupNodeCopyListens(nodeId); + addEventListenersToNumberInputs(nodeId); + setupTextInputListeners(nodeId); + reloadi18n(); + const nodeElement = document.getElementById(`node-${nodeId}`); + if (nodeElement) { + const copyButton = nodeElement.querySelector(".button.copy-button"); + if (copyButton) { setupNodeCopyListens(nodeId); - addEventListenersToNumberInputs(nodeId); - setupTextInputListeners(nodeId); - reloadi18n(); - const nodeElement = document.getElementById(`node-${nodeId}`); - if (nodeElement) { - const copyButton = nodeElement.querySelector('.button.copy-button'); - if (copyButton) { - setupNodeCopyListens(nodeId); - } - } - }); + } + } + }); } function copyToClipboard(contentToCopy) { - var tempTextarea = document.createElement("textarea"); - tempTextarea.value = contentToCopy; - document.body.appendChild(tempTextarea); - tempTextarea.select(); - tempTextarea.setSelectionRange(0, 99999); - - try { - var successful = document.execCommand("copy"); - if (successful) { - Swal.fire('Copied!', '', 'success'); - } else { - Swal.fire('Failed to copy', '', 'error'); - } - } catch (err) { - Swal.fire('Failed to copy', '', 'error'); + const tempTextarea = document.createElement("textarea"); + tempTextarea.value = contentToCopy; + document.body.appendChild(tempTextarea); + tempTextarea.select(); + tempTextarea.setSelectionRange(0, 99999); + + try { + const successful = document.execCommand("copy"); + if (successful) { + Swal.fire("Copied!", "", "success"); + } else { + Swal.fire("Failed to copy", "", "error"); } - document.body.removeChild(tempTextarea); + } catch (err) { + Swal.fire("Failed to copy", "", "error"); + } + document.body.removeChild(tempTextarea); } function fetchExample(index, processData) { - fetch('/read-examples', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - data: index, - // lang: getCookie('locale') || 'en', - lang: 'en', - }) - }).then(response => { - if (!response.ok) { - throw new Error('Network error.'); - } - return response.json(); + fetch("/read-examples", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + data: index, + // lang: getCookie('locale') || 'en', + lang: "en", }) - .then(processData); + }).then(response => { + if (!response.ok) { + throw new Error("Network error."); + } + return response.json(); + }) + .then(processData); } function importExample(index) { - fetchExample(index, data => { - const dataToImport = data.json; - - addHtmlAndReplacePlaceHolderBeforeImport(dataToImport) - .then(() => { - clearModuleSelected(); - editor.import(dataToImport); - Object.keys(dataToImport.drawflow.Home.data).forEach((nodeId) => { - setupNodeListeners(nodeId); - setupTextInputListeners(nodeId); - const nodeElement = document.getElementById(`node-${nodeId}`); - if (nodeElement) { - const copyButton = nodeElement.querySelector('.button.copy-button'); - if (copyButton) { - setupNodeCopyListens(nodeId); - } - } - }); - reloadi18n(); - }); - }) + fetchExample(index, data => { + const dataToImport = data.json; + + addHtmlAndReplacePlaceHolderBeforeImport(dataToImport) + .then(() => { + clearModuleSelected(); + editor.import(dataToImport); + Object.keys(dataToImport.drawflow.Home.data).forEach((nodeId) => { + setupNodeListeners(nodeId); + setupTextInputListeners(nodeId); + const nodeElement = document.getElementById(`node-${nodeId}`); + if (nodeElement) { + const copyButton = nodeElement.querySelector(".button.copy-button"); + if (copyButton) { + setupNodeCopyListens(nodeId); + } + } + }); + reloadi18n(); + }); + }); } function importExample_step(index) { - if (!localStorage.getItem('firstGuide')) { - localStorage.setItem('firstGuide', 'true'); - skipGuide(); - } - fetchExample(index, data => { - const dataToImportStep = data.json; - addHtmlAndReplacePlaceHolderBeforeImport(dataToImportStep).then(() => { - clearModuleSelected(); - descriptionStep = ["Readme", "Model", "UserAgent", - "DialogAgent"]; - initializeImport(dataToImportStep); - }) + if (!localStorage.getItem("firstGuide")) { + localStorage.setItem("firstGuide", "true"); + skipGuide(); + } + fetchExample(index, data => { + const dataToImportStep = data.json; + addHtmlAndReplacePlaceHolderBeforeImport(dataToImportStep).then(() => { + clearModuleSelected(); + descriptionStep = ["Readme", "Model", "UserAgent", + "DialogAgent"]; + initializeImport(dataToImportStep); }); + }); } function updateImportButtons() { - document.getElementById('import-prev').disabled = currentImportIndex + document.getElementById("import-prev").disabled = currentImportIndex <= 1; - document.getElementById('import-next').disabled = currentImportIndex >= importQueue.length; - document.getElementById('import-skip').disabled = currentImportIndex >= importQueue.length; - reloadi18n() + document.getElementById("import-next").disabled = currentImportIndex >= importQueue.length; + document.getElementById("import-skip").disabled = currentImportIndex >= importQueue.length; + reloadi18n(); } -function createElement(tag, id, html = '', parent = document.body) { - let element = document.getElementById(id) || document.createElement(tag); - element.id = id; - element.innerHTML = html; - if (!element.parentNode) { - parent.appendChild(element); - } - return element; +function createElement(tag, id, html = "", parent = document.body) { + const element = document.getElementById(id) || document.createElement(tag); + element.id = id; + element.innerHTML = html; + if (!element.parentNode) { + parent.appendChild(element); + } + return element; } function initializeImport(data) { - ['menu-btn', 'menu-btn-svg'].forEach(cls => { - let containers = document.getElementsByClassName(cls); - Array.from(containers).forEach(container => container.style.display = 'none'); - }); + ["menu-btn", "menu-btn-svg"].forEach(cls => { + const containers = document.getElementsByClassName(cls); + Array.from(containers).forEach(container => container.style.display = "none"); + }); - createElement('div', 'left-sidebar-blur', '', document.body).style.cssText = ` + createElement("div", "left-sidebar-blur", "", document.body).style.cssText = ` position: fixed; top: 60px; left: 0; bottom: 0; width: 250px; background: rgba(128, 128, 128, 0.7); filter: blur(2px); z-index: 1000; cursor: not-allowed; `; - createElement('div', 'import-buttons', '', document.body); + createElement("div", "import-buttons", "", document.body); - dataToImportStep = data; - importQueue = Object.keys(dataToImportStep.drawflow.Home.data); + dataToImportStep = data; + importQueue = Object.keys(dataToImportStep.drawflow.Home.data); - const importButtonsDiv = document.getElementById('import-buttons'); + const importButtonsDiv = document.getElementById("import-buttons"); - createElement('div', 'step-info', '', importButtonsDiv); - createElement('button', 'import-prev', - ' Previous', - importButtonsDiv).onclick = importPreviousComponent; - createElement('button', 'import-next', - ' Next', - importButtonsDiv).onclick = importNextComponent; - createElement('button', 'import-skip', - ' Skip', - importButtonsDiv).onclick = importSkipComponent; - createElement('button', 'import-quit', - ' Quit', - importButtonsDiv).onclick = importQuitComponent; - createElement('div', 'step-warning', - 'Caution: You are currently in the tutorial mode where modifications are restricted.
    Please click Quit to exit and start creating your custom multi-agent applications. ', document.body); + createElement("div", "step-info", "", importButtonsDiv); + createElement("button", "import-prev", + " Previous", + importButtonsDiv).onclick = importPreviousComponent; + createElement("button", "import-next", + " Next", + importButtonsDiv).onclick = importNextComponent; + createElement("button", "import-skip", + " Skip", + importButtonsDiv).onclick = importSkipComponent; + createElement("button", "import-quit", + " Quit", + importButtonsDiv).onclick = importQuitComponent; + createElement("div", "step-warning", + "Caution: You are currently in the tutorial mode where modifications are restricted.
    Please click Quit to exit and start creating your custom multi-agent applications. ", document.body); - accumulatedImportData = {}; - currentImportIndex = 0; - importNextComponent(); + accumulatedImportData = {}; + currentImportIndex = 0; + importNextComponent(); - updateImportButtons(); + updateImportButtons(); } function importPreviousComponent() { - if (currentImportIndex > 0) { - currentImportIndex--; - accumulatedImportData = Object.assign({}, ...importQueue.slice(0, currentImportIndex).map(k => ({[k]: dataToImportStep.drawflow.Home.data[k]}))); - editor.import({drawflow: {Home: {data: accumulatedImportData}}}); - updateStepInfo(); - } - updateImportButtons(); + if (currentImportIndex > 0) { + currentImportIndex--; + accumulatedImportData = Object.assign({}, ...importQueue.slice(0, currentImportIndex).map(k => ({[k]: dataToImportStep.drawflow.Home.data[k]}))); + editor.import({drawflow: {Home: {data: accumulatedImportData}}}); + updateStepInfo(); + } + updateImportButtons(); } function importNextComponent() { - const nodeId = importQueue[currentImportIndex]; - accumulatedImportData[nodeId] = dataToImportStep.drawflow.Home.data[nodeId]; + const nodeId = importQueue[currentImportIndex]; + accumulatedImportData[nodeId] = dataToImportStep.drawflow.Home.data[nodeId]; - editor.import({drawflow: {Home: {data: accumulatedImportData}}}); - currentImportIndex++; - updateStepInfo(); - updateImportButtons(); + editor.import({drawflow: {Home: {data: accumulatedImportData}}}); + currentImportIndex++; + updateStepInfo(); + updateImportButtons(); } function importSkipComponent() { - accumulatedImportData = Object.assign({}, ...importQueue.map(k => ({[k]: dataToImportStep.drawflow.Home.data[k]}))); - editor.import({drawflow: {Home: {data: accumulatedImportData}}}); - currentImportIndex = importQueue.length; - updateImportButtons(); - updateStepInfo(); + accumulatedImportData = Object.assign({}, ...importQueue.map(k => ({[k]: dataToImportStep.drawflow.Home.data[k]}))); + editor.import({drawflow: {Home: {data: accumulatedImportData}}}); + currentImportIndex = importQueue.length; + updateImportButtons(); + updateStepInfo(); } function importQuitComponent() { - clearModuleSelected(); - ['menu-btn', 'menu-btn-svg'].forEach(cls => { - let containers = document.getElementsByClassName(cls); - Array.from(containers).forEach(container => container.style.display = ''); - }); + clearModuleSelected(); + ["menu-btn", "menu-btn-svg"].forEach(cls => { + const containers = document.getElementsByClassName(cls); + Array.from(containers).forEach(container => container.style.display = ""); + }); } function updateStepInfo() { - let stepInfoDiv = document.getElementById('step-info'); - if (stepInfoDiv && currentImportIndex > 0) { - stepInfoDiv.innerHTML = + const stepInfoDiv = document.getElementById("step-info"); + if (stepInfoDiv && currentImportIndex > 0) { + stepInfoDiv.innerHTML = `Current Step (${currentImportIndex}/${importQueue.length})
    ${descriptionStep[currentImportIndex - 1]}`; - } else if (stepInfoDiv) { - stepInfoDiv.innerHTML = 'No steps to display.'; - } + } else if (stepInfoDiv) { + stepInfoDiv.innerHTML = "No steps to display."; + } } function clearModuleSelected() { - editor.clearModuleSelected(); + editor.clearModuleSelected(); - let importButtonsDiv = document.getElementById("import-buttons"); - if (importButtonsDiv) { - importButtonsDiv.remove(); - } + const importButtonsDiv = document.getElementById("import-buttons"); + if (importButtonsDiv) { + importButtonsDiv.remove(); + } - let stepWarningDiv = document.getElementById("step-warning"); - if (stepWarningDiv) { - stepWarningDiv.remove(); - } + const stepWarningDiv = document.getElementById("step-warning"); + if (stepWarningDiv) { + stepWarningDiv.remove(); + } - let blurDiv = document.getElementById('left-sidebar-blur'); - if (blurDiv) { - blurDiv.remove(); - } + const blurDiv = document.getElementById("left-sidebar-blur"); + if (blurDiv) { + blurDiv.remove(); + } } function getCookie(name) { - var matches = document.cookie.match(new RegExp( - "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)" - )); - return matches ? decodeURIComponent(matches[1]) : undefined; + const matches = document.cookie.match(new RegExp( + "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, "\\$1") + "=([^;]*)" + )); + return matches ? decodeURIComponent(matches[1]) : undefined; } function showSurveyModal() { - document.getElementById("surveyModal").style.display = "block"; + document.getElementById("surveyModal").style.display = "block"; } function hideSurveyModal() { - document.getElementById("surveyModal").style.display = "none"; + document.getElementById("surveyModal").style.display = "none"; } function reloadi18n() { - let currentLang = getCookie('locale') || 'en'; - $("[i18n]").i18n({ - defaultLang: currentLang, - filePath: "../static/i18n/", - filePrefix: "i18n_", - fileSuffix: "", - forever: true, - callback: function () { - } - }); + const currentLang = getCookie("locale") || "en"; + $("[i18n]").i18n({ + defaultLang: currentLang, + filePath: "../static/i18n/", + filePrefix: "i18n_", + fileSuffix: "", + forever: true, + callback: function () { + } + }); } -window.addEventListener('storage', function (event) { - if (event.key === 'locale') { - reloadi18n() - } +window.addEventListener("storage", function (event) { + if (event.key === "locale") { + reloadi18n(); + } }, false); function startGuide() { - const targetElement = document.querySelector('.guide-Example'); - const element = document.querySelector('.tour-guide'); - positionElementRightOf(element, targetElement); + const targetElement = document.querySelector(".guide-Example"); + const element = document.querySelector(".tour-guide"); + positionElementRightOf(element, targetElement); } function getElementCoordinates(targetElement) { - const style = window.getComputedStyle(targetElement); - const rect = targetElement.getBoundingClientRect(); - return { - left: rect.left + (parseFloat(style.left) || 0), - top: rect.top + (parseFloat(style.top) || 0), - right: rect.right + (parseFloat(style.top) || 0), - bottom: rect.bottom + (parseFloat(style.top) || 0), - width: rect.width, - height: rect.height, - x: rect.x, - y: rect.y, - }; + const style = window.getComputedStyle(targetElement); + const rect = targetElement.getBoundingClientRect(); + return { + left: rect.left + (parseFloat(style.left) || 0), + top: rect.top + (parseFloat(style.top) || 0), + right: rect.right + (parseFloat(style.top) || 0), + bottom: rect.bottom + (parseFloat(style.top) || 0), + width: rect.width, + height: rect.height, + x: rect.x, + y: rect.y, + }; } function positionElementRightOf(element, targetElement) { - const targetCoordinates = getElementCoordinates(targetElement); - const mask = document.querySelector(".overlay"); - mask.style.display = "block"; - element.style.position = 'absolute'; - element.style.display = 'block'; - element.style.left = `${targetCoordinates.x + targetCoordinates.right}px`; - element.style.top = `${targetCoordinates.y}px`; + const targetCoordinates = getElementCoordinates(targetElement); + const mask = document.querySelector(".overlay"); + mask.style.display = "block"; + element.style.position = "absolute"; + element.style.display = "block"; + element.style.left = `${targetCoordinates.x + targetCoordinates.right}px`; + element.style.top = `${targetCoordinates.y}px`; } function skipGuide() { - const element = document.querySelector(".tour-guide"); - const mask = document.querySelector(".overlay"); - localStorage.setItem('firstGuide', 'true'); - if (element) { - element.style.display = "none"; - element.remove(); - mask.style.display = "none"; - mask.remove(); - } + const element = document.querySelector(".tour-guide"); + const mask = document.querySelector(".overlay"); + localStorage.setItem("firstGuide", "true"); + if (element) { + element.style.display = "none"; + element.remove(); + mask.style.display = "none"; + mask.remove(); + } } class Notification { - static count = 0; - static instances = []; - - static clearInstances() { - Notification.count = 0; - Notification.instances = []; - } - - constructor(props) { - Notification.count += 1; - Notification.instances.push(this); - this.currentIndex = Notification.count; - this.position = 'bottom-right'; - this.title = 'Notification Title'; - this.content = 'Notification Content'; - this.element = null; - this.closeBtn = true; - this.progress = false; - this.intervalTime = 3000; - this.confirmBtn = false; - this.cancelBtn = false; + static initStatics() { + this.count = 0; + this.instances = []; + } + + static clearInstances() { + Notification.count = 0; + Notification.instances = []; + } + + constructor(props) { + Notification.count += 1; + Notification.instances.push(this); + this.currentIndex = Notification.count; + this.position = "bottom-right"; + this.title = "Notification Title"; + this.content = "Notification Content"; + this.element = null; + this.closeBtn = true; + this.progress = false; + this.intervalTime = 3000; + this.confirmBtn = false; + this.cancelBtn = false; + this.pause = true; + this.reduceNumber = 0; + + // 绑定 this + this.destroyAll = this.destroyAll.bind(this); + this.onCancelCallback = this.onCancelCallback.bind(this); + this.onConfirmCallback = this.onConfirmCallback.bind(this); + + this.init(props); + } + + init(props) { + this.setDefaultValues(props); + this.element = document.createElement("div"); + this.element.className = "notification"; + this.title && this.renderTitle(getCookie("locale") == "zh" ? props.i18nTitle : this.title); + this.closeBtn && this.renderCloseButton(); + this.content && this.renderContent(getCookie("locale") == "zh" ? props.i18nContent : this.content); + (this.confirmBtn || this.cancelBtn) && this.renderClickButton(); + this.progress && this.renderProgressBar(); + this.setPosition(this.position); + document.body.appendChild(this.element); + setTimeout(() => { + this.show(); + }, 10); + } + + isHTMLString(string) { + const doc = new DOMParser().parseFromString(string, "text/html"); + return Array.from(doc.body.childNodes).some(node => node.nodeType === 1); + } + + renderCloseButton() { + this.closeBtn = document.createElement("span"); + this.closeBtn.className = "notification-close"; + this.closeBtn.innerText = "X"; + this.closeBtn.onclick = this.destroyAll; + this.title.appendChild(this.closeBtn); + } + + renderTitle(component) { + if (this.isHTMLString(component)) { + this.title = document.createElement("div"); + this.title.className = "notification-title"; + this.title.innerHTML = component; + } else { + this.title = document.createElement("div"); + this.titleText = document.createElement("div"); + this.title.className = "notification-title"; + this.titleText.className = "notification-titleText"; + this.titleText.innerText = component; + this.title.appendChild(this.titleText); + } + this.element.appendChild(this.title); + } + + renderContent(component) { + if (this.isHTMLString(component)) { + this.content = document.createElement("div"); + this.content.className = "notification-content"; + this.content.innerHTML = component; + } else { + this.content = document.createElement("div"); + this.content.className = "notification-content"; + this.content.innerText = component; + } + this.element.appendChild(this.content); + } + + renderClickButton() { + if (this.confirmBtn || this.cancelBtn) { + this.clickBottonBox = document.createElement("div"); + this.clickBottonBox.className = "notification-clickBotton-box"; + } + if (this.confirmBtn) { + this.confirmBotton = document.createElement("button"); + this.confirmBotton.className = "notification-btn confirmBotton"; + this.confirmBotton.innerText = getCookie("locale") == "zh" ? this.i18nConfirmBtn : this.confirmBtn; + this.confirmBotton.onclick = this.onConfirmCallback; + this.clickBottonBox.appendChild(this.confirmBotton); + } + if (this.cancelBtn) { + this.cancelBotton = document.createElement("button"); + this.cancelBotton.className = "notification-btn cancelBotton"; + this.cancelBotton.innerText = getCookie("locale") == "zh" ? this.i18nCancelBtn : this.cancelBtn; + this.cancelBotton.onclick = this.onCancelCallback; + this.clickBottonBox.appendChild(this.cancelBotton); + } + this.element.appendChild(this.clickBottonBox); + } + + renderProgressBar() { + this.progressBar = document.createElement("div"); + this.progressBar.className = "notification-progress"; + this.element.appendChild(this.progressBar); + } + + stepProgressBar(callback) { + const startTime = performance.now(); + const step = (timestamp) => { + const progress = Math.min((timestamp + this.reduceNumber - startTime) / this.intervalTime, 1); + this.progressBar.style.width = (1 - progress) * 100 + "%"; + if (progress < 1 && this.pause === false) { + requestAnimationFrame(step); + } else { + this.reduceNumber = timestamp + this.reduceNumber - startTime; + } + if (progress === 1) { this.pause = true; this.reduceNumber = 0; - this.init(props); - } - - init(props) { - this.setDefaultValues(props); - this.element = document.createElement('div'); - // init notification-box css - this.element.className = 'notification'; - // render title - this.title && this.renderTitle(getCookie("locale") == "zh" ? props.i18nTitle : this.title); - // render closeButtion - this.closeBtn && this.renderCloseButton(); - // render content - this.content && this.renderContent(getCookie("locale") == "zh" ? props.i18nContent : this.content); - // render confirmBtn - (this.confirmBtn || this.cancelBtn) && this.renderClickButton(); - this.progress && this.renderProgressBar(); - // set position - this.setPosition(this.position); - document.body.appendChild(this.element); - setTimeout(() => { - this.show(); - }, 10) - } - - // check if string is HTML - isHTMLString(string) { - const doc = new DOMParser().parseFromString(string, 'text/html'); - return Array.from(doc.body.childNodes).some(node => node.nodeType === 1); - } - - // render closeButtion - renderCloseButton() { - this.closeBtn = document.createElement('span'); - this.closeBtn.className = 'notification-close'; - this.closeBtn.innerText = 'X'; - this.closeBtn.onclick = this.destroyAll.bind(this); - this.title.appendChild(this.closeBtn); - } - - // render title string or HTML - renderTitle(component) { - if (this.isHTMLString(component)) { - this.title = document.createElement('div'); - this.title.className = 'notification-title'; - this.title.innerHTML = component; - } else { - this.title = document.createElement('div'); - this.titleText = document.createElement('div'); - this.title.className = 'notification-title'; - this.titleText.className = 'notification-titleText'; - this.titleText.innerText = component; - this.title.appendChild(this.titleText); - } - this.element.appendChild(this.title); - } - - // render content string or HTML - renderContent(component) { - if (this.isHTMLString(component)) { - this.content = document.createElement('div'); - this.content.className = 'notification-content'; - this.content.innerHTML = component; - } else { - this.content = document.createElement('div'); - this.content.className = 'notification-content'; - this.content.innerText = component; - } - this.element.appendChild(this.content); - } - - // render clickbtn - renderClickButton() { - if (this.confirmBtn || this.cancelBtn) { - this.clickBottonBox = document.createElement('div'); - this.clickBottonBox.className = 'notification-clickBotton-box'; - } - if (this.confirmBtn) { - this.confirmBotton = document.createElement('button'); - this.confirmBotton.className = 'notification-btn confirmBotton'; - this.confirmBotton.innerText = getCookie("locale") == "zh" ? this.i18nConfirmBtn : this.confirmBtn; - this.confirmBotton.onclick = this.onConfirmCallback.bind(this); - this.clickBottonBox.appendChild(this.confirmBotton); - } - if (this.cancelBtn) { - this.cancelBotton = document.createElement('button'); - this.cancelBotton.className = 'notification-btn cancelBotton'; - this.cancelBotton.innerText = getCookie("locale") == "zh" ? this.i18nCancelBtn : this.cancelBtn; - this.cancelBotton.onclick = this.onCancelCallback.bind(this); - this.clickBottonBox.appendChild(this.cancelBotton); - } - this.element.appendChild(this.clickBottonBox); - } - - // render progress bar - renderProgressBar() { - this.progressBar = document.createElement('div'); - this.progressBar.className = 'notification-progress'; - this.element.appendChild(this.progressBar); - } - - // stepProgressBar - stepProgressBar(callback) { - let startTime = performance.now(); - const step = (timestamp) => { - const progress = Math.min((timestamp + this.reduceNumber - startTime) / this.intervalTime, 1); - this.progressBar.style.width = (1 - progress) * 100 + '%'; - if (progress < 1 && this.pause == false) { - requestAnimationFrame(step) - } else { - this.reduceNumber = timestamp + this.reduceNumber - startTime - } - if (progress == 1) { - this.pause == true; - this.reduceNumber = 0; - callback(); - this.removeChild(); - } - } - requestAnimationFrame(step); - } - - setDefaultValues(props) { - for (const key in props) { - if (props[key] === undefined) { - return; - } else { - this[key] = props[key]; - } - } - } - - setPosition() { - switch (this.position) { - case 'top-left': - this.element.style.top = '25px'; - this.element.style.left = '-100%'; - break; - case 'top-right': - this.element.style.top = '25px'; - this.element.style.right = '-100%'; - break; - case 'bottom-right': - this.element.style.bottom = '25px'; - this.element.style.right = '-100%'; - break; - case 'bottom-left': - this.element.style.bottom = '25px'; - this.element.style.left = '-100%'; - break; - } - } - - show() { - this.element.style.display = 'flex'; - switch (this.position) { - case 'top-left': - this.element.style.top = '25px'; - this.element.style.left = '25px'; - break; - case 'top-right': - this.element.style.top = '25px'; - this.element.style.right = '25px'; - break; - case 'bottom-right': - this.element.style.bottom = '25px'; - this.element.style.right = '25px'; - break; - case 'bottom-left': - this.element.style.bottom = '25px'; - this.element.style.left = '25px'; - break; - } - } - - // hide() { - // // this.element.style.display = 'none'; - // } - destroyAll() { - for (const instance of Notification.instances) { - document.body.removeChild(instance.element); - } - Notification.clearInstances(); - } - - removeChild() { - let removeIndex; - for (let i = 0; i < Notification.instances.length; i++) { - if (Notification.instances[i].currentIndex === this.currentIndex) { - removeIndex = i; - break; - } - } - if (removeIndex !== undefined) { - Notification.instances.splice(removeIndex, 1); - } - this.element.remove(); - } - - addCloseListener() { - this.closeBtn.addEventListener('click', () => { - this.removeChild(); - }); - } + callback(); + this.removeChild(); + } + }; + requestAnimationFrame(step); + } + + setDefaultValues(props) { + for (const key in props) { + if (props[key] !== undefined) { + this[key] = props[key]; + } + } + } + + setPosition() { + switch (this.position) { + case "top-left": + this.element.style.top = "25px"; + this.element.style.left = "-100%"; + break; + case "top-right": + this.element.style.top = "25px"; + this.element.style.right = "-100%"; + break; + case "bottom-right": + this.element.style.bottom = "25px"; + this.element.style.right = "-100%"; + break; + case "bottom-left": + this.element.style.bottom = "25px"; + this.element.style.left = "-100%"; + break; + } + } + + show() { + this.element.style.display = "flex"; + switch (this.position) { + case "top-left": + this.element.style.top = "25px"; + this.element.style.left = "25px"; + break; + case "top-right": + this.element.style.top = "25px"; + this.element.style.right = "25px"; + break; + case "bottom-right": + this.element.style.bottom = "25px"; + this.element.style.right = "25px"; + break; + case "bottom-left": + this.element.style.bottom = "25px"; + this.element.style.left = "25px"; + break; + } + } + + destroyAll() { + for (const instance of Notification.instances) { + document.body.removeChild(instance.element); + } + Notification.clearInstances(); + } + + removeChild() { + let removeIndex; + for (let i = 0; i < Notification.instances.length; i++) { + if (Notification.instances[i].currentIndex === this.currentIndex) { + removeIndex = i; + break; + } + } + if (removeIndex !== undefined) { + Notification.instances.splice(removeIndex, 1); + } + this.element.remove(); + } + + addCloseListener() { + this.closeBtn.addEventListener("click", () => { + this.removeChild(); + }); + } - onCancelCallback() { - if (typeof this.onCancel === 'function') { - this.onCancel(); - this.removeChild(); - } + onCancelCallback() { + if (typeof this.onCancel === "function") { + this.onCancel(); + this.removeChild(); } + } - onConfirmCallback() { - if (typeof this.onConfirm === 'function') { - this.pause = !this.pause - if (!this.pause) { - this.stepProgressBar(this.onConfirm); - this.confirmBotton.innerText = getCookie("locale") == "zh" ? '暂停' : 'pause' - } else { - this.confirmBotton.innerText = this.confirmBtn - } - } + onConfirmCallback() { + if (typeof this.onConfirm === "function") { + this.pause = !this.pause; + if (!this.pause) { + this.stepProgressBar(this.onConfirm); + this.confirmBotton.innerText = getCookie("locale") === "zh" ? "暂停" : "pause"; + } else { + this.confirmBotton.innerText = this.confirmBtn; + } } + } } +// 初始化静态属性 +Notification.initStatics(); + function createNotification(props) { - new Notification(props); + new Notification(props); } function setCookie(name, value, days) { - var expires = ""; - if (days) { - var date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = "; expires=" + date.toUTCString(); - } - document.cookie = name + "=" + (value || "") + expires + "; path=/"; + let expires = ""; + if (days) { + const date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = "; expires=" + date.toUTCString(); + } + document.cookie = name + "=" + (value || "") + expires + "; path=/"; } -document.addEventListener('DOMContentLoaded', function() { - showTab('tab1'); +document.addEventListener("DOMContentLoaded", function () { + showTab("tab1"); }); function sendWorkflow(fileName) { - Swal.fire({ - text: 'Are you sure you want to import this workflow?', - icon: 'warning', - showCancelButton: true, - confirmButtonText: 'Yes, import it!', - cancelButtonText: 'Cancel' - }).then((result) => { - if (result.isConfirmed) { - const workstationUrl = '/workstation?filename=' + encodeURIComponent(fileName); - window.location.href = workstationUrl; - } - }); + Swal.fire({ + text: "Are you sure you want to import this workflow?", + icon: "warning", + showCancelButton: true, + confirmButtonText: "Yes, import it!", + cancelButtonText: "Cancel" + }).then((result) => { + if (result.isConfirmed) { + const workstationUrl = "/workstation?filename=" + encodeURIComponent(fileName); + window.location.href = workstationUrl; + } + }); } function showEditorTab() { - document.getElementById('col-right').style.display = 'block'; - document.getElementById('col-right2').style.display = 'none'; - console.log('Show Editor'); + document.getElementById("col-right").style.display = "block"; + document.getElementById("col-right2").style.display = "none"; + console.log("Show Editor"); } + function importGalleryWorkflow(data) { - try { - const parsedData = JSON.parse(data); - addHtmlAndReplacePlaceHolderBeforeImport(parsedData) - .then(() => { - editor.clear(); - editor.import(parsedData); - importSetupNodes(parsedData); - Swal.fire({ - title: 'Imported!', - icon: 'success', - showConfirmButton: true - }).then((result) => { - if (result.isConfirmed) { - showEditorTab(); - } - }); - }); - } catch (error) { - Swal.showValidationMessage(`Import error: ${error}`); - } + try { + const parsedData = JSON.parse(data); + addHtmlAndReplacePlaceHolderBeforeImport(parsedData) + .then(() => { + editor.clear(); + editor.import(parsedData); + importSetupNodes(parsedData); + Swal.fire({ + title: "Imported!", + icon: "success", + showConfirmButton: true + }).then((result) => { + if (result.isConfirmed) { + showEditorTab(); + } + }); + }); + } catch (error) { + Swal.showValidationMessage(`Import error: ${error}`); + } } function deleteWorkflow(fileName) { - Swal.fire({ - title: 'Are you sure?', - text: "Workflow will be deleted!", - icon: 'warning', - showCancelButton: true, - confirmButtonColor: '#3085d6', - cancelButtonColor: '#d33', - confirmButtonText: 'Yes, delete it!' - }).then((result) => { - if (result.isConfirmed) { - fetch('/delete-workflow', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - filename: fileName, - }) - }).then(response => response.json()) - .then(data => { - if (data.error) { - Swal.fire('Error', data.error, 'error'); - } else { - showLoadWorkflowList('tab2'); - Swal.fire('Deleted!', 'Your workflow has been deleted.', 'success'); - } - }) - .catch(error => { - console.error('Error:', error); - Swal.fire('Error', 'Delete workflow error.', 'error'); - }); - } - }); + Swal.fire({ + title: "Are you sure?", + text: "Workflow will be deleted!", + icon: "warning", + showCancelButton: true, + confirmButtonColor: "#3085d6", + cancelButtonColor: "#d33", + confirmButtonText: "Yes, delete it!" + }).then((result) => { + if (result.isConfirmed) { + fetch("/delete-workflow", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + filename: fileName, + }) + }).then(response => response.json()) + .then(data => { + if (data.error) { + Swal.fire("Error", data.error, "error"); + } else { + showLoadWorkflowList("tab2"); + Swal.fire("Deleted!", "Your workflow has been deleted.", "success"); + } + }) + .catch(error => { + console.error("Error:", error); + Swal.fire("Error", "Delete workflow error.", "error"); + }); + } + }); } function showTab(tabId) { - var tabs = document.getElementsByClassName("tab"); - for (var i = 0; i < tabs.length; i++) { - tabs[i].classList.remove("active"); - tabs[i].style.display = "none"; - } - var tab = document.getElementById(tabId); - if (tab) { - tab.classList.add("active"); - tab.style.display = "block"; - - var tabButtons = document.getElementsByClassName("tab-button"); - for (var j = 0; j < tabButtons.length; j++) { - tabButtons[j].classList.remove("active"); - } - var activeTabButton = document.querySelector(`.tab-button[onclick*="${tabId}"]`); - if (activeTabButton) { - activeTabButton.classList.add("active"); - } + const tabs = document.getElementsByClassName("tab"); + for (let i = 0; i < tabs.length; i++) { + tabs[i].classList.remove("active"); + tabs[i].style.display = "none"; + } + const tab = document.getElementById(tabId); + if (tab) { + tab.classList.add("active"); + tab.style.display = "block"; - if (tabId === "tab2") { - showLoadWorkflowList(tabId); - } else if (tabId === "tab1") { - showGalleryWorkflowList(tabId); - } + const tabButtons = document.getElementsByClassName("tab-button"); + for (let j = 0; j < tabButtons.length; j++) { + tabButtons[j].classList.remove("active"); + } + const activeTabButton = document.querySelector(`.tab-button[onclick*="${tabId}"]`); + if (activeTabButton) { + activeTabButton.classList.add("active"); } + + if (tabId === "tab2") { + showLoadWorkflowList(tabId); + } else if (tabId === "tab1") { + showGalleryWorkflowList(tabId); + } + } } let galleryWorkflows = []; function showGalleryWorkflowList(tabId) { - const container = document.getElementById(tabId).querySelector('.grid-container'); - container.innerHTML = ''; - fetch('/fetch-gallery', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({}) - }) + const container = document.getElementById(tabId).querySelector(".grid-container"); + container.innerHTML = ""; + fetch("/fetch-gallery", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({}) + }) .then(response => response.json()) .then(data => { - galleryWorkflows = data.json || []; // 存储获取到的工作流数据 - galleryWorkflows.forEach((workflow, index) => { - const meta = workflow.meta; - const title = meta.title; - const author = meta.author; - const time = meta.time; - const thumbnail = meta.thumbnail || generateThumbnailFromContent(meta); - createGridItem(title, container, thumbnail, author, time, false, index); // 将index传递给createGridItem - }); + galleryWorkflows = data.json || []; // 存储获取到的工作流数据 + galleryWorkflows.forEach((workflow, index) => { + const meta = workflow.meta; + const title = meta.title; + const author = meta.author; + const time = meta.time; + const thumbnail = meta.thumbnail || generateThumbnailFromContent(meta); + createGridItem(title, container, thumbnail, author, time, false, index); // 将index传递给createGridItem + }); }) .catch(error => { - console.error('Error fetching gallery workflows:', error); + console.error("Error fetching gallery workflows:", error); }); } -function createGridItem(workflowName, container, thumbnail, author = '', time = '', showDeleteButton = false, index) { - var gridItem = document.createElement('div'); - gridItem.className = 'grid-item'; - gridItem.style.borderRadius = '15px'; - var gridItem = document.createElement('div'); - gridItem.className = 'grid-item'; - gridItem.style.borderRadius = '15px'; - gridItem.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)'; - - var img = document.createElement('div'); - img.className = 'thumbnail'; - img.style.backgroundImage = `url('${thumbnail}')`; - img.style.backgroundSize = 'cover'; - img.style.backgroundPosition = 'center'; - gridItem.appendChild(img); - - var caption = document.createElement('div'); - caption.className = 'caption'; - caption.style.backgroundColor = 'white'; - - var h6 = document.createElement('h6'); - h6.textContent = workflowName; - h6.style.margin = '1px 0'; - - var pAuthor = document.createElement('p'); - pAuthor.textContent = `Author: ${author}`; - pAuthor.style.margin = '1px 0'; - pAuthor.style.fontSize = '10px'; - - var pTime = document.createElement('p'); - pTime.textContent = `Date: ${time}`; - pTime.style.margin = '1px 0'; - pTime.style.fontSize = '10px'; - - var button = document.createElement('button'); - button.textContent = ' Load '; - button.className = 'button'; - button.style.backgroundColor = '#007aff'; - button.style.color = 'white'; - button.style.padding = '2px 7px'; - button.style.border = 'none'; - button.style.borderRadius = '8px'; - button.style.fontSize = '12px'; - button.style.cursor = 'pointer'; - button.style.transition = 'background 0.3s'; - - button.addEventListener('mouseover', function () { - button.style.backgroundColor = '#005bb5'; +function createGridItem(workflowName, container, thumbnail, author = "", time = "", showDeleteButton = false, index) { + var gridItem = document.createElement("div"); + gridItem.className = "grid-item"; + gridItem.style.borderRadius = "15px"; + var gridItem = document.createElement("div"); + gridItem.className = "grid-item"; + gridItem.style.borderRadius = "15px"; + gridItem.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.2)"; + + const img = document.createElement("div"); + img.className = "thumbnail"; + img.style.backgroundImage = `url('${thumbnail}')`; + img.style.backgroundSize = "cover"; + img.style.backgroundPosition = "center"; + gridItem.appendChild(img); + + const caption = document.createElement("div"); + caption.className = "caption"; + caption.style.backgroundColor = "white"; + + const h6 = document.createElement("h6"); + h6.textContent = workflowName; + h6.style.margin = "1px 0"; + + const pAuthor = document.createElement("p"); + pAuthor.textContent = `Author: ${author}`; + pAuthor.style.margin = "1px 0"; + pAuthor.style.fontSize = "10px"; + + const pTime = document.createElement("p"); + pTime.textContent = `Date: ${time}`; + pTime.style.margin = "1px 0"; + pTime.style.fontSize = "10px"; + + const button = document.createElement("button"); + button.textContent = " Load "; + button.className = "button"; + button.style.backgroundColor = "#007aff"; + button.style.color = "white"; + button.style.padding = "2px 7px"; + button.style.border = "none"; + button.style.borderRadius = "8px"; + button.style.fontSize = "12px"; + button.style.cursor = "pointer"; + button.style.transition = "background 0.3s"; + + button.addEventListener("mouseover", function () { + button.style.backgroundColor = "#005bb5"; + }); + + button.addEventListener("mouseout", function () { + button.style.backgroundColor = "#007aff"; + }); + button.onclick = function (e) { + e.preventDefault(); + if (showDeleteButton) { + sendWorkflow(workflowName); + } else { + const workflowData = galleryWorkflows[index]; + importGalleryWorkflow(JSON.stringify(workflowData)); + } + }; + + caption.appendChild(h6); + if (author) { + caption.appendChild(pAuthor); + } + if (time) { + caption.appendChild(pTime); + } + caption.appendChild(button); + + if (showDeleteButton) { + const deleteButton = document.createElement("button"); + deleteButton.textContent = "Delete"; + deleteButton.className = "button"; + deleteButton.style.backgroundColor = "#007aff"; + deleteButton.style.color = "white"; + deleteButton.style.padding = "2px 3px"; + deleteButton.style.border = "none"; + deleteButton.style.borderRadius = "8px"; + deleteButton.style.fontSize = "12px"; + deleteButton.style.cursor = "pointer"; + deleteButton.style.transition = "background 0.3s"; + + deleteButton.addEventListener("mouseover", function () { + deleteButton.style.backgroundColor = "#005bb5"; }); - - button.addEventListener('mouseout', function () { - button.style.backgroundColor = '#007aff'; + deleteButton.addEventListener("mouseout", function () { + deleteButton.style.backgroundColor = "#007aff"; }); - button.onclick = function (e) { - e.preventDefault(); - if (showDeleteButton) { - sendWorkflow(workflowName); - } else { - const workflowData = galleryWorkflows[index]; - importGalleryWorkflow(JSON.stringify(workflowData)); - } - }; - - caption.appendChild(h6); - if (author) caption.appendChild(pAuthor); - if (time) caption.appendChild(pTime); - caption.appendChild(button); - if (showDeleteButton) { - var deleteButton = document.createElement('button'); - deleteButton.textContent = 'Delete'; - deleteButton.className = 'button'; - deleteButton.style.backgroundColor = '#007aff'; - deleteButton.style.color = 'white'; - deleteButton.style.padding = '2px 3px'; - deleteButton.style.border = 'none'; - deleteButton.style.borderRadius = '8px'; - deleteButton.style.fontSize = '12px'; - deleteButton.style.cursor = 'pointer'; - deleteButton.style.transition = 'background 0.3s'; - - deleteButton.addEventListener('mouseover', function () { - deleteButton.style.backgroundColor = '#005bb5'; - }); - deleteButton.addEventListener('mouseout', function () { - deleteButton.style.backgroundColor = '#007aff'; - }); - - deleteButton.onclick = function (e) { - e.preventDefault(); - deleteWorkflow(workflowName); - }; + deleteButton.onclick = function (e) { + e.preventDefault(); + deleteWorkflow(workflowName); + }; - caption.appendChild(deleteButton); - } + caption.appendChild(deleteButton); + } - gridItem.appendChild(caption); - container.appendChild(gridItem); - console.log('Grid item appended:', gridItem); + gridItem.appendChild(caption); + container.appendChild(gridItem); + console.log("Grid item appended:", gridItem); } function showLoadWorkflowList(tabId) { - fetch('/list-workflows', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({}) + fetch("/list-workflows", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({}) + }) + .then(response => response.json()) + .then(data => { + if (!Array.isArray(data.files)) { + throw new TypeError("The return data is not an array"); + } + + const container = document.getElementById(tabId).querySelector(".grid-container"); + container.innerHTML = ""; + + data.files.forEach(workflowName => { + const title = workflowName.replace(/\.json$/, ""); + const thumbnail = generateThumbnailFromContent({title}); + createGridItem(title, container, thumbnail, "", "", true); + }); }) - .then(response => response.json()) - .then(data => { - if (!Array.isArray(data.files)) { - throw new TypeError('The return data is not an array'); - } - - const container = document.getElementById(tabId).querySelector('.grid-container'); - container.innerHTML = ''; - - data.files.forEach(workflowName => { - const title = workflowName.replace(/\.json$/, ''); - const thumbnail = generateThumbnailFromContent({title}); - createGridItem(title, container, thumbnail, '', '', true); - }); - }) - .catch(error => { - console.error('Error fetching workflow list:', error); - alert('Fetch workflow list error.'); - }); + .catch(error => { + console.error("Error fetching workflow list:", error); + alert("Fetch workflow list error."); + }); } function generateThumbnailFromContent(content) { - const canvas = document.createElement('canvas'); - canvas.width = 150; - canvas.height = 150; - const ctx = canvas.getContext('2d'); + const canvas = document.createElement("canvas"); + canvas.width = 150; + canvas.height = 150; + const ctx = canvas.getContext("2d"); - ctx.fillStyle = '#f0f0f0'; - ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = "#f0f0f0"; + ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.font = 'italic bold 14px "Helvetica Neue", sans-serif'; - ctx.textAlign = 'center'; - ctx.fillStyle = '#333'; + ctx.font = "italic bold 14px \"Helvetica Neue\", sans-serif"; + ctx.textAlign = "center"; + ctx.fillStyle = "#333"; - ctx.fillText(content.title, canvas.width / 2, canvas.height / 2 + 20); + ctx.fillText(content.title, canvas.width / 2, canvas.height / 2 + 20); - return canvas.toDataURL(); + return canvas.toDataURL(); } diff --git a/src/agentscope/studio/static/js/workstation_iframe.js b/src/agentscope/studio/static/js/workstation_iframe.js index cc6d9209a..2aa23dc24 100644 --- a/src/agentscope/studio/static/js/workstation_iframe.js +++ b/src/agentscope/studio/static/js/workstation_iframe.js @@ -1,3 +1,3 @@ -var iframe = document.getElementById('workstation-iframe'); -var currentUrl = window.location.protocol + '//' + window.location.host + '/workstation'; +var iframe = document.getElementById("workstation-iframe"); +var currentUrl = window.location.protocol + "//" + window.location.host + "/workstation"; iframe.src = currentUrl; \ No newline at end of file