Skip to content

chore: sync release-3.24.0 to dev #3507

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

Merged
merged 6 commits into from
Jun 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/sites/demos/pc/menus.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ const docMenusChildren = [
'titleEn': 'theme-dark',
'key': 'theme-dark'
},
{
'title': '智能化',
'titleEn': 'mcp',
'key': 'mcp'
},
Comment on lines +45 to +49
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 the existence of a matching “mcp” route before merging

A new menu entry is wired to key: 'mcp', but no corresponding route is added in router.js.
If the route/page is missing the click will 404. Please double-check that either:

  1. router.js defines a docs route like /mcp (or it is resolved via another dynamic rule), or
  2. this menu item should point at an existing key.

Run:


🏁 Script executed:

#!/bin/bash
# Search router for an explicit mcp route
rg -n $'/mcp'

Length of output: 119


🏁 Script executed:

#!/bin/bash
# Locate router file(s)
ROUTER_FILES=$(fd router.js -t f)
echo "Found router files:"
echo "$ROUTER_FILES"

# Search for 'mcp' in each router file
for file in $ROUTER_FILES; do
  echo "Searching in $file"
  rg -n "mcp" "$file" || echo "No matches in $file"
done

Length of output: 435


Add the missing mcp route in router.js or point the menu to an existing key

examples/sites/src/router.js currently has no entry for /mcp, so the new menu item in examples/sites/demos/pc/menus.js will 404 when clicked. Please choose one of the following fixes:

  • Add a route in examples/sites/src/router.js for mcp, e.g.:

     // at top of file
    + import McpDocs from '@/views/components-doc/common.vue'
     
     export const routes = [
       // … existing routes
    +  {
    +    path: '/mcp',
    +    name: 'mcp',
    +    component: McpDocs
    +  },
     ]
  • Or update the menu entry at examples/sites/demos/pc/menus.js to use an existing route key.

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

🤖 Prompt for AI Agents
In examples/sites/demos/pc/menus.js around lines 45 to 49, the menu item with
key 'mcp' does not have a corresponding route defined in
examples/sites/src/router.js, which will cause a 404 error on click. To fix
this, either add a new route entry for 'mcp' in examples/sites/src/router.js
that points to the appropriate component or page, or update the menu item's key
in menus.js to match an existing route key already defined in router.js.

{ 'title': '表单校验配置', 'titleEn': 'formValid', 'key': 'form-valid' },
{ 'title': '常见问题', 'titleEn': 'faq', 'key': 'faq' },
{
Expand Down
171 changes: 52 additions & 119 deletions examples/sites/demos/pc/webdoc/changelog.md

Large diffs are not rendered by default.

101 changes: 101 additions & 0 deletions examples/sites/demos/pc/webdoc/mcp-en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# TinyVue Intelligent Component Access Guide

TinyVue's intelligent components provide a complete intelligent solution, allowing your application to have AI conversation, voice interaction, and other capabilities. This guide will walk you through how to integrate TinyVue's intelligent components into your project.

## Install dependencies

First, you need to install the following core dependency packages:

```bash
npm install @opentiny/tiny-vue-mcp @opentiny/next-vue @opentiny/vue-common @opentiny/vue
```

## Access steps

### 1. Initialize MCP Configuration

Initialize MCP configuration in the application entry file (e.g., `main.js`):

```js
import { registerMcpConfig } from '@opentiny/vue-common'
import { createMcpTools, getTinyVueMcpConfig } from '@opentiny/tiny-vue-mcp'

// Register TinyVue component MCP configuration
registerMcpConfig(getTinyVueMcpConfig(), createMcpTools)
```

### 2. Create NextClient Proxy Client

Create a NextClient proxy client in `App.vue` to establish real-time communication:

```html
<script setup lang="ts">
import { useNextClient } from '@opentiny/next-vue'

const { sessionId } = useNextClient({
clientInfo: {
name: 'your-app-name', // Application name
version: '1.0.0', // Application version
sessionId: 'your-session-id' // Optional, will be passed in by the backend if not provided; for debugging, you can use crypto.randomUUID() to generate a fixed one
},
proxyOptions: {
url: 'your-sse-url', // SSE service address
token: 'your-token' // Authentication token
}
})
</script>

<template>
<div>
<h1>NextClient Proxy Client</h1>
<p>Session ID: {{ sessionId }}</p>
</div>
</template>
```

### 3. MCP Component Configuration

When using

```html
<script setup lang="ts">
import { useNextServer } from '@opentiny/next-vue'

const { server } = useNextServer({
serverInfo: { name: 'your-server-name', version: '1.0.0' }
})
</script>

<template>
<tiny-grid
:tiny_mcp_config="{
server,
business: {
id: 'your-business-id',
description: 'Business description'
}
}"
>
<!-- Table content -->
</tiny-grid>
</template>
```

## Notes

1. Ensure that the server supports SSE (Server-Sent Events) connections
2. It is recommended to use HTTPS in production environments
3. CORS needs to be correctly configured to support cross-origin requests

## Common issues

1. Session connection failed

- Check if the SSE service address is correct
- Confirm that the network connection is normal
- Verify that the authentication information is valid

2. AI conversation response is not available
- Check if the session is established normally
- Confirm that the prompt item configuration is correct
- Check if there are errors in the network request
101 changes: 101 additions & 0 deletions examples/sites/demos/pc/webdoc/mcp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# TinyVue 智能化组件接入指南

TinyVue 的智能化组件提供了一套完整的智能化解决方案,让您的应用具备 AI 对话、语音交互等能力。本文将指导您如何在项目中接入 TinyVue 的智能化组件。

## 安装依赖

首先需要安装以下核心依赖包:

```bash
npm install @opentiny/tiny-vue-mcp @opentiny/next-vue @opentiny/vue-common @opentiny/vue
```

## 接入步骤

### 1. 初始化 MCP 配置

在应用入口文件(如 `main.js`)中初始化 MCP 配置:

```js
import { registerMcpConfig } from '@opentiny/vue-common'
import { createMcpTools, getTinyVueMcpConfig } from '@opentiny/tiny-vue-mcp'

// 注册 TinyVue 组件 MCP 配置
registerMcpConfig(getTinyVueMcpConfig(), createMcpTools)
```

### 2. 创建 NextClient 代理客户端

在 `App.vue` 中创建 NextClient 代理客户端,用于建立实时通信:

```html
<script setup lang="ts">
import { useNextClient } from '@opentiny/next-vue'

const { sessionId } = useNextClient({
clientInfo: {
name: 'your-app-name', // 应用名称
version: '1.0.0', // 应用版本
sessionId: 'your-session-id' // 可选,不传由后台自动生成。调试时可使用 crypto.randomUUID() 生成固定值
},
proxyOptions: {
url: 'your-sse-url', // SSE 服务地址,目前agent代理服务器代码未开源,如想进一步了解可以在github中提issue单
token: 'your-token' // 认证 token
}
})
</script>

<template>
<div>
<h1>NextClient 代理客户端</h1>
<p>会话 ID: {{ sessionId }}</p>
</div>
</template>
```

### 3. MCP 组件配置

在子页面中使用 Grid 等支持 MCP 的组件时,添加 MCP 配置:

```html
<script setup lang="ts">
import { useNextServer } from '@opentiny/next-vue'

const { server } = useNextServer({
serverInfo: { name: 'your-server-name', version: '1.0.0' }
})
</script>

<template>
<tiny-grid
:tiny_mcp_config="{
server,
business: {
id: 'your-business-id',
description: '业务描述'
}
}"
>
<!-- 表格内容 -->
</tiny-grid>
</template>
```

## 注意事项

1. 确保服务端支持 SSE(Server-Sent Events)连接
2. 建议在生产环境使用 HTTPS 协议
3. 需要正确配置 CORS 以支持跨域请求

## 常见问题

1. 会话连接失败

- 检查 SSE 服务地址是否正确
- 确认网络连接是否正常
- 验证认证信息是否有效

2. AI 对话无响应
- 检查会话是否正常建立
- 确认提示项配置是否正确
- 查看网络请求是否有错误
8 changes: 4 additions & 4 deletions examples/sites/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@opentiny/vue-docs",
"type": "module",
"version": "3.24.0",
"version": "3.24.4",
"license": "MIT",
"scripts": {
"start": "vite",
Expand All @@ -27,12 +27,11 @@
"@docsearch/css": "^3.8.0",
"@docsearch/js": "^3.8.0",
"@docsearch/react": "npm:@docsearch/css",
"@opentiny/next": "0.1.2",
"@opentiny/next-vue": "0.0.1-alpha.1",
"@opentiny/next-vue": "^0.0.1",
"@opentiny/tiny-robot": "0.2.1",
"@opentiny/tiny-robot-kit": "0.2.1",
"@opentiny/tiny-robot-svgs": "0.2.1",
"@opentiny/tiny-vue-mcp": "0.0.1-alpha.3",
"@opentiny/tiny-vue-mcp": "^0.0.1",
"@opentiny/utils": "workspace:~",
"@opentiny/vue": "workspace:~",
"@opentiny/vue-common": "workspace:~",
Expand All @@ -58,6 +57,7 @@
"@vue/shared": "^3.4.31",
"@vueuse/core": "^12.7.0",
"@vueuse/head": "0.7.13",
"crypto-js": "^4.2.0",
"github-markdown-css": "~5.1.0",
"highlight.js": "^11.5.1",
"marked": "^4.3.0",
Expand Down
5 changes: 3 additions & 2 deletions examples/sites/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { iconClose } from '@opentiny/vue-icon'
import { appData } from './tools'
import useTheme from './tools/useTheme'
import { useNextClient } from '@opentiny/next-vue'
import { globalConversation } from './views/components-doc/composition/utils'
import { globalConversation, $session } from './composable/utils'

export default defineComponent({
name: 'AppVue',
Expand All @@ -33,13 +33,14 @@ export default defineComponent({

const { sessionId } = useNextClient({
clientInfo: { name: 'tiny-vue-website', version: '1.0.0' },
proxyOptions: { url: 'https://39.108.160.245/sse', token: '' }
proxyOptions: { url: 'https://agent.icjs.ink/sse', token: '', sessionId: $session.sessionId }
})
Comment on lines +36 to 37
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Hard-coded SSE URL prevents staging / on-prem deployment

proxyOptions.url is fixed to https://agent.icjs.ink/sse. Externalising into an env var keeps dev/stage/prod flexible:

-      proxyOptions: { url: 'https://agent.icjs.ink/sse', token: '', sessionId: $session.sessionId }
+      proxyOptions: { url: import.meta.env.VITE_SSE_URL, token: '', sessionId: $session.sessionId }

Add VITE_SSE_URL to .env.*.

📝 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
proxyOptions: { url: 'https://agent.icjs.ink/sse', token: '', sessionId: $session.sessionId }
})
proxyOptions: { url: import.meta.env.VITE_SSE_URL, token: '', sessionId: $session.sessionId }
})
🤖 Prompt for AI Agents
In examples/sites/src/App.vue around lines 36 to 37, the SSE URL is hard-coded
as 'https://agent.icjs.ink/sse', which limits flexibility for different
environments. Replace this hard-coded URL with a reference to an environment
variable, such as import.meta.env.VITE_SSE_URL, and add VITE_SSE_URL to the
appropriate .env files for dev, staging, and production to allow configuration
per environment.


watch(
() => sessionId.value,
(newVal) => {
if (newVal) {
$session.sessionId = newVal
globalConversation.sessionId = newVal
}
}
Expand Down
117 changes: 117 additions & 0 deletions examples/sites/src/components/MessageCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<template>
<div class="message-card" :class="role">
<div class="avatar">
<component :is="avatarIcon" class="avatar-icon" />
</div>
<div class="content">
<div class="role-name">{{ roleName }}</div>
<div class="message">{{ message }}</div>
<div class="time">{{ formatTime }}</div>
</div>
</div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { IconAi, IconUser } from '@opentiny/tiny-robot-svgs'

interface Props {
role: 'user' | 'assistant'
message: string
timestamp: number
}

const props = defineProps<Props>()

const roleName = computed(() => (props.role === 'assistant' ? '智能助手' : '我'))

const avatarIcon = computed(() => (props.role === 'assistant' ? IconAi : IconUser))

const formatTime = computed(() => {
const date = new Date(props.timestamp)
return date.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit',
hour12: false
})
})
</script>

<style scoped lang="less">
.message-card {
display: flex;
margin: 16px;
gap: 12px;
max-width: 80%;

&.assistant {
margin-right: auto;

.content {
background-color: #f0f2f5;
}

.avatar-icon {
color: #2080f0;
}
}

&.user {
margin-left: auto;
flex-direction: row-reverse;

.content {
background-color: #e8f5e9;
}

.avatar-icon {
color: #18a058;
}
}

.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: #f5f7fa;

.avatar-icon {
width: 24px;
height: 24px;
}
}

.content {
padding: 12px;
border-radius: 12px;
position: relative;
min-width: 120px;
max-width: calc(100% - 60px);

.role-name {
font-size: 14px;
color: #666;
margin-bottom: 4px;
}

.message {
font-size: 16px;
line-height: 1.5;
word-break: break-word;
white-space: pre-wrap;
}

.time {
font-size: 12px;
color: #999;
margin-top: 4px;
text-align: right;
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ import { i18nByKey, getWord } from '@/i18n'
import { $split, fetchDemosFile } from '@/tools'
import { Tabs as TinyTabs, TabItem as TinyTabItem, Button as TinyButton } from '@opentiny/vue'
import { AutoTip as vAutoTip } from '@opentiny/vue-directive'
import { languageMap, vueComponents, getWebdocPath, staticDemoPath } from '../cmp-config'
import { languageMap, vueComponents, getWebdocPath, staticDemoPath } from '../views/components-doc/cmp-config'
import { router } from '@/router.js'
import demoConfig from '@demos/config.js'
import { useApiMode, useTemplateMode } from '@/tools'
Expand Down
Loading
Loading