@opentiny/tiny-robot-cli 0.5.2-alpha.13 → 0.5.2-alpha.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +32 -5
  2. package/bin/commands/add.js +589 -198
  3. package/bin/utils.js +139 -47
  4. package/package.json +4 -3
  5. package/templates/basic/.env.example +8 -0
  6. package/templates/basic/README.md +53 -22
  7. package/templates/basic/index.html +2 -2
  8. package/templates/basic/package.json +12 -16
  9. package/templates/basic/public/favicon.svg +1 -0
  10. package/templates/basic/public/icons.svg +24 -0
  11. package/templates/basic/src/App.vue +112 -119
  12. package/templates/basic/src/main.ts +2 -2
  13. package/templates/basic/tsconfig.app.json +2 -5
  14. package/templates/basic/tsconfig.node.json +3 -6
  15. package/templates/basic/vite.config.ts +6 -1
  16. package/templates/chat/.env.example +8 -0
  17. package/templates/chat/README.md +21 -13
  18. package/templates/chat/package.json +5 -5
  19. package/templates/chat/src/TinyRobotChat.vue +52 -132
  20. package/templates/chat/src/components/ComposerTools.vue +99 -0
  21. package/templates/chat/src/{tiny-robot-chat/components → components}/WindowHeader.vue +1 -1
  22. package/templates/chat/src/{tiny-robot-chat/composables → composables}/useWindow.ts +8 -18
  23. package/templates/chat/src/config/chat-runtime.ts +82 -0
  24. package/templates/chat/src/{tiny-robot-chat/config → config}/chat-ui.ts +22 -4
  25. package/templates/chat/src/index.css +116 -0
  26. package/templates/chat/src/main.ts +3 -0
  27. package/templates/basic/public/modelcontextprotocol.png +0 -0
  28. package/templates/basic/src/components/ChatList.vue +0 -82
  29. package/templates/basic/src/components/ChatSender.vue +0 -125
  30. package/templates/basic/src/components/ConversationHistory.vue +0 -136
  31. package/templates/basic/src/components/HistoryDrawerButton.vue +0 -43
  32. package/templates/basic/src/components/McpServerPickerButton.vue +0 -278
  33. package/templates/basic/src/components/ThemeToggleButton.vue +0 -44
  34. package/templates/basic/src/components/icons/IconDeepThink.vue +0 -29
  35. package/templates/basic/src/components/icons/IconModelAliyunBailian.vue +0 -51
  36. package/templates/basic/src/components/icons/IconModelDeepseek.vue +0 -29
  37. package/templates/basic/src/components/icons/IconMoon.vue +0 -29
  38. package/templates/basic/src/components/icons/IconPlugin.vue +0 -29
  39. package/templates/basic/src/components/icons/IconSun.vue +0 -35
  40. package/templates/basic/src/components/icons/IconWebSearch.vue +0 -36
  41. package/templates/basic/src/components/icons/index.ts +0 -7
  42. package/templates/basic/src/composables/useChat.ts +0 -129
  43. package/templates/basic/src/composables/useMcp.ts +0 -170
  44. package/templates/basic/src/composables/useModel.ts +0 -82
  45. package/templates/basic/src/mcpServers.ts +0 -40
  46. package/templates/basic/src/models.ts +0 -81
  47. package/templates/chat/src/tiny-robot-chat/components/ComposerTools.vue +0 -72
  48. package/templates/chat/src/tiny-robot-chat/config/chat-runtime.ts +0 -26
@@ -1,130 +1,123 @@
1
- <template>
2
- <TrTheme>
3
- <main class="app chat-card">
4
- <ConversationHistory />
5
-
6
- <section class="chat-panel">
7
- <div class="chat-panel-content">
8
- <p v-if="!hasApiConfig" class="config-warning">
9
- 缺少 API 配置,请在 <code>.env</code> 中设置当前模型服务商对应的 Key。
10
- </p>
11
- <header class="chat-header">
12
- <HistoryDrawerButton @click="historyDrawerOpen = true" />
13
- <h3 v-if="currentConversationTitle">{{ currentConversationTitle }}</h3>
14
- <ThemeToggleButton v-if="isWelcomePage" />
15
- </header>
16
-
17
- <ChatList />
18
-
19
- <ChatSender />
20
- </div>
21
- </section>
22
- </main>
23
- </TrTheme>
24
- </template>
25
-
26
1
  <script setup lang="ts">
2
+ import {
3
+ TrChat,
4
+ useLocalChatRuntime,
5
+ type ChatMcpServers,
6
+ type ChatProviderConfig,
7
+ type ChatUIOptions,
8
+ } from '@opentiny/tiny-robot-chat'
27
9
  import { TrThemeProvider as TrTheme } from '@opentiny/tiny-robot'
28
- import { computed, provide, ref } from 'vue'
29
- import ChatList from './components/ChatList.vue'
30
- import ChatSender from './components/ChatSender.vue'
31
- import ConversationHistory from './components/ConversationHistory.vue'
32
- import HistoryDrawerButton from './components/HistoryDrawerButton.vue'
33
- import ThemeToggleButton from './components/ThemeToggleButton.vue'
34
- import { useChat } from './composables/useChat'
35
- import { useModel } from './composables/useModel'
36
-
37
- const { activeConversation, messages } = useChat()
38
- const { hasApiConfig } = useModel()
39
- const historyDrawerOpen = ref(false)
40
- provide('historyDrawerOpen', historyDrawerOpen)
41
-
42
- const isWelcomePage = computed(() => {
43
- return messages.value.filter((item) => item.role !== 'system').length === 0
10
+ import { IconBailian, IconDeepseek } from '@opentiny/tiny-robot-svgs'
11
+
12
+ const modelProviders: ChatProviderConfig[] = [
13
+ {
14
+ type: 'qwen',
15
+ label: 'DashScope',
16
+ apiUrl: import.meta.env.VITE_QWEN_API_URL?.trim() || undefined,
17
+ apiKey: import.meta.env.VITE_ALIYUN_DASHSCOPE_KEY?.trim(),
18
+ models: [
19
+ {
20
+ id: 'qwen3.7-flash',
21
+ label: 'Qwen3.7 Flash',
22
+ icon: IconBailian,
23
+ capabilities: {
24
+ thinking: true,
25
+ search: true,
26
+ },
27
+ },
28
+ {
29
+ id: 'qwen3.7-plus',
30
+ label: 'Qwen3.7 Plus',
31
+ icon: IconBailian,
32
+ capabilities: {
33
+ thinking: true,
34
+ search: true,
35
+ },
36
+ },
37
+ {
38
+ id: 'qwen3.7-max',
39
+ label: 'Qwen3.7 Max',
40
+ icon: IconBailian,
41
+ capabilities: {
42
+ thinking: true,
43
+ search: true,
44
+ },
45
+ },
46
+ ],
47
+ },
48
+ {
49
+ type: 'deepseek',
50
+ apiUrl: import.meta.env.VITE_DEEPSEEK_API_URL?.trim() || undefined,
51
+ apiKey: import.meta.env.VITE_DEEPSEEK_API_KEY?.trim(),
52
+ models: [
53
+ {
54
+ id: 'deepseek-v4-flash',
55
+ label: 'DeepSeek V4 Flash',
56
+ icon: IconDeepseek,
57
+ capabilities: {
58
+ thinking: true,
59
+ },
60
+ },
61
+ {
62
+ id: 'deepseek-v4-pro',
63
+ label: 'DeepSeek V4 Pro',
64
+ icon: IconDeepseek,
65
+ capabilities: {
66
+ thinking: true,
67
+ },
68
+ },
69
+ ],
70
+ },
71
+ ]
72
+
73
+ const amapMcpApiKey = import.meta.env.VITE_ALIYUN_DASHSCOPE_KEY?.trim()
74
+
75
+ const mcpServers = [
76
+ {
77
+ id: 'amap-maps',
78
+ name: '高德地图',
79
+ description: '覆盖地图、导航、地理编码、天气、路径规划、距离测量、关键词搜索和周边搜索等地理信息服务。',
80
+ baseUrl: import.meta.env.VITE_AMAP_MCP_URL?.trim() || 'https://dashscope.aliyuncs.com/api/v1/mcps/amap-maps/mcp',
81
+ icon: 'https://img.alicdn.com/imgextra/i4/O1CN01iPPabT1EGRN6uatHP_!!6000000000324-0-tps-512-512.jpg',
82
+ headers: amapMcpApiKey ? { Authorization: `Bearer ${amapMcpApiKey}` } : undefined,
83
+ },
84
+ {
85
+ id: 'model-context-protocol-mcp',
86
+ name: 'Model Context Protocol MCP',
87
+ description: 'MCP Server',
88
+ baseUrl: '/modelcontextprotocol-mcp',
89
+ installed: true,
90
+ },
91
+ ] satisfies ChatMcpServers
92
+
93
+ const runtime = useLocalChatRuntime({
94
+ mcpServers,
95
+ modelProviders,
44
96
  })
45
97
 
46
- const currentConversationTitle = computed(() => {
47
- return activeConversation.value?.title
48
- })
98
+ const chatUi = {
99
+ layout: {
100
+ rightAside: {
101
+ mode: 'dock',
102
+ width: 400,
103
+ defaultOpen: false,
104
+ },
105
+ },
106
+ } satisfies ChatUIOptions
49
107
  </script>
50
108
 
51
- <style scoped>
52
- .app {
53
- height: 100vh;
54
- display: flex;
55
- justify-content: center;
56
- align-items: stretch;
57
- padding: 0;
58
- }
59
-
60
- .chat-card {
61
- width: 100%;
62
- height: 100vh;
63
- display: flex;
64
- gap: 0;
65
- overflow: hidden;
66
- align-items: stretch;
67
- flex-direction: row;
68
- padding: 0;
69
- margin: 0;
70
- border-radius: 0;
71
- background: var(--tr-container-bg-default);
72
- box-shadow: none;
73
- }
74
-
75
- .chat-panel {
76
- flex: 1;
77
- min-width: 0;
78
- display: flex;
79
- padding: 12px;
80
- }
81
-
82
- .chat-panel-content {
83
- width: 100%;
84
- max-width: 980px;
85
- margin: 0 auto;
86
- display: flex;
87
- flex-direction: column;
88
- gap: 12px;
89
- min-height: 0;
90
- }
91
-
92
- .chat-header h3 {
93
- margin: 0;
94
- flex: 1;
95
- min-width: 0;
96
- white-space: nowrap;
97
- overflow: hidden;
98
- text-overflow: ellipsis;
99
- }
100
-
101
- .chat-header {
102
- display: flex;
103
- align-items: center;
104
- gap: 8px;
105
- }
106
-
107
- .config-warning {
108
- margin: 0;
109
- padding: 10px 12px;
110
- border-radius: 8px;
111
- background: var(--tr-color-warning-light);
112
- color: var(--tr-color-warning);
113
- font-size: 14px;
114
- }
109
+ <template>
110
+ <TrTheme>
111
+ <div class="chat-basic">
112
+ <TrChat :runtime="runtime" :ui="chatUi" />
113
+ </div>
114
+ </TrTheme>
115
+ </template>
115
116
 
117
+ <style scoped>
116
118
  @media (max-width: 959px) {
117
- .chat-header {
118
- position: relative;
119
- justify-content: center;
120
- min-height: 32px;
121
- }
122
-
123
- .chat-header h3 {
124
- width: 100%;
125
- text-align: center;
126
- padding: 0 48px;
127
- flex: none;
119
+ .chat-basic :deep(.tr-bubble__avatar) {
120
+ display: none;
128
121
  }
129
122
  }
130
123
  </style>
@@ -1,7 +1,7 @@
1
1
  import { createApp } from 'vue'
2
- import App from './App.vue'
3
-
2
+ import '@opentiny/tiny-robot-chat/dist/style.css'
4
3
  import '@opentiny/tiny-robot/dist/style.css'
5
4
  import './style.css'
5
+ import App from './App.vue'
6
6
 
7
7
  createApp(App).mount('#app')
@@ -3,14 +3,11 @@
3
3
  "compilerOptions": {
4
4
  "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
5
5
  "types": ["vite/client"],
6
-
7
- /* Linting */
8
- "strict": true,
6
+ "allowArbitraryExtensions": true,
9
7
  "noUnusedLocals": true,
10
8
  "noUnusedParameters": true,
11
9
  "erasableSyntaxOnly": true,
12
- "noFallthroughCasesInSwitch": true,
13
- "noUncheckedSideEffectImports": true
10
+ "noFallthroughCasesInSwitch": true
14
11
  },
15
12
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
16
13
  }
@@ -1,26 +1,23 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
- "target": "ES2023",
4
+ "target": "es2023",
5
5
  "lib": ["ES2023"],
6
- "module": "ESNext",
7
6
  "types": ["node"],
8
7
  "skipLibCheck": true,
9
8
 
10
9
  /* Bundler mode */
11
- "moduleResolution": "bundler",
10
+ "module": "nodenext",
12
11
  "allowImportingTsExtensions": true,
13
12
  "verbatimModuleSyntax": true,
14
13
  "moduleDetection": "force",
15
14
  "noEmit": true,
16
15
 
17
16
  /* Linting */
18
- "strict": true,
19
17
  "noUnusedLocals": true,
20
18
  "noUnusedParameters": true,
21
19
  "erasableSyntaxOnly": true,
22
- "noFallthroughCasesInSwitch": true,
23
- "noUncheckedSideEffectImports": true
20
+ "noFallthroughCasesInSwitch": true
24
21
  },
25
22
  "include": ["vite.config.ts"]
26
23
  }
@@ -1,10 +1,15 @@
1
1
  import { defineConfig } from 'vite'
2
2
  import vue from '@vitejs/plugin-vue'
3
+ import { resolve } from 'node:path'
4
+
5
+ const workspaceRoot = resolve(import.meta.dirname, '..')
3
6
 
4
- // https://vite.dev/config/
5
7
  export default defineConfig({
6
8
  plugins: [vue()],
7
9
  server: {
10
+ fs: {
11
+ allow: [workspaceRoot],
12
+ },
8
13
  proxy: {
9
14
  '/modelcontextprotocol-mcp': {
10
15
  target: 'https://modelcontextprotocol.io/mcp',
@@ -1,2 +1,10 @@
1
+ # Optional custom model endpoints. Leave blank to use official Provider defaults.
2
+ VITE_QWEN_API_URL=
3
+ VITE_DEEPSEEK_API_URL=
4
+
5
+ # Optional custom MCP endpoint. Leave blank to use the official endpoint.
6
+ VITE_AMAP_MCP_URL=
7
+
8
+ # Optional local direct-connection credentials.
1
9
  VITE_ALIYUN_DASHSCOPE_KEY=
2
10
  VITE_DEEPSEEK_API_KEY=
@@ -1,37 +1,45 @@
1
- # chat-add
1
+ # TinyRobot Chat Add
2
2
 
3
- `chat-add` 是一个可嵌入现有 Vue 应用的 Chat 扩展模板,提供通用工作助手场景的最小工程结构。
3
+ 这是一个独立的 Chat 扩展模板,提供通用工作助手场景的最小工程结构。
4
4
 
5
5
  ## 启动
6
6
 
7
7
  ```powershell
8
- pnpm --filter chat-add dev
8
+ pnpm dev
9
9
  ```
10
10
 
11
11
  ## 构建
12
12
 
13
13
  ```powershell
14
- pnpm --filter chat-add type-check
15
- pnpm --filter chat-add build
14
+ pnpm type-check
15
+ pnpm build
16
16
  ```
17
17
 
18
18
  ## 接入真实模型
19
19
 
20
- 将生成的 `.env.example` 复制为 `.env.local`,按需配置 `VITE_ALIYUN_DASHSCOPE_KEY` 和 `VITE_DEEPSEEK_API_KEY`,重启 Vite 后即可使用模型选择器中的真实模型。
20
+ 复制项目根目录的 `.env.example` 为 `.env.local`,配置 `VITE_QWEN_API_URL`、`VITE_ALIYUN_DASHSCOPE_KEY`、`VITE_DEEPSEEK_API_URL` 和 `VITE_DEEPSEEK_API_KEY`,重启 Vite 后即可使用模型选择器中的真实模型。模板只提供 `.env.example`,不会自动创建 `.env`。配置读取逻辑位于 `src/config/chat-runtime.ts`;使用 `add chat` 注入后,对应文件位于 `src/tiny-robot-chat/config/chat-runtime.ts`。
21
21
 
22
- Qwen 和 DeepSeek 默认使用 `@opentiny/tiny-robot-chat` 内置的官方接口地址。仅在使用代理、私有网关或其他地域接口时,才需要在 `.env.local` 中额外配置 `VITE_QWEN_API_URL` 或 `VITE_DEEPSEEK_API_URL`。配置读取逻辑位于 `src/tiny-robot-chat/config/chat-runtime.ts`。
22
+ ## 模型配置
23
+
24
+ 模型配置中的 `icon` 用于模型选择器触发器;在窄容器中,带图标的模型会只显示图标。Qwen 模型支持深度思考和联网搜索,DeepSeek 模型支持深度思考。
25
+
26
+ DeepSeek 模型默认继承 `low`、`high`、`max` 三档思考强度,默认值为 `high`。开启 `深度思考` 后,模型选择器才会显示思考等级。业务侧可以在模型对象中通过 `efforts` 和 `defaultEffort` 覆盖选项;只有必须始终思考的模型才配置 `thinkingRequired: true`。
27
+
28
+ ## MCP 代理
29
+
30
+ 独立模板的 `vite.config.ts` 已配置 `/modelcontextprotocol-mcp` 代理。使用 `add chat` 时,CLI 不会复制或修改业务项目的 `vite.config.*`,需要手动把该代理配置添加到业务项目的 `server.proxy` 下,并重启 Vite。
23
31
 
24
32
  ## 目录职责
25
33
 
26
- - `src/TinyRobotChat.vue`: 悬浮入口、Chat 主体以及组件作用域样式。
27
- - `src/tiny-robot-chat/config/chat-ui.ts`: Chat UI、提示词和模板配置。
28
- - `src/tiny-robot-chat/config/chat-runtime.ts`: 模型配置和留给后续集成的空 MCP Server 列表。
29
- - `src/tiny-robot-chat/components`: 窗口头部和输入区工具。
30
- - `src/tiny-robot-chat/composables/useWindow.ts`: floating、fullscreen 窗口状态。
34
+ - `src/config/chat-ui.ts`: Chat UI、提示词、模板和菜单配置。
35
+ - `src/config/chat-runtime.ts`: MCP 示例和模型配置。
36
+ - `src/components`: 窗口头部和输入区工具。
37
+ - `src/composables/useWindow.ts`: floating、fullscreen 窗口状态。
38
+ - `src/index.css`: 模板公共样式和 Surface 样式变量。
31
39
 
32
40
  ## 替换数据
33
41
 
34
- 直接修改 `src/tiny-robot-chat/config/chat-ui.ts` 和 `src/tiny-robot-chat/config/chat-runtime.ts` 中导出的数据;组件通过 props 使用这些配置。
42
+ 直接修改 `src/config/chat-ui.ts` 和 `src/config/chat-runtime.ts` 中导出的数据;组件通过 props 使用这些配置。
35
43
 
36
44
  ## 切换窗口模式
37
45
 
@@ -10,11 +10,11 @@
10
10
  "type-check": "vue-tsc -b"
11
11
  },
12
12
  "dependencies": {
13
- "@opentiny/tiny-robot": "0.5.2-alpha.10",
14
- "@opentiny/tiny-robot-chat": "0.5.2-alpha.10",
15
- "@opentiny/tiny-robot-kit": "0.5.2-alpha.10",
16
- "@opentiny/tiny-robot-svgs": "0.5.2-alpha.10",
17
- "@vueuse/core": "13.9.0",
13
+ "@opentiny/tiny-robot": "0.5.2-alpha.14",
14
+ "@opentiny/tiny-robot-chat": "0.5.2-alpha.14",
15
+ "@opentiny/tiny-robot-kit": "0.5.2-alpha.14",
16
+ "@opentiny/tiny-robot-svgs": "0.5.2-alpha.14",
17
+ "@vueuse/core": "13.1.0",
18
18
  "vue": "^3.5.40"
19
19
  },
20
20
  "devDependencies": {
@@ -1,16 +1,14 @@
1
1
  <script setup lang="ts">
2
2
  import type { HistoryMenuItem, PromptProps, TemplateItem } from '@opentiny/tiny-robot'
3
3
  import { TrSender, TrThemeProvider as TrTheme } from '@opentiny/tiny-robot'
4
- import '@opentiny/tiny-robot/dist/style.css'
5
4
  import { TrChat, useChatHistoryItems, useLocalChatRuntime, type ChatHistoryItem } from '@opentiny/tiny-robot-chat'
6
- import '@opentiny/tiny-robot-chat/dist/style.css'
7
5
  import { IconAi } from '@opentiny/tiny-robot-svgs'
8
6
  import { computed, reactive, ref } from 'vue'
9
- import ComposerTools from './tiny-robot-chat/components/ComposerTools.vue'
10
- import WindowHeader from './tiny-robot-chat/components/WindowHeader.vue'
11
- import { createChatUi, templateCategories } from './tiny-robot-chat/config/chat-ui'
12
- import { mcpServers, modelProviders } from './tiny-robot-chat/config/chat-runtime'
13
- import { useWindow } from './tiny-robot-chat/composables/useWindow'
7
+ import ComposerTools from './components/ComposerTools.vue'
8
+ import WindowHeader from './components/WindowHeader.vue'
9
+ import { composerMenus, createChatUi, templateCategories } from './config/chat-ui'
10
+ import { mcpExamples, mcpServers, modelProviders } from './config/chat-runtime'
11
+ import { useWindow } from './composables/useWindow'
14
12
 
15
13
  const runtime = useLocalChatRuntime({ modelProviders, mcpServers })
16
14
  const window = reactive(useWindow())
@@ -47,130 +45,52 @@ function handleHistoryAction(action: HistoryMenuItem, item: ChatHistoryItem): vo
47
45
 
48
46
  <template>
49
47
  <TrTheme>
50
- <button
51
- v-if="!window.show"
52
- class="chat-add-launcher"
53
- type="button"
54
- title="打开 TinyRobot"
55
- aria-label="打开 TinyRobot"
56
- @click="window.open"
57
- >
58
- <IconAi style="font-size: 32px" />
59
- </button>
60
- <TrChat
61
- v-if="window.show"
62
- ref="chatRef"
63
- :class="['chat-add-window', `chat-add-window--${window.displayMode}`]"
64
- :style="window.layoutStyle"
65
- :runtime="runtime"
66
- :ui="chatUi"
67
- v-model:floating-state="window.floatingState"
68
- @prompt-click="handlePromptClick"
69
- >
70
- <template #layout-header>
71
- <WindowHeader
72
- :display-mode="window.displayMode"
73
- :show-history="showHistory"
74
- :history-data="historyData"
75
- :active-conversation-id="activeConversationId"
76
- @new-session="handleNewSession"
77
- @select-history="handleHistorySelect"
78
- @rename-history="handleHistoryRename"
79
- @history-action="handleHistoryAction"
80
- @update:show-history="showHistory = $event"
81
- @change-mode="window.setDisplayMode"
82
- @close="window.close"
83
- />
84
- </template>
85
- <template #composer-before>
86
- <ComposerTools v-model:current-template="currentTemplate" :template-categories="templateCategories" />
87
- </template>
88
- </TrChat>
48
+ <main class="chat-add-app">
49
+ <button
50
+ v-if="!window.show"
51
+ class="chat-add-launcher"
52
+ type="button"
53
+ title="打开 TinyRobot"
54
+ aria-label="打开 TinyRobot"
55
+ @click="window.open"
56
+ >
57
+ <IconAi style="font-size: 32px" />
58
+ </button>
59
+ <TrChat
60
+ v-if="window.show"
61
+ ref="chatRef"
62
+ :class="['chat-add-window', `chat-add-window--${window.displayMode}`]"
63
+ :style="window.layoutStyle"
64
+ :runtime="runtime"
65
+ :ui="chatUi"
66
+ v-model:floating-state="window.floatingState"
67
+ @prompt-click="handlePromptClick"
68
+ >
69
+ <template #layout-header>
70
+ <WindowHeader
71
+ :display-mode="window.displayMode"
72
+ :show-history="showHistory"
73
+ :history-data="historyData"
74
+ :active-conversation-id="activeConversationId"
75
+ @new-session="handleNewSession"
76
+ @select-history="handleHistorySelect"
77
+ @rename-history="handleHistoryRename"
78
+ @history-action="handleHistoryAction"
79
+ @update:show-history="showHistory = $event"
80
+ @change-mode="window.setDisplayMode"
81
+ @close="window.close"
82
+ />
83
+ </template>
84
+ <template #composer-before="{ submit }">
85
+ <ComposerTools
86
+ v-model:current-template="currentTemplate"
87
+ :template-categories="templateCategories"
88
+ :mcp-examples="mcpExamples"
89
+ :menus="composerMenus"
90
+ :submit="submit"
91
+ />
92
+ </template>
93
+ </TrChat>
94
+ </main>
89
95
  </TrTheme>
90
96
  </template>
91
-
92
- <style scoped>
93
- .chat-add-launcher {
94
- position: fixed;
95
- right: 24px;
96
- bottom: 24px;
97
- z-index: var(--tr-z-index-popover, 1000);
98
- display: inline-flex;
99
- align-items: center;
100
- justify-content: center;
101
- width: 56px;
102
- height: 56px;
103
- padding: 0;
104
- border: 0;
105
- border-radius: 50%;
106
- background: var(--tr-container-bg-default);
107
- color: var(--tr-color-primary);
108
- box-shadow: 0 8px 24px rgb(0 0 0 / 20%);
109
- cursor: pointer;
110
- }
111
- .chat-add-launcher:hover {
112
- background: var(--tr-color-primary-light);
113
- }
114
- .chat-add-launcher:focus-visible {
115
- outline: 2px solid var(--tr-color-primary);
116
- outline-offset: 3px;
117
- }
118
- @media (max-width: 519px) {
119
- .chat-add-launcher {
120
- right: 16px;
121
- bottom: 16px;
122
- }
123
- }
124
- </style>
125
-
126
- <style>
127
- .chat-add-window {
128
- --chat-prompt-min-width: 280px;
129
- --tr-layout-bg-default: #f5f5f7;
130
- --tr-chat-ui-header-bg: #f5f5f7;
131
- --tr-chat-ui-main-bg: #f5f5f7;
132
- --tr-chat-ui-footer-bg: #f5f5f7;
133
- min-width: 0;
134
- }
135
- .chat-add-window .tr-welcome {
136
- box-sizing: border-box;
137
- width: 100%;
138
- padding: 24px 24px 0;
139
- }
140
- .chat-add-window .tr-welcome__title-wrapper {
141
- display: flex;
142
- align-items: center;
143
- justify-content: center;
144
- }
145
- .chat-add-window .tr-prompts {
146
- --tr-prompts-gap: 16px;
147
- box-sizing: border-box;
148
- width: 100%;
149
- padding: 16px 24px;
150
- }
151
- .chat-add-window .tr-prompts .tr-prompts__list-container.wrap {
152
- display: grid;
153
- grid-template-columns: repeat(2, minmax(var(--chat-prompt-min-width), 1fr));
154
- }
155
- .chat-add-window .tr-prompts__list-container > .prompt-item {
156
- box-sizing: border-box;
157
- width: 100%;
158
- min-width: 0;
159
- }
160
- @container (max-width: 623px) {
161
- .chat-add-window .tr-prompts .tr-prompts__list-container.wrap {
162
- grid-template-columns: minmax(0, 1fr);
163
- }
164
- }
165
- @container (max-width: 519px) {
166
- .chat-add-window .tr-welcome {
167
- padding-inline: 12px;
168
- }
169
- .chat-add-window .tr-prompts {
170
- padding-inline: 12px;
171
- }
172
- .chat-add-window .tr-bubble__avatar {
173
- display: none;
174
- }
175
- }
176
- </style>