-
Notifications
You must be signed in to change notification settings - Fork 330
feat(site): connect next-sdk and ai dialog box to realize dynamic switching routing function of large models #3619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,11 @@ | ||
| module.exports = { | ||
| extends: 'stylelint-config-standard', //stylelint-config-airbnb | ||
| extends: 'stylelint-config-standard', | ||
| rules: { | ||
| 'string-quotes': 'single', | ||
| 'property-no-unknown': true, | ||
| 'selector-pseudo-class-no-unknown': true, | ||
| 'at-rule-empty-line-before': 'always', | ||
| 'block-no-empty': true, | ||
| 'indentation': 4 // http://cui.ulanqab.huawei.com/#/articalDetail?id=b76da810d8ed8 | ||
| 'indentation': 4 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -27,6 +27,10 @@ | |||||||||||||||||
| "@docsearch/css": "^3.8.0", | ||||||||||||||||||
| "@docsearch/js": "^3.8.0", | ||||||||||||||||||
| "@docsearch/react": "npm:@docsearch/css", | ||||||||||||||||||
| "@opentiny/next-sdk": "0.0.1-alpha.5", | ||||||||||||||||||
| "@opentiny/tiny-robot": "0.3.0-alpha.3", | ||||||||||||||||||
| "@opentiny/tiny-robot-kit": "0.3.0-alpha.3", | ||||||||||||||||||
| "@opentiny/tiny-robot-svgs": "0.3.0-alpha.3", | ||||||||||||||||||
|
Comment on lines
+30
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify alpha version stability and security for production use. These alpha versions (@opentiny/next-sdk at 0.0.1-alpha.5 and @opentiny/tiny-robot packages at 0.3.0-alpha.3) may introduce instability in production environments. Alpha releases typically have incomplete features and potential breaking changes. 🏁 Script executed: #!/bin/bash
# Check for security advisories and release stability of the new packages
echo "Checking security advisories for new packages..."
for package in "@opentiny/next-sdk" "@opentiny/tiny-robot" "@opentiny/tiny-robot-kit" "@opentiny/tiny-robot-svgs"; do
echo "Checking $package..."
npm audit --package-lock-only --audit-level moderate 2>/dev/null | grep -i "$package" || echo "No advisories found for $package"
done
# Check npm registry for latest versions
echo -e "\nChecking latest versions..."
npm view @opentiny/next-sdk versions --json | tail -10
npm view @opentiny/tiny-robot versions --json | tail -10Length of output: 3009 Upgrade alpha dependencies for stability and production readiness No security advisories were found for these packages, but you’re locked to very early alpha versions:
Please update these entries to receive the latest fixes or consider waiting for a stable release: - "@opentiny/tiny-robot": "0.3.0-alpha.3",
- "@opentiny/tiny-robot-kit": "0.3.0-alpha.3",
- "@opentiny/tiny-robot-svgs": "0.3.0-alpha.3",
+ "@opentiny/tiny-robot": "0.3.0-alpha.14",
+ "@opentiny/tiny-robot-kit": "0.3.0-alpha.14",
+ "@opentiny/tiny-robot-svgs": "0.3.0-alpha.14",Optionally use caret ranges (e.g. "^0.3.0-alpha.14") if you want to track future alpha updates automatically. Confirm that alpha-level dependencies align with your stability and security requirements before deploying to production. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| "@opentiny/tiny-vue-mcp": "^0.0.2", | ||||||||||||||||||
| "@opentiny/utils": "workspace:~", | ||||||||||||||||||
| "@opentiny/vue": "workspace:~", | ||||||||||||||||||
|
|
@@ -62,7 +66,8 @@ | |||||||||||||||||
| "tailwindcss": "^3.2.4", | ||||||||||||||||||
| "vue": "^3.4.31", | ||||||||||||||||||
| "vue-i18n": "~9.14.3", | ||||||||||||||||||
| "vue-router": "4.1.5" | ||||||||||||||||||
| "vue-router": "4.1.5", | ||||||||||||||||||
| "zod": "^3.24.4" | ||||||||||||||||||
| }, | ||||||||||||||||||
| "devDependencies": { | ||||||||||||||||||
| "@opentiny-internal/unplugin-virtual-template": "workspace:~", | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,57 +7,120 @@ | |||||||||||||
| <iframe v-if="modalSHow" width="100%" height="100%" :src="previewUrl" frameborder="0"></iframe> | ||||||||||||||
| </tiny-modal> | ||||||||||||||
| </tiny-config-provider> | ||||||||||||||
| <div class="right-panel" :class="{ collapsed: !showTinyRobot }"> | ||||||||||||||
| <tiny-robot-chat /> | ||||||||||||||
| </div> | ||||||||||||||
| <IconAi @click="handleShowTinyRobot" class="style-settings-icon"></IconAi> | ||||||||||||||
| <tiny-dialog-box | ||||||||||||||
| v-model:visible="boxVisibility" | ||||||||||||||
| :close-on-click-modal="false" | ||||||||||||||
| title="请填写您的LLM信息, 否则无法体验智能化能力" | ||||||||||||||
| width="30%" | ||||||||||||||
| > | ||||||||||||||
| <div> | ||||||||||||||
| <tiny-form ref="formRef" :model="createData" label-width="120px"> | ||||||||||||||
| <tiny-form-item label="LLM URL" prop="llmUrl" :rules="{ required: true, messages: '必填', trigger: 'blur' }"> | ||||||||||||||
| <tiny-input v-model="createData.llmUrl"></tiny-input> | ||||||||||||||
| </tiny-form-item> | ||||||||||||||
| <tiny-form-item | ||||||||||||||
| label="API Key" | ||||||||||||||
| prop="llmApiKey" | ||||||||||||||
| :rules="{ required: true, messages: '必填', trigger: 'blur' }" | ||||||||||||||
| > | ||||||||||||||
| <tiny-input v-model="createData.llmApiKey"></tiny-input> | ||||||||||||||
| </tiny-form-item> | ||||||||||||||
| <tiny-form-item> | ||||||||||||||
| <tiny-button @click="submit" type="primary">保存</tiny-button> | ||||||||||||||
| </tiny-form-item> | ||||||||||||||
| </tiny-form> | ||||||||||||||
| </div> | ||||||||||||||
| </tiny-dialog-box> | ||||||||||||||
| </div> | ||||||||||||||
| </template> | ||||||||||||||
|
|
||||||||||||||
| <script> | ||||||||||||||
| import { defineComponent, onMounted, provide, ref } from 'vue' | ||||||||||||||
| import { ConfigProvider, Modal } from '@opentiny/vue' | ||||||||||||||
| import { iconClose } from '@opentiny/vue-icon' | ||||||||||||||
| import { appData } from './tools' | ||||||||||||||
| <script setup lang="ts"> | ||||||||||||||
| import { onMounted, provide, ref, reactive } from 'vue' | ||||||||||||||
| import { | ||||||||||||||
| TinyConfigProvider, | ||||||||||||||
| TinyModal, | ||||||||||||||
| TinyDialogBox, | ||||||||||||||
| TinyForm, | ||||||||||||||
| TinyFormItem, | ||||||||||||||
| TinyInput, | ||||||||||||||
| TinyButton | ||||||||||||||
| } from '@opentiny/vue' | ||||||||||||||
| import useTheme from './tools/useTheme' | ||||||||||||||
| import TinyRobotChat from './components/tiny-robot-chat.vue' | ||||||||||||||
| import { IconAi } from '@opentiny/tiny-robot-svgs' | ||||||||||||||
| import { showTinyRobot } from './composable/utils' | ||||||||||||||
| import { createServer, createInMemoryTransport } from '@opentiny/next-sdk' | ||||||||||||||
| import { createGlobalMcpTool } from './tools/globalMcpTool' | ||||||||||||||
| import { $local, isEnvLLMDefined, isLocalLLMDefined } from './composable/utils' | ||||||||||||||
|
|
||||||||||||||
| export default defineComponent({ | ||||||||||||||
| name: 'AppVue', | ||||||||||||||
| props: [], | ||||||||||||||
| components: { | ||||||||||||||
| TinyConfigProvider: ConfigProvider, | ||||||||||||||
| TinyModal: Modal, | ||||||||||||||
| TinyIconClose: iconClose() | ||||||||||||||
| }, | ||||||||||||||
| setup() { | ||||||||||||||
| const previewUrl = ref(import.meta.env.VITE_PLAYGROUND_URL) | ||||||||||||||
| const modalSHow = ref(false) | ||||||||||||||
| const boxVisibility = ref(false) | ||||||||||||||
| const formRef = ref() | ||||||||||||||
| const createData = reactive({ | ||||||||||||||
| llmUrl: $local.llmUrl || import.meta.env.VITE_LLM_URL, | ||||||||||||||
| llmApiKey: $local.llmApiKey || import.meta.env.VITE_LLM_API_KEY | ||||||||||||||
| }) | ||||||||||||||
|
|
||||||||||||||
| onMounted(() => { | ||||||||||||||
| // 加载header | ||||||||||||||
| const common = new window.TDCommon(['#header'], { | ||||||||||||||
| allowDarkTheme: true, | ||||||||||||||
| searchConfig: { | ||||||||||||||
| show: true | ||||||||||||||
| }, | ||||||||||||||
| menuCollapse: { | ||||||||||||||
| useCollapse: true, // 启用1024以下隐藏菜单 | ||||||||||||||
| menuId: '#layoutSider' | ||||||||||||||
| } | ||||||||||||||
| }) | ||||||||||||||
| common.renderHeader() | ||||||||||||||
| }) | ||||||||||||||
| const { designConfig, currentThemeKey } = useTheme() | ||||||||||||||
| const submit = () => { | ||||||||||||||
| formRef.value.validate().then(() => { | ||||||||||||||
| $local.llmUrl = createData.llmUrl | ||||||||||||||
| $local.llmApiKey = createData.llmApiKey | ||||||||||||||
|
Comment on lines
+69
to
+70
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security: Avoid storing API keys in localStorage Storing API keys in localStorage is insecure as they can be accessed by any script. Consider using a more secure storage method or implementing a backend proxy. For production use, API keys should be handled server-side. Consider:
🤖 Prompt for AI Agents |
||||||||||||||
| boxVisibility.value = false | ||||||||||||||
| window.location.reload() | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid using window.location.reload() Full page reload disrupts the single-page application experience. Consider using Vue's reactivity to update the necessary components. - window.location.reload()
+ // Emit an event or use a reactive store to notify components about the configuration change
+ showTinyRobot.value = true
+ // Re-initialize the AI client with new credentials
🤖 Prompt for AI Agents |
||||||||||||||
| }) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| provide('showPreview', (url) => { | ||||||||||||||
| previewUrl.value = url | ||||||||||||||
| modalSHow.value = true | ||||||||||||||
| }) | ||||||||||||||
| return { | ||||||||||||||
| appData, | ||||||||||||||
| designConfig, | ||||||||||||||
| currentThemeKey, | ||||||||||||||
| previewUrl, | ||||||||||||||
| modalSHow | ||||||||||||||
| const previewUrl = ref(import.meta.env.VITE_PLAYGROUND_URL) | ||||||||||||||
| const modalSHow = ref(false) | ||||||||||||||
| const server = createServer( | ||||||||||||||
| { | ||||||||||||||
| name: 'comprehensive-config', | ||||||||||||||
| version: '1.0.0' | ||||||||||||||
| }, | ||||||||||||||
| { | ||||||||||||||
| capabilities: { | ||||||||||||||
| logging: {}, | ||||||||||||||
| resources: { subscribe: true, listChanged: true } | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| server.use(createInMemoryTransport()) | ||||||||||||||
|
|
||||||||||||||
| createGlobalMcpTool(server) | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pass router instance to createGlobalMcpTool Based on the earlier review of +import { useRouter } from 'vue-router'
+
+const router = useRouter()
-createGlobalMcpTool(server)
+createGlobalMcpTool(server, router)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| onMounted(() => { | ||||||||||||||
| server.connectTransport() | ||||||||||||||
| // 加载header | ||||||||||||||
|
Comment on lines
+78
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling for server initialization Server creation and connection could fail. Add try-catch blocks to handle potential errors gracefully. +try {
const server = createServer(
// ... server config ...
)
server.use(createInMemoryTransport())
createGlobalMcpTool(server, router)
onMounted(() => {
- server.connectTransport()
+ try {
+ server.connectTransport()
+ } catch (error) {
+ console.error('Failed to connect server transport:', error)
+ }
// ... rest of onMounted code ...
})
+} catch (error) {
+ console.error('Failed to initialize server:', error)
+}
🤖 Prompt for AI Agents |
||||||||||||||
| const common = new window.TDCommon(['#header'], { | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add type checking for window.TDCommon Using - const common = new window.TDCommon(['#header'], {
+ if (typeof window.TDCommon === 'undefined') {
+ console.error('TDCommon is not loaded')
+ return
+ }
+ const common = new window.TDCommon(['#header'], {📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| allowDarkTheme: true, | ||||||||||||||
| searchConfig: { | ||||||||||||||
| show: true | ||||||||||||||
| }, | ||||||||||||||
| menuCollapse: { | ||||||||||||||
| useCollapse: true, // 启用1024以下隐藏菜单 | ||||||||||||||
| menuId: '#layoutSider' | ||||||||||||||
| } | ||||||||||||||
| }) | ||||||||||||||
| common.renderHeader() | ||||||||||||||
| }) | ||||||||||||||
| const { designConfig, currentThemeKey } = useTheme() | ||||||||||||||
|
|
||||||||||||||
| provide('showPreview', (url) => { | ||||||||||||||
| previewUrl.value = url | ||||||||||||||
| modalSHow.value = true | ||||||||||||||
| }) | ||||||||||||||
|
|
||||||||||||||
| const handleShowTinyRobot = () => { | ||||||||||||||
| if (!isEnvLLMDefined && !isLocalLLMDefined) { | ||||||||||||||
| boxVisibility.value = true | ||||||||||||||
| } else { | ||||||||||||||
| showTinyRobot.value = !showTinyRobot.value | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| </script> | ||||||||||||||
|
|
||||||||||||||
| <style scoped lang="less"> | ||||||||||||||
|
|
@@ -73,4 +136,18 @@ export default defineComponent({ | |||||||||||||
| padding: 34px 0 0; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| .right-panel { | ||||||||||||||
| :deep(.tr-container) { | ||||||||||||||
| z-index: 9999; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| .style-settings-icon { | ||||||||||||||
| position: fixed; | ||||||||||||||
| bottom: 100px; | ||||||||||||||
| right: 100px; | ||||||||||||||
| font-size: 24px; | ||||||||||||||
| z-index: 19999; | ||||||||||||||
| cursor: pointer; | ||||||||||||||
| } | ||||||||||||||
| </style> | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <template> | ||
| <div v-html="markdown"></div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| import { BubbleMarkdownMessageRenderer } from '@opentiny/tiny-robot' | ||
| import { computed } from 'vue' | ||
|
|
||
| const props = defineProps<{ content: string }>() | ||
| const markdownRenderer = new BubbleMarkdownMessageRenderer() | ||
| const markdown = computed(() => markdownRenderer.md.render(props.content)) | ||
| </script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Externalise secrets to avoid accidental leakage
Committing real
VITE_LLM_API_KEYvalues directly (or even an empty placeholder in a committed.env) makes it too easy for a future commit to leak credentials.Recommend:
.env.examplecontaining only place-holders..envto.gitignoreso that real keys remain local.This small discipline prevents credential exposure in OSS projects.
🤖 Prompt for AI Agents