Skip to content
介绍

TinyRobot 版本

javascript
import { TinyRemoter } from '@opentiny/next-remoter'

该组件为使用 @opentiny/tiny-robot 开发的 TinyRemoter, 仅支持 Vue3

主要功能:

  • 对话LLM
  • 欢迎界面以及suggestions的展示
  • 多角色展示消息以及MD, TOOL调用等展示
  • 支持新建会话
  • 支持扫码添加应用
  • 支持MCP市场

1、扫码应用的 sessionId 后,它会自动创建一个 streamableHTTP 类型的 MCPServer,之后自动创建 MCPClient连接并查询所有的 TOOLS, 并展示在"已安装插件"列表中。 2、市场应用的插件,通常都是 streamableHTTPSSE 类型的 MCPServer。 选择添加后,也是自动创建 MCPClient连接并查询所有的 TOOLS, 并展示在"已安装插件"列表中。

总之,已安装插件中的所有Tool都可以在与 LLM 对话时被调用。

属性

  • v-model:show 双向绑定是否显示,内部关闭是 emit('update:show',false)
  • v-model:fullscreen 双向绑定是否全屏
  • sessionId 必须传
  • title 左上角的 container.title
  • agentRoot 后端代理的地址,有默认值 https://agent.opentiny.design/api/v1/webmcp-trial/
  • locale 国际化key, 可选值为:'zh-CN' | 'en-US' 。一些默认描述,placeholder的国际化的key: lang=zh-CN
  • mode 展示模式,可选值为:'remoter' | 'chat-dialog'。遥控器模式: 自动在右下角显示一个AI图标,点击展开多个菜单项; 对话框模式: 直接显示一个对话框界面
  • remoteUrl 远程URL,用于显示在遥控器模式下,点击遥控器图标后,显示的菜单项。
  • qrCodeUrl 二维码URL,用于显示在遥控器模式下,点击遥控器图标后,弹出二维码对应的链接 url。
  • menuItems 菜单项配置数组,用于显示在遥控器模式下,点击遥控器图标后,显示的菜单项。具体配置项见 api-createRemoter
  • systemPrompt 对话llm 时,传入的 system message: system-prompt=你是一个智能助手,工作地点是深圳
  • llmConfig 大语言模型配置对象,支持配置 apiKeybaseURLmodelmaxStepsproviderTypeproviderOptionsextraTools,其中 apiKey/baseURL/providerTypellmConfig.llm 二选一
  • inBrowserExt 设置组件运行在普通页面还是浏览器的扩展中,默认值为:false
  • genUiAble 设置是否支持生成式UI的渲染,默认值为:false
  • genUiComponents 生成式UI内置了一批组件,如果需要引入新组件,需要通过这里导入。 参考示例: shallowReactive({TinyUser, TinyAlert })
  • customMarketMcpServers 追加自定义 MCP 市场服务列表(PluginInfo[]),传入后会与组件内置的 DEFAULT_SERVERS 合并,用于扩展市场内容
  • skills 设置技能的配置数组。 在聊天输入框中输入 @ 符号能唤起技能列表,选择相应的技能后,可能快速附带上技能对应的提示词内容,参考底部示例。

llmConfig 配置详情

typescript
type ProviderFactoryConfig = {
  /** API密钥 */
  apiKey: string
  /** API基础URL */
  baseURL: string
  /** 提供商类型,支持 'openai' | 'deepseek' 或自定义Provider函数 */
  providerType: 'openai' | 'deepseek' | ((options: any) => ProviderV2)
}

type ProviderInstanceConfig = {
  /** 直接传入 ai-sdk Provider 实例,优先级最高 */
  llm: ProviderV2
}

type ICustomAgentModelProviderLlmConfig = (ProviderFactoryConfig | ProviderInstanceConfig) & {
  /** 模型名称 */
  model: string
  /** 工具调用最大步数,默认为15 */
  maxSteps?: number
  /** Provider 额外参数 */
  providerOptions?: Record<string, any>
  /** 额外自定义工具 */
  extraTools?: Record<string, any>
}

通过 llmConfig.llm 使用自定义 Provider

llmConfig.llm 可以接受任何符合 ai-sdk Provider 规范的实例,例如:

typescript
import { createOpenAI } from '@ai-sdk/openai'
import { createAnthropic } from '@ai-sdk/anthropic'

const llmConfig = {
  // OpenAI Provider
  llm: createOpenAI({
    apiKey: process.env.OPENAI_API_KEY,
    baseURL: 'https://api.openai.com/v1'
  })
}

const claudeConfig = {
  // Anthropic Provider
  llm: createAnthropic({
    apiKey: process.env.ANTHROPIC_API_KEY
  })
}

插槽

  • #welcome: 没有对话消息时,展示在组件中间的 Welcome & Promts 等内容。设计成插槽可以让用户有完全的定制能力。
  • #suggestions: 展示在输入框上面的提示性组件。可以使用 @opentiny/tiny-robot 中的 SuggestionPills 等强大功能的组件。
  • #operations: 容器头部右侧的操作区域,默认包含新建会话按钮、历史会话按钮和扫码组件。可以通过此插槽自定义头部操作按钮。
  • #header-actions: MCP 服务器选择器(插件市场)头部的操作区域,可以在此处添加自定义操作按钮,如自定义添加插件的按钮等。

插槽使用示例

自定义头部操作区域(operations 插槽)

vue
<template>
  <TinyRemoter v-model:show="show" sessionId="your-session-id" title="我的AI助手" systemPrompt="你是一个智能助手">
    <template #operations>
      <!-- 自定义头部操作按钮 -->
      <button @click="handleCustomAction">自定义操作</button>
      <!-- 或者保留默认功能,添加额外按钮 -->
      <button @click="handleExport">导出对话</button>
    </template>
  </TinyRemoter>
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'

const show = ref(false)

function handleCustomAction() {
  console.log('执行自定义操作')
}

function handleExport() {
  console.log('导出对话')
}
</script>

自定义插件市场头部操作(header-actions 插槽)

vue
<template>
  <TinyRemoter v-model:show="show" sessionId="your-session-id" title="我的AI助手" systemPrompt="你是一个智能助手">
    <template #header-actions>
      <!-- 在插件市场头部添加自定义按钮 -->
      <button class="custom-add-button" type="button" @click="openCustomModal">
        <span>+</span>
        自定义添加
      </button>
    </template>
  </TinyRemoter>
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'

const show = ref(false)

function openCustomModal() {
  // 打开自定义添加插件的弹窗
  console.log('打开自定义添加弹窗')
}
</script>

自定义欢迎界面和提示建议(welcome 和 suggestions 插槽)

vue
<template>
  <TinyRemoter
    ref="robotRef"
    v-model:show="show"
    sessionId="your-session-id"
    title="我的AI助手"
    systemPrompt="你是一个智能助手"
  >
    <!-- 自定义欢迎界面 -->
    <template #welcome>
      <div class="custom-welcome">
        <h2>欢迎使用 AI 助手</h2>
        <p>我可以帮助你完成各种任务</p>
        <div class="prompts">
          <button v-for="prompt in prompts" :key="prompt.id" @click="handlePromptClick(prompt)">
            {{ prompt.label }}
          </button>
        </div>
      </div>
    </template>

    <!-- 自定义输入框上方的提示建议 -->
    <template #suggestions>
      <div class="suggestion-pills">
        <button
          v-for="suggestion in suggestions"
          :key="suggestion"
          class="suggestion-pill"
          @click="handleSuggestionClick(suggestion)"
        >
          {{ suggestion }}
        </button>
      </div>
    </template>
  </TinyRemoter>
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'

const show = ref(false)
const robotRef = ref()

const prompts = [
  { id: 1, label: '帮我写一个快速排序', text: '帮我写一个快速排序算法' },
  { id: 2, label: '解释一下 Vue3 的响应式原理', text: '请详细解释 Vue3 的响应式原理' }
]

const suggestions = ['天气查询', '日程安排', '代码生成', '文本翻译']

function handlePromptClick(prompt) {
  // 使用组件暴露的方法发送消息
  robotRef.value?.sendMessage(prompt.text)
}

function handleSuggestionClick(suggestion) {
  robotRef.value?.sendMessage(suggestion)
}
</script>

导出变量

typescript
defineExpose({
  /** 欢迎图标 */
  welcomeIcon,
  /** 对话消息 */
  messages,
  /** 对话消息状态 */
  messageState,
  /** 对话卡片的角色配置 */
  roles,
  /** 输入框的文本 */
  inputMessage,
  /** 输入框组件的实例 */
  senderRef,
  /** 取消发送 */
  abortRequest,
  /** 发送消息 */
  sendMessage
})

导出变量是方便在插槽中使用内部的功能,比如 #welcome 插槽 中点击后 Promts ,发出固定的请求:

typescript
const robotRef = ref<InstanceType<typeof TinyRemoter>>()

function promtClick(item) {
  robotRef.sendMessage(item.description)
}

自定义市场 MCP 插件(customMarketMcpServers)

customMarketMcpServers 属性让你可以在 TinyRemoter 的“插件市场”中动态追加自有 MCP 服务,数组结构遵循 PluginInfo 定义,常用字段如下:

ts
const customMarketMcpServers = [
  {
    id: 'ppt-mcp',
    name: 'PPT文档MCP服务器',
    description: '可以创建、编辑、保存PPT文档',
    icon: 'https://your-mcp-server-icon-url.com/icon.png',
    url: 'https://your-mcp-server-url.com/servers/ppt-mcp/sse',
    type: 'sse',
    enabled: false,
    addState: 'idle',
    tools: []
  }
]
  • id 需要保持唯一(最终会拼接成 plugin-${id}
  • type 对应该 MCP 服务的协议类型,例如 sseStreamableHTTP
  • enabled/addState/tools 驱动 TinyRemoter 市场内的状态展示(中文注释:配合 UI 控制按钮、进度等)

组件初始化时会把上述数组与 DEFAULT_SERVERS 合并,因此你可以通过简单传参扩展默认市场。

使用示例

基本使用

vue
<template>
  <TinyRemoter v-model:show="show" sessionId="your-session-id" title="我的AI助手" systemPrompt="你是一个智能助手" />
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'

const show = ref(false)
</script>

使用自定义LLM配置

vue
<template>
  <TinyRemoter
    v-model:show="show"
    sessionId="your-session-id"
    title="我的AI助手"
    systemPrompt="你是一个智能助手"
    :llmConfig="llmConfig"
  />
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'

const show = ref(false)

// 使用llmConfig配置
const llmConfig = {
  apiKey: 'your-api-key',
  baseURL: 'https://api.openai.com/v1',
  providerType: 'openai',
  model: 'gpt-4o',
  maxSteps: 10
}
</script>

使用自定义Provider实例

vue
<template>
  <TinyRemoter
    v-model:show="show"
    sessionId="your-session-id"
    title="我的AI助手"
    systemPrompt="你是一个智能助手"
    :llmConfig="llmConfig"
  />
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'
import { createOpenAI } from '@ai-sdk/openai'

const show = ref(false)

// 使用自定义Provider实例
const llmConfig = {
  llm: createOpenAI({
    apiKey: process.env.OPENAI_API_KEY,
    baseURL: 'https://api.openai.com/v1',
    fetch: (...args) => {
      // 这里可以自定义大模型请求链接地址,非必要无需配置fetch
      args[0] = args[0] + '?test=123'
      return fetch(...args)
    }
  })
}
</script>

使用DeepSeek模型

vue
<template>
  <TinyRemoter
    v-model:show="show"
    sessionId="your-session-id"
    title="我的AI助手"
    systemPrompt="你是一个智能助手"
    :llmConfig="deepSeekConfig"
  />
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'

const show = ref(false)

// 使用DeepSeek配置
const deepSeekConfig = {
  apiKey: 'your-deepseek-api-key',
  baseURL: 'https://api.deepseek.com',
  providerType: 'deepseek',
  model: 'DeepSeek-V3',
  maxSteps: 10
}
</script>

使用Anthropic Claude模型

vue
<template>
  <TinyRemoter
    v-model:show="show"
    sessionId="your-session-id"
    title="我的AI助手"
    systemPrompt="你是一个智能助手"
    :llmConfig="anthropicConfig"
  />
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'
import { createAnthropic } from '@ai-sdk/anthropic'

const show = ref(false)

// 使用Anthropic Provider
const anthropicConfig = {
  llm: createAnthropic({
    apiKey: process.env.ANTHROPIC_API_KEY
  })
}
</script>

使用自定义Provider函数

vue
<template>
  <TinyRemoter
    v-model:show="show"
    sessionId="your-session-id"
    title="我的AI助手"
    systemPrompt="你是一个智能助手"
    :llmConfig="customConfig"
  />
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'
import { createCustomProvider } from '@ai-sdk/custom'

const show = ref(false)

// 使用自定义Provider函数
const customConfig = {
  apiKey: 'your-custom-api-key',
  baseURL: 'https://api.custom-llm.com/v1',
  providerType: createCustomProvider
}
</script>

环境变量配置示例

vue
<template>
  <TinyRemoter
    v-model:show="show"
    sessionId="your-session-id"
    title="我的AI助手"
    systemPrompt="你是一个智能助手"
    :llmConfig="envConfig"
  />
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'

const show = ref(false)

// 使用环境变量配置
const envConfig = {
  apiKey: import.meta.env.VITE_OPENAI_API_KEY,
  baseURL: import.meta.env.VITE_OPENAI_BASE_URL || 'https://api.openai.com/v1',
  providerType: 'openai',
  model: 'gpt-4o',
  maxSteps: 10
}
</script>

配置技能列表

在输入框中输入 @ 可以唤起技能列表,选择相应技能后,可以将技能提示词拼接到 LLM 对话大模型systemPrompt属性中,支持同时@多个技能。

vue
<template>
  <TinyRemoter
    v-model:show="show"
    sessionId="your-session-id"
    title="我的AI助手"
    systemPrompt="你是一个智能助手"
    :llmConfig="llmConfig"
    :skills="skills"
  />
</template>

<script setup>
import { ref } from 'vue'
import { TinyRemoter } from '@opentiny/next-remoter'
import { createAnthropic } from '@ai-sdk/anthropic'

const show = ref(false)

const llmConfig = {
  apiKey: 'your-api-key',
  baseURL: 'https://api.openai.com/v1',
  providerType: 'openai',
  model: 'gpt-4o',
  maxSteps: 10
}
interface SkillItem{
  /** 技能名称 */
  label:string;
  /** 技能的提示词 */
  value:string;
  /** 【可选】技能依赖的 MCP 工具名称列表 */
  tools? :string[];
}

const skills= ref([
  {label:'办公助手', value:'你是一个办公助手,可以.......'},
  {label:'画图专家', value:'你是一个画图专家,可以.......', tools: ['openUrl','computer']},
])
</script>