@opentiny/tiny-robot-cli 0.5.0 → 0.5.2-alpha.12

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.
@@ -0,0 +1,271 @@
1
+ import type { LayoutFloatingOptions } from '@opentiny/tiny-robot'
2
+ import type { ChatSenderOptions, ChatUIOptions } from '@opentiny/tiny-robot-chat'
3
+ import type { TemplateItem } from '@opentiny/tiny-robot'
4
+ import { IconAi, IconUser } from '@opentiny/tiny-robot-svgs'
5
+ import { h, type CSSProperties } from 'vue'
6
+
7
+ export interface ChatUiConfigOptions {
8
+ floatingOptions: Readonly<LayoutFloatingOptions>
9
+ templateExtensions: NonNullable<ChatSenderOptions['extensions']>
10
+ }
11
+
12
+ export interface PromptItemData {
13
+ label: string
14
+ description: string
15
+ emoji: string
16
+ badge?: string
17
+ }
18
+
19
+ export const PROMPT_ITEMS_DATA: PromptItemData[] = [
20
+ {
21
+ label: '日常助理场景',
22
+ description: '今天需要我帮你安排日程,规划旅行,还是起草一封邮件?',
23
+ emoji: '🧠',
24
+ badge: 'NEW',
25
+ },
26
+ {
27
+ label: '学习/知识型场景',
28
+ description: '有什么想了解的吗?可以是"Vue3 和 React 的区别"!',
29
+ emoji: '🤔',
30
+ },
31
+ {
32
+ label: '创意生成场景',
33
+ description: '想写段文案、起个名字,还是来点灵感?',
34
+ emoji: '✨',
35
+ },
36
+ {
37
+ label: '工作效率场景',
38
+ description: '需要我帮你总结内容、拆解任务,还是整理一份行动清单?',
39
+ emoji: '⚡',
40
+ },
41
+ ]
42
+
43
+ export const prompts = PROMPT_ITEMS_DATA
44
+
45
+ export interface TemplateSuggestionItem {
46
+ id: string
47
+ text: string
48
+ template: TemplateItem[]
49
+ }
50
+
51
+ export const templateSuggestions: TemplateSuggestionItem[] = [
52
+ {
53
+ id: 'write',
54
+ text: '帮我写作',
55
+ template: [
56
+ { id: 'write-prefix', type: 'text', content: '请帮我撰写一篇' },
57
+ {
58
+ id: 'write-kind',
59
+ type: 'select',
60
+ content: '',
61
+ placeholder: '文章类型',
62
+ options: [
63
+ { label: '公告', value: '公告' },
64
+ { label: '方案', value: '方案' },
65
+ { label: '邮件', value: '邮件' },
66
+ ],
67
+ },
68
+ { id: 'write-topic-prefix', type: 'text', content: ',主题是' },
69
+ { id: 'write-topic', type: 'block', content: '主题' },
70
+ { id: 'write-tone-prefix', type: 'text', content: ',语气是' },
71
+ {
72
+ id: 'write-tone',
73
+ type: 'select',
74
+ content: '',
75
+ placeholder: '语气类型',
76
+ options: [
77
+ { label: '正式', value: '正式' },
78
+ { label: '轻松', value: '轻松' },
79
+ { label: '专业', value: '专业' },
80
+ ],
81
+ },
82
+ { id: 'write-description-prefix', type: 'text', content: ',具体内容是' },
83
+ { id: 'write-description', type: 'block', content: '详细描述' },
84
+ ],
85
+ },
86
+ {
87
+ id: 'translate',
88
+ text: '翻译',
89
+ template: [
90
+ { id: 'translate-source-prefix', type: 'text', content: '请将以下' },
91
+ {
92
+ id: 'translate-source-language',
93
+ type: 'select',
94
+ content: '',
95
+ placeholder: '源语言',
96
+ options: [
97
+ { label: '中文', value: '中文' },
98
+ { label: '英文', value: '英文' },
99
+ { label: '日语', value: '日语' },
100
+ ],
101
+ },
102
+ { id: 'translate-content-prefix', type: 'text', content: '内容翻译成' },
103
+ {
104
+ id: 'translate-target-language',
105
+ type: 'select',
106
+ content: '',
107
+ placeholder: '目标语言',
108
+ options: [
109
+ { label: '中文', value: '中文' },
110
+ { label: '英文', value: '英文' },
111
+ { label: '日语', value: '日语' },
112
+ ],
113
+ },
114
+ { id: 'translate-content-suffix', type: 'text', content: ',内容是' },
115
+ { id: 'translate-content', type: 'block', content: '需要翻译的内容' },
116
+ ],
117
+ },
118
+ {
119
+ id: 'code-review',
120
+ text: '代码审查',
121
+ template: [
122
+ { id: 'code-review-prefix', type: 'text', content: '请帮我审查以下' },
123
+ {
124
+ id: 'code-review-language',
125
+ type: 'select',
126
+ content: '',
127
+ placeholder: '代码语言',
128
+ options: [
129
+ { label: 'JavaScript', value: 'JavaScript' },
130
+ { label: 'TypeScript', value: 'TypeScript' },
131
+ { label: 'Python', value: 'Python' },
132
+ ],
133
+ },
134
+ { id: 'code-review-focus-prefix', type: 'text', content: '代码,关注' },
135
+ {
136
+ id: 'code-review-focus',
137
+ type: 'select',
138
+ content: '',
139
+ placeholder: '关注方向',
140
+ options: [
141
+ { label: '性能', value: '性能' },
142
+ { label: '安全', value: '安全' },
143
+ { label: '可读性', value: '可读性' },
144
+ ],
145
+ },
146
+ { id: 'code-review-content-prefix', type: 'text', content: '方面,代码如下:' },
147
+ { id: 'code-review-content', type: 'block', content: '代码内容' },
148
+ ],
149
+ },
150
+ {
151
+ id: 'email-compose',
152
+ text: '写邮件',
153
+ template: [
154
+ { id: 'email-compose-prefix', type: 'text', content: '请帮我起草一封' },
155
+ {
156
+ id: 'email-compose-type',
157
+ type: 'select',
158
+ content: '',
159
+ placeholder: '邮件类型',
160
+ options: [
161
+ { label: '正式', value: '正式' },
162
+ { label: '非正式', value: '非正式' },
163
+ ],
164
+ },
165
+ { id: 'email-compose-recipient-prefix', type: 'text', content: '邮件,发送给' },
166
+ { id: 'email-compose-recipient', type: 'block', content: '收件人角色' },
167
+ { id: 'email-compose-subject-prefix', type: 'text', content: ',主题是' },
168
+ { id: 'email-compose-subject', type: 'block', content: '邮件主题' },
169
+ { id: 'email-compose-content-prefix', type: 'text', content: ',内容是关于' },
170
+ { id: 'email-compose-content', type: 'block', content: '邮件内容' },
171
+ ],
172
+ },
173
+ {
174
+ id: 'interview-questions',
175
+ text: '面试问题',
176
+ template: [
177
+ { id: 'interview-questions-prefix', type: 'text', content: '请为' },
178
+ { id: 'interview-questions-role', type: 'block', content: '岗位名称' },
179
+ { id: 'interview-questions-skill-prefix', type: 'text', content: '岗位,针对' },
180
+ { id: 'interview-questions-skill', type: 'block', content: '技能领域' },
181
+ { id: 'interview-questions-count-prefix', type: 'text', content: '方向,设计' },
182
+ {
183
+ id: 'interview-questions-count',
184
+ type: 'select',
185
+ content: '',
186
+ placeholder: '问题数量',
187
+ options: [
188
+ { label: '3', value: '3' },
189
+ { label: '5', value: '5' },
190
+ { label: '10', value: '10' },
191
+ ],
192
+ },
193
+ { id: 'interview-questions-difficulty-prefix', type: 'text', content: '个难度为' },
194
+ {
195
+ id: 'interview-questions-difficulty',
196
+ type: 'select',
197
+ content: '',
198
+ placeholder: '岗位难度',
199
+ options: [
200
+ { label: '简单', value: '简单' },
201
+ { label: '中等', value: '中等' },
202
+ { label: '困难', value: '困难' },
203
+ ],
204
+ },
205
+ { id: 'interview-questions-suffix', type: 'text', content: '的面试问题' },
206
+ ],
207
+ },
208
+ ]
209
+
210
+ export interface TemplateCategory {
211
+ id: string
212
+ title: string
213
+ items: TemplateSuggestionItem[]
214
+ }
215
+
216
+ export const templateCategories: TemplateCategory[] = [
217
+ { id: 'writing', title: '写作表达', items: [templateSuggestions[0]] },
218
+ { id: 'language', title: '语言处理', items: [templateSuggestions[1]] },
219
+ { id: 'engineering', title: '研发协作', items: [templateSuggestions[2]] },
220
+ { id: 'communication', title: '工作沟通', items: [templateSuggestions[3]] },
221
+ { id: 'growth', title: '人才发展', items: [templateSuggestions[4]] },
222
+ ]
223
+
224
+ const promptItems = PROMPT_ITEMS_DATA.map((item) => ({
225
+ ...item,
226
+ icon: h('span', { style: { fontSize: '18px' } as CSSProperties }, item.emoji) as never,
227
+ }))
228
+
229
+ export function createChatUi(options: ChatUiConfigOptions): ChatUIOptions {
230
+ return {
231
+ history: false,
232
+ welcome: {
233
+ title: 'TinyRobot',
234
+ description: '您好,我是TinyRobot,您专属的 AI 智能专家',
235
+ icon: h(IconAi, { style: { fontSize: '48px' } }) as never,
236
+ },
237
+ prompts: { items: promptItems, wrap: true, itemClass: 'prompt-item' },
238
+ bubble: {
239
+ autoScroll: true,
240
+ bubbleList: {
241
+ roleConfigs: {
242
+ assistant: { placement: 'start', avatar: h(IconAi, { style: { fontSize: '32px' } }) as never },
243
+ user: { placement: 'end', avatar: h(IconUser, { style: { fontSize: '32px' } }) as never },
244
+ system: { hidden: true },
245
+ },
246
+ },
247
+ },
248
+ layout: {
249
+ heightMode: 'parent',
250
+ leftAside: false,
251
+ rightAside: {
252
+ mode: 'drawer',
253
+ width: 400,
254
+ defaultOpen: false,
255
+ },
256
+ surface: { mode: 'floating', floatingOptions: options.floatingOptions },
257
+ emptyState: 'center',
258
+ composer: { welcome: 'footer' },
259
+ contentMaxWidth: 1280,
260
+ panelPadding: 0,
261
+ panelGap: 0,
262
+ } as ChatUIOptions['layout'],
263
+ sender: {
264
+ mode: 'multiple',
265
+ clearable: true,
266
+ showWordLimit: true,
267
+ maxLength: 2000,
268
+ extensions: options.templateExtensions,
269
+ },
270
+ }
271
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
3
+ "compilerOptions": {
4
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
5
+ "types": ["vite/client"],
6
+ "allowArbitraryExtensions": true,
7
+ "noUnusedLocals": true,
8
+ "noUnusedParameters": true,
9
+ "erasableSyntaxOnly": true,
10
+ "noFallthroughCasesInSwitch": true
11
+ },
12
+ "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
13
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "es2023",
5
+ "lib": ["ES2023"],
6
+ "types": ["node"],
7
+ "skipLibCheck": true,
8
+ "module": "nodenext",
9
+ "allowImportingTsExtensions": true,
10
+ "verbatimModuleSyntax": true,
11
+ "moduleDetection": "force",
12
+ "noEmit": true,
13
+ "noUnusedLocals": true,
14
+ "noUnusedParameters": true,
15
+ "erasableSyntaxOnly": true,
16
+ "noFallthroughCasesInSwitch": true
17
+ },
18
+ "include": ["vite.config.ts"]
19
+ }
@@ -0,0 +1,16 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+
4
+ // https://vite.dev/config/
5
+ export default defineConfig({
6
+ plugins: [vue()],
7
+ server: {
8
+ proxy: {
9
+ '/modelcontextprotocol-mcp': {
10
+ target: 'https://modelcontextprotocol.io/mcp',
11
+ changeOrigin: true,
12
+ rewrite: (path) => path.replace(/^\/modelcontextprotocol-mcp/, ''),
13
+ },
14
+ },
15
+ },
16
+ })