Skip to content

Conversation

@zzcr
Copy link
Member

@zzcr zzcr commented Jul 28, 2025

feat: 对接next-sdk和ai对话框,实现大模型动态切换路由功能

PR

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

  • New Features

    • Introduced an interactive AI chat panel with user-configurable LLM credentials and chat streaming capabilities.
    • Added new components for AI chat UI and reactive markdown rendering.
    • Integrated tools for page navigation and simulating long-running tasks.
  • Enhancements

    • Refactored main application structure to use Vue Composition API.
    • Improved localization by merging additional locale messages.
    • Registered global TinyVue MCP configuration for enhanced component support.
  • Configuration

    • Added environment variables for LLM API integration.
    • Updated package dependencies to include AI and robot-related packages.
  • Bug Fixes / Maintenance

    • Updated import paths and cleaned up style and formatting in several files.
    • Removed unused code and improved export styles for utility modules.
  • Style

    • Improved code formatting and consistency across multiple files.

@coderabbitai
Copy link

coderabbitai bot commented Jul 28, 2025

Walkthrough

This change introduces an AI chat panel to the official website example, migrating the main App.vue to the Composition API and adding new components and composables for AI chat functionality. It adds dependencies for AI and robot features, configures environment variables, and registers global tools for chat and navigation. Several files are refactored or updated for imports, configuration, and styling.

Changes

Cohort / File(s) Change Summary
AI Chat Panel Integration & Refactor
examples/sites/src/App.vue
Refactored from Options API to Composition API; added AI chat panel (tiny-robot-chat), dialog for LLM config, toggle button, server setup, and preview logic.
New AI Chat Components
examples/sites/src/components/ReactiveMarkdown.vue
examples/sites/src/components/tiny-robot-chat.vue
Added ReactiveMarkdown for markdown rendering and tiny-robot-chat for AI-powered chat UI, including prompt suggestions, chat bubbles, and input handling.
AI Chat Composables
examples/sites/src/composable/agentModelProvider.ts
examples/sites/src/composable/useTinyRobot.ts
Added composables for AI chat streaming, tool call handling, and chat UI state management.
AI Chat Utilities & State
examples/sites/src/composable/utils.ts
Updated exports; removed unused state, added showTinyRobot ref and LLM config checks.
Global MCP Tool Registration
examples/sites/src/tools/globalMcpTool.ts
New module to register global tools and resources (menus, router switching, long-task simulation) on the server.
Dependency and Config Updates
examples/sites/package.json
examples/sites/env/.env
Added dependencies for AI chat and robot features; added LLM API key and URL environment variables.
Main App Registration & Localization
examples/sites/src/main.js
examples/sites/src/i18n/index.js
Registered MCP config and tools globally; merged external locale messages with local ones.
Import Path Refactors
examples/sites/src/views/layout/layout.vue
examples/sites/src/tools/useTemplateMode.js
Changed imports from menus.jsx to menus for menu-related utilities.
Minor Config and Style Updates
examples/sites/.stylelintrc.js
examples/sites/tsconfig.node.json
Removed comments and reformatted configuration files.
Other Minor Cleanups
examples/sites/src/menus.js
examples/sites/src/router.js
examples/sites/src/tools/useBulletin.jsx
Removed trailing blank lines, unused flags, and improved JSX formatting.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AppVue
    participant TinyRobotChat
    participant AgentModelProvider
    participant Server
    participant LocalStorage

    User->>AppVue: Click AI icon
    AppVue->>LocalStorage: Check LLM config
    alt LLM config missing
        AppVue->>User: Show dialog for LLM URL/API key
        User->>AppVue: Submit LLM credentials
        AppVue->>LocalStorage: Save credentials
        AppVue->>AppVue: Reload page
    else LLM config present
        AppVue->>TinyRobotChat: Show AI chat panel
        User->>TinyRobotChat: Send message
        TinyRobotChat->>AgentModelProvider: chatStream(request)
        AgentModelProvider->>Server: Stream AI response
        Server-->>AgentModelProvider: Streamed data/events
        AgentModelProvider-->>TinyRobotChat: Update chat UI
        TinyRobotChat-->>User: Display AI response
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Poem

In the warren of code, a new chat appears,
With robots and markdown and helpful AI peers.
A bunny hops in, with a toggle to show,
The secrets of LLMs, in a dialog's glow.
Now the site can converse, with wisdom to share—
Hooray for the robots, and all who prepare!
🐰💬🤖

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch zzc/feat-add-ai-0725

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the enhancement New feature or request (功能增强) label Jul 28, 2025
@zzcr zzcr changed the title feat: connect next-sdk and ai dialog box to realize dynamic switching routing function of large models feat(site): connect next-sdk and ai dialog box to realize dynamic switching routing function of large models Jul 28, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 22

🔭 Outside diff range comments (1)
examples/sites/src/views/layout/layout.vue (1)

140-172: routerCbDestroy is never initialised – will throw on unmount

routerCbDestroy is declared as null and invoked unconditionally in onUnmounted, leading to a TypeError: routerCbDestroy is not a function the first time the component is destroyed.

-let routerCbDestroy = null
+let routerCbDestroy = () => {}
 ...
 onUnmounted(() => {
-  routerCbDestroy()
+  routerCbDestroy?.()
 })

or simply remove the variable if it is no longer needed.

🧹 Nitpick comments (4)
examples/sites/src/tools/useBulletin.jsx (1)

34-34: Pass width as a number, not a string (minor)

@opentiny/vue’s Modal.confirm expects width to be number | string. When it’s purely numeric, passing a number avoids an unnecessary type cast.

-        width: '760',
+        width: 760,
examples/sites/src/composable/utils.ts (1)

6-16: LGTM! Clean utility functions for AI chat state management.

The changes properly support the AI chat functionality:

  • showTinyRobot ref for controlling chat visibility
  • Boolean flags for checking LLM configuration availability
  • Clean export style for storage utilities

Consider adding JSDoc comments for better documentation:

+/** Controls the visibility of the AI chat robot */
export const showTinyRobot = ref(false)

+/** Checks if LLM configuration is defined in environment variables */
export const isEnvLLMDefined = Boolean(import.meta.env.VITE_LLM_API_KEY && import.meta.env.VITE_LLM_URL)
+/** Checks if LLM configuration is defined in local storage */
export const isLocalLLMDefined = Boolean($local.llmUrl && $local.llmApiKey)
examples/sites/src/tools/globalMcpTool.ts (1)

24-24: Remove or translate unrelated comment

The comment "帮我查看button组件的API" (help me check button component API) seems unrelated to the code below.

examples/sites/src/composable/agentModelProvider.ts (1)

76-77: Improve error message for unimplemented method

The error message should be more descriptive about why this method is not implemented.

-    throw new Error('Method not implemented.')
+    throw new Error('Synchronous chat is not supported. Please use chatStream() for streaming responses.')
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b27c30 and d45ad3d.

📒 Files selected for processing (18)
  • examples/sites/.stylelintrc.js (1 hunks)
  • examples/sites/env/.env (1 hunks)
  • examples/sites/package.json (2 hunks)
  • examples/sites/src/App.vue (2 hunks)
  • examples/sites/src/components/ReactiveMarkdown.vue (1 hunks)
  • examples/sites/src/components/tiny-robot-chat.vue (1 hunks)
  • examples/sites/src/composable/agentModelProvider.ts (1 hunks)
  • examples/sites/src/composable/useTinyRobot.ts (1 hunks)
  • examples/sites/src/composable/utils.ts (1 hunks)
  • examples/sites/src/i18n/index.js (1 hunks)
  • examples/sites/src/main.js (2 hunks)
  • examples/sites/src/menus.js (0 hunks)
  • examples/sites/src/router.js (0 hunks)
  • examples/sites/src/tools/globalMcpTool.ts (1 hunks)
  • examples/sites/src/tools/useBulletin.jsx (1 hunks)
  • examples/sites/src/tools/useTemplateMode.js (1 hunks)
  • examples/sites/src/views/layout/layout.vue (1 hunks)
  • examples/sites/tsconfig.node.json (1 hunks)
💤 Files with no reviewable changes (2)
  • examples/sites/src/menus.js
  • examples/sites/src/router.js
🧰 Additional context used
🧠 Learnings (5)
examples/sites/src/views/layout/layout.vue (2)

Learnt from: Davont
PR: #2513
File: packages/vue/src/huicharts/huicharts-histogram/src/chart-histogram.vue:33-36
Timestamp: 2024-11-25T03:43:05.285Z
Learning: 在 Tiny Vue 代码库中,使用 chart-core 中的 huiChartOption 的组件,不应在其 data 中定义 huiChartOptionoption,而是应该依赖 chart-core 提供的 huiChartOption

Learnt from: Davont
PR: #2513
File: packages/vue/src/huicharts/huicharts-sunburst/src/chart-sunburst.vue:30-32
Timestamp: 2024-11-25T03:24:05.740Z
Learning: 在位于packages/vue/src/huicharts/huicharts-sunburst/src/chart-sunburst.vue的组件中,当使用chart-core时,应删除错误的option定义,使用chart-core中的huiChartOption

examples/sites/src/main.js (1)

Learnt from: Davont
PR: #2513
File: packages/vue/src/huicharts/huicharts-histogram/src/chart-histogram.vue:33-36
Timestamp: 2024-11-25T03:43:05.285Z
Learning: 在 Tiny Vue 代码库中,使用 chart-core 中的 huiChartOption 的组件,不应在其 data 中定义 huiChartOptionoption,而是应该依赖 chart-core 提供的 huiChartOption

examples/sites/src/composable/useTinyRobot.ts (1)

Learnt from: Davont
PR: #2513
File: packages/vue/src/huicharts/huicharts-histogram/src/chart-histogram.vue:33-36
Timestamp: 2024-11-25T03:43:05.285Z
Learning: 在 Tiny Vue 代码库中,使用 chart-core 中的 huiChartOption 的组件,不应在其 data 中定义 huiChartOptionoption,而是应该依赖 chart-core 提供的 huiChartOption

examples/sites/src/composable/utils.ts (2)

Learnt from: Davont
PR: #2513
File: packages/vue/src/huicharts/huicharts-histogram/src/chart-histogram.vue:33-36
Timestamp: 2024-11-25T03:43:05.285Z
Learning: 在 Tiny Vue 代码库中,使用 chart-core 中的 huiChartOption 的组件,不应在其 data 中定义 huiChartOptionoption,而是应该依赖 chart-core 提供的 huiChartOption

Learnt from: Davont
PR: #2513
File: packages/vue/src/huicharts/huicharts-heatmap/src/chart-heatmap.vue:38-40
Timestamp: 2024-11-25T03:43:19.322Z
Learning: 在 Vue.js 组件(如 chart-heatmap.vue)中,使用来自 chart-corehuiChartOption 来管理图表选项,不要在 data() 中声明 option

examples/sites/src/App.vue (3)

Learnt from: Davont
PR: #2513
File: packages/vue/src/huicharts/huicharts-histogram/src/chart-histogram.vue:33-36
Timestamp: 2024-11-25T03:43:05.285Z
Learning: 在 Tiny Vue 代码库中,使用 chart-core 中的 huiChartOption 的组件,不应在其 data 中定义 huiChartOptionoption,而是应该依赖 chart-core 提供的 huiChartOption

Learnt from: Davont
PR: #2513
File: packages/vue/src/huicharts/huicharts-heatmap/src/chart-heatmap.vue:38-40
Timestamp: 2024-11-25T03:43:19.322Z
Learning: 在 Vue.js 组件(如 chart-heatmap.vue)中,使用来自 chart-corehuiChartOption 来管理图表选项,不要在 data() 中声明 option

Learnt from: Davont
PR: #2513
File: packages/vue/src/huicharts/huicharts-sunburst/src/chart-sunburst.vue:30-32
Timestamp: 2024-11-25T03:24:05.740Z
Learning: 在位于packages/vue/src/huicharts/huicharts-sunburst/src/chart-sunburst.vue的组件中,当使用chart-core时,应删除错误的option定义,使用chart-core中的huiChartOption

🧬 Code Graph Analysis (2)
examples/sites/src/main.js (1)
packages/vue-common/src/index.ts (1)
  • registerMcpConfig (194-197)
examples/sites/src/composable/agentModelProvider.ts (1)
examples/sites/src/composable/utils.ts (2)
  • isEnvLLMDefined (15-15)
  • $local (10-10)
🔇 Additional comments (9)
examples/sites/src/tools/useTemplateMode.js (1)

3-3: Check that the alias '@/menus' resolves consistently

The change drops the explicit .jsx extension. Vite/TS will resolve index.(js|ts|jsx|tsx) automatically, but only if such a file exists. Please verify that:

fd menus src | grep -E '/menus(\.|/index\.)'

returns a valid module; otherwise runtime import errors will occur.

examples/sites/src/views/layout/layout.vue (1)

60-64: Import path adjustment looks good

Switching to the barrel module @/menus keeps the codebase consistent with other files modified in this PR.

examples/sites/tsconfig.node.json (1)

9-10: No issues – formatting change only

Single-line "include" array and trailing newline are fine.

examples/sites/.stylelintrc.js (1)

2-10: Config cleanup accepted

Removing the stale comment keeps the linter config tidy; rule set unchanged.

examples/sites/package.json (1)

70-70: LGTM! Schema validation dependency added.

The addition of zod at version ^3.24.4 is appropriate for input validation in the AI chat functionality.

examples/sites/src/i18n/index.js (1)

8-10: LGTM! Proper locale integration with MCP package.

The localization integration correctly merges the MCP package's translations with existing local translations using the spread operator. This preserves existing translations while adding new ones for the AI chat functionality.

examples/sites/src/main.js (1)

36-41: LGTM! Proper MCP configuration registration.

The MCP (micro-component platform) integration is correctly implemented:

  • Appropriate imports for MCP tools and configuration
  • Style import for tiny-robot components
  • Global registration occurs at the right time in the app lifecycle
  • Localization function properly passed to the configuration

Also applies to: 99-100

examples/sites/src/components/ReactiveMarkdown.vue (1)

1-12: Ensure rendered markdown is sanitized to prevent XSS

Rendering untrusted markdown via v-html can open an XSS hole unless the output is properly sanitized. Please confirm whether BubbleMarkdownMessageRenderer already strips or escapes unsafe HTML. If it does not, wrap its output with your XSS filter:

• Import and use the built-in HTML sanitizer from @opentiny/utils
• Or disable raw HTML in your markdown-renderer config
• Only pass trusted content to this component

Suggested patch:

<script setup lang="ts">
-import { BubbleMarkdownMessageRenderer } from '@opentiny/tiny-robot'
+import { BubbleMarkdownMessageRenderer } from '@opentiny/tiny-robot'
+import { xss } from '@opentiny/utils'
 import { computed } from 'vue'

 const props = defineProps<{ content: string }>()

 const markdownRenderer = new BubbleMarkdownMessageRenderer()
-const markdown = computed(() => markdownRenderer.md.render(props.content))
+const markdown = computed(() => {
+  // Sanitize rendered HTML to prevent XSS
+  return xss.filterHtml(markdownRenderer.md.render(props.content))
+})
</script>
examples/sites/src/composable/agentModelProvider.ts (1)

63-63: Security: Review the use of dangerouslyAllowBrowser

The dangerouslyAllowBrowser: true flag bypasses security restrictions. Ensure this is intentional and document why it's necessary.

This flag typically allows API keys to be exposed in browser environments, which is a security risk. Consider implementing a backend proxy instead.

Comment on lines +9 to +11

VITE_LLM_API_KEY=
VITE_LLM_URL=https://api.deepseek.com/v1
Copy link

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_KEY values directly (or even an empty placeholder in a committed .env) makes it too easy for a future commit to leak credentials.
Recommend:

  1. Commit a .env.example containing only place-holders.
  2. Add .env to .gitignore so that real keys remain local.

This small discipline prevents credential exposure in OSS projects.

🤖 Prompt for AI Agents
In examples/sites/env/.env around lines 9 to 11, the real or placeholder API key
is committed directly, risking accidental credential leaks. To fix this, remove
the actual key from this file, commit a separate .env.example file with only
placeholder values, and add .env to .gitignore so that real secret keys are
never committed to the repository.

Comment on lines +30 to +33
"@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",
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify 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 -10

Length 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:

  • examples/sites/package.json (lines 30–33)
    • @opentiny/next-sdk remains at 0.0.1-alpha.5 (latest)
    • @opentiny/tiny-robot, @opentiny/tiny-robot-kit, and @opentiny/tiny-robot-svgs are pinned at 0.3.0-alpha.3, while the latest available is 0.3.0-alpha.14.

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

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"@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",
"@opentiny/next-sdk": "0.0.1-alpha.5",
"@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",
🤖 Prompt for AI Agents
In examples/sites/package.json around lines 30 to 33, the dependencies
@opentiny/tiny-robot, @opentiny/tiny-robot-kit, and @opentiny/tiny-robot-svgs
are pinned to older alpha versions 0.3.0-alpha.3, while newer alpha versions
0.3.0-alpha.14 are available. Update these dependencies to the latest alpha
versions by changing their version strings to "0.3.0-alpha.14" or use caret
ranges like "^0.3.0-alpha.14" to track future alpha updates automatically. Also
consider updating @opentiny/next-sdk if a newer alpha is available or confirm it
is at the latest. Ensure these changes align with your stability and security
requirements before deploying.

Comment on lines +69 to +70
$local.llmUrl = createData.llmUrl
$local.llmApiKey = createData.llmApiKey
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

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:

  1. Implementing a backend proxy that stores the API keys securely
  2. Using session storage with encryption
  3. Warning users about the security implications
🤖 Prompt for AI Agents
In examples/sites/src/App.vue around lines 69 to 70, the code stores the API key
in localStorage, which is insecure. To fix this, remove storing the API key in
localStorage and instead implement a backend proxy to handle API requests
securely, or use a more secure storage method such as encrypted session storage.
Additionally, update the code to fetch the API key from the secure backend or
encrypted storage rather than localStorage.

$local.llmUrl = createData.llmUrl
$local.llmApiKey = createData.llmApiKey
boxVisibility.value = false
window.location.reload()
Copy link

Choose a reason for hiding this comment

The 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

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In examples/sites/src/App.vue at line 72, replace the use of
window.location.reload() with Vue's reactive state management to update the
necessary components without a full page reload. Identify the specific data or
state changes needed and trigger those updates through Vue's reactive properties
or methods to maintain the single-page application experience.

Comment on lines +78 to +97
const server = createServer(
{
name: 'comprehensive-config',
version: '1.0.0'
},
{
capabilities: {
logging: {},
resources: { subscribe: true, listChanged: true }
}
}
)
server.use(createInMemoryTransport())
createGlobalMcpTool(server)
onMounted(() => {
server.connectTransport()
// 加载header
Copy link

Choose a reason for hiding this comment

The 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)
+}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In examples/sites/src/App.vue around lines 78 to 97, the server creation and
connection code lacks error handling. Wrap the server creation and the
server.connectTransport() call inside try-catch blocks to catch any exceptions.
In the catch block, log or handle the error gracefully to prevent the app from
crashing unexpectedly.

Comment on lines +5 to +6
export const createGlobalMcpTool = (server) => {
const router = useRouter()
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

useRouter() must be called within Vue's setup context

The useRouter() composable should be called within a Vue component's setup function or <script setup>. Calling it here will likely throw an error. Consider passing the router instance as a parameter instead.

-export const createGlobalMcpTool = (server) => {
-  const router = useRouter()
+export const createGlobalMcpTool = (server, router) => {
🤖 Prompt for AI Agents
In examples/sites/src/tools/globalMcpTool.ts around lines 5 to 6, the
useRouter() function is called outside of a Vue setup context, which is invalid
and causes errors. To fix this, remove the direct call to useRouter() here and
instead modify createGlobalMcpTool to accept the router instance as a parameter
passed from a valid Vue setup context where useRouter() can be safely called.

)
// 帮我查看button组件的API
server.registerTool(
'swtich-router',
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix typo in tool name

There's a typo in the tool name.

-    'swtich-router',
+    'switch-router',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'swtich-router',
'switch-router',
🤖 Prompt for AI Agents
In examples/sites/src/tools/globalMcpTool.ts at line 26, correct the typo in the
tool name from 'swtich-router' to 'switch-router' to fix the spelling error.

Comment on lines +36 to +42
async ({ key, type, isOpenApi }) => {
const { params, fullPath } = router.currentRoute.value
const { theme } = params
const themeIndex = fullPath.indexOf(theme)
const linkUrl =
fullPath.slice(0, themeIndex) + `${theme}/${type}/${key === 'overview' ? '' : key}${isOpenApi ? '#api' : ''}`
router.push(linkUrl)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential runtime error when router params are undefined

The code assumes params.theme exists but doesn't validate it. This could cause runtime errors if the theme parameter is missing.

     async ({ key, type, isOpenApi }) => {
       const { params, fullPath } = router.currentRoute.value
       const { theme } = params
+      if (!theme) {
+        return {
+          content: [{
+            type: 'text',
+            text: '当前路由缺少主题参数'
+          }]
+        }
+      }
       const themeIndex = fullPath.indexOf(theme)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async ({ key, type, isOpenApi }) => {
const { params, fullPath } = router.currentRoute.value
const { theme } = params
const themeIndex = fullPath.indexOf(theme)
const linkUrl =
fullPath.slice(0, themeIndex) + `${theme}/${type}/${key === 'overview' ? '' : key}${isOpenApi ? '#api' : ''}`
router.push(linkUrl)
async ({ key, type, isOpenApi }) => {
const { params, fullPath } = router.currentRoute.value
const { theme } = params
if (!theme) {
return {
content: [{
type: 'text',
text: '当前路由缺少主题参数'
}]
}
}
const themeIndex = fullPath.indexOf(theme)
const linkUrl =
fullPath.slice(0, themeIndex) + `${theme}/${type}/${key === 'overview' ? '' : key}${isOpenApi ? '#api' : ''}`
router.push(linkUrl)
🤖 Prompt for AI Agents
In examples/sites/src/tools/globalMcpTool.ts around lines 36 to 42, the code
assumes params.theme is always defined, which can cause runtime errors if it is
missing. Add a check to verify that params and params.theme exist before using
them. If theme is undefined, handle this case gracefully, such as by returning
early or providing a default value, to prevent errors when accessing theme or
using it in string operations.

Comment on lines +56 to +60
'long-task',
{
title: 'long-task',
description: '可以帮用户订机票'
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Tool description doesn't match implementation

The description says "可以帮用户订机票" (can help users book flights), but the implementation is just a 10-second timeout. Either update the description or implement the actual functionality.

-      description: '可以帮用户订机票'
+      description: '模拟长时间运行的任务示例'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'long-task',
{
title: 'long-task',
description: '可以帮用户订机票'
},
'long-task',
{
title: 'long-task',
description: '模拟长时间运行的任务示例'
},
🤖 Prompt for AI Agents
In examples/sites/src/tools/globalMcpTool.ts around lines 56 to 60, the tool
description states it can help users book flights, but the implementation only
performs a 10-second timeout. To fix this, either update the description to
accurately reflect the current timeout behavior or implement the actual flight
booking functionality as described.

Comment on lines +26 to +31
<div style="font-size:16px;line-height:1.5;">
<div>尊敬的 TinyVue 用户:</div>
<p style="text-indent: 2em;" v-html={lastBulletin.content}></p>
<div style="text-align:right;margin-top:20px">TinyVue 团队</div>
<div style="text-align:right;">{lastBulletin.time}</div>
</div>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Sanitize lastBulletin.content before injecting with v-html

v-html will render raw HTML and is therefore vulnerable to XSS if the source string is not 100 % trusted. Although the current bulletin text is hard-coded, future items might come from external sources or be edited in a CMS. Mitigate the risk by sanitising the HTML first.

-            <p style="text-indent: 2em;" v-html={lastBulletin.content}></p>
+            <!-- sanitize before injecting to avoid XSS -->
+            <p
+              style="text-indent: 2em;"
+              v-html={DOMPurify.sanitize(lastBulletin.content)}
+            ></p>

Remember to add an explicit import once in this file (or a shared util) and list dompurify in package.json:

+import DOMPurify from 'dompurify'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div style="font-size:16px;line-height:1.5;">
<div>尊敬的 TinyVue 用户:</div>
<p style="text-indent: 2em;" v-html={lastBulletin.content}></p>
<div style="text-align:right;margin-top:20px">TinyVue 团队</div>
<div style="text-align:right;">{lastBulletin.time}</div>
</div>
<div style="font-size:16px;line-height:1.5;">
<div>尊敬的 TinyVue 用户:</div>
<!-- sanitize before injecting to avoid XSS -->
<p
style="text-indent: 2em;"
v-html={DOMPurify.sanitize(lastBulletin.content)}
></p>
<div style="text-align:right;margin-top:20px">TinyVue 团队</div>
<div style="text-align:right;">{lastBulletin.time}</div>
</div>
🤖 Prompt for AI Agents
In examples/sites/src/tools/useBulletin.jsx around lines 26 to 31, the use of
v-html to inject lastBulletin.content directly poses an XSS risk if the content
is not fully trusted. To fix this, import the dompurify library at the top of
the file, sanitize lastBulletin.content using dompurify's sanitize method before
passing it to v-html, and ensure dompurify is added as a dependency in
package.json. This will clean the HTML content and prevent potential XSS
vulnerabilities.

@kagol kagol merged commit 12d2364 into dev Jul 28, 2025
16 checks passed
@kagol kagol deleted the zzc/feat-add-ai-0725 branch July 28, 2025 03:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request (功能增强)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants