@huyooo/ai-chat-frontend-vue 0.1.6 → 0.1.7

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 (159) hide show
  1. package/README.md +367 -0
  2. package/dist/adapter.d.ts +7 -7
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/components/ChatPanel.vue.d.ts +120 -9
  5. package/dist/components/ChatPanel.vue.d.ts.map +1 -1
  6. package/dist/components/common/ConfirmDialog.vue.d.ts +30 -0
  7. package/dist/components/common/ConfirmDialog.vue.d.ts.map +1 -0
  8. package/dist/components/common/CopyButton.vue.d.ts +18 -0
  9. package/dist/components/common/CopyButton.vue.d.ts.map +1 -0
  10. package/dist/components/common/IndexingSettings.vue.d.ts +3 -0
  11. package/dist/components/common/IndexingSettings.vue.d.ts.map +1 -0
  12. package/dist/components/common/SettingsPanel.vue.d.ts +16 -0
  13. package/dist/components/common/SettingsPanel.vue.d.ts.map +1 -0
  14. package/dist/components/common/Toast.vue.d.ts +18 -0
  15. package/dist/components/common/Toast.vue.d.ts.map +1 -0
  16. package/dist/components/common/ToggleSwitch.vue.d.ts +10 -0
  17. package/dist/components/common/ToggleSwitch.vue.d.ts.map +1 -0
  18. package/dist/components/{chat/ui → header}/ChatHeader.vue.d.ts +5 -3
  19. package/dist/components/header/ChatHeader.vue.d.ts.map +1 -0
  20. package/dist/components/input/AtFilePicker.vue.d.ts +21 -0
  21. package/dist/components/input/AtFilePicker.vue.d.ts.map +1 -0
  22. package/dist/components/{ChatInput.vue.d.ts → input/ChatInput.vue.d.ts} +16 -14
  23. package/dist/components/input/ChatInput.vue.d.ts.map +1 -0
  24. package/dist/components/input/DropdownSelector.vue.d.ts +42 -0
  25. package/dist/components/input/DropdownSelector.vue.d.ts.map +1 -0
  26. package/dist/components/input/ImagePreviewModal.vue.d.ts +17 -0
  27. package/dist/components/input/ImagePreviewModal.vue.d.ts.map +1 -0
  28. package/dist/components/input/at-views/AtBranchView.vue.d.ts +18 -0
  29. package/dist/components/input/at-views/AtBranchView.vue.d.ts.map +1 -0
  30. package/dist/components/input/at-views/AtBrowserView.vue.d.ts +18 -0
  31. package/dist/components/input/at-views/AtBrowserView.vue.d.ts.map +1 -0
  32. package/dist/components/input/at-views/AtChatsView.vue.d.ts +18 -0
  33. package/dist/components/input/at-views/AtChatsView.vue.d.ts.map +1 -0
  34. package/dist/components/input/at-views/AtDocsView.vue.d.ts +18 -0
  35. package/dist/components/input/at-views/AtDocsView.vue.d.ts.map +1 -0
  36. package/dist/components/input/at-views/AtFilesView.vue.d.ts +23 -0
  37. package/dist/components/input/at-views/AtFilesView.vue.d.ts.map +1 -0
  38. package/dist/components/input/at-views/AtTerminalsView.vue.d.ts +18 -0
  39. package/dist/components/input/at-views/AtTerminalsView.vue.d.ts.map +1 -0
  40. package/dist/components/message/MessageBubble.vue.d.ts +45 -0
  41. package/dist/components/message/MessageBubble.vue.d.ts.map +1 -0
  42. package/dist/components/message/PartsRenderer.vue.d.ts +15 -0
  43. package/dist/components/message/PartsRenderer.vue.d.ts.map +1 -0
  44. package/dist/components/message/WelcomeMessage.vue.d.ts +14 -0
  45. package/dist/components/message/WelcomeMessage.vue.d.ts.map +1 -0
  46. package/dist/components/message/blocks/CodeBlock.vue.d.ts +11 -0
  47. package/dist/components/message/blocks/CodeBlock.vue.d.ts.map +1 -0
  48. package/dist/components/{chat/SearchResultBlock.vue.d.ts → message/blocks/TextBlock.vue.d.ts} +3 -4
  49. package/dist/components/message/blocks/TextBlock.vue.d.ts.map +1 -0
  50. package/dist/components/message/blocks/index.d.ts +6 -0
  51. package/dist/components/message/blocks/index.d.ts.map +1 -0
  52. package/dist/components/message/parts/CollapsibleCard.vue.d.ts +45 -0
  53. package/dist/components/message/parts/CollapsibleCard.vue.d.ts.map +1 -0
  54. package/dist/components/{chat/ToolCallBlock.vue.d.ts → message/parts/ErrorPart.vue.d.ts} +4 -5
  55. package/dist/components/message/parts/ErrorPart.vue.d.ts.map +1 -0
  56. package/dist/components/{chat/ThinkingBlock.vue.d.ts → message/parts/ImagePart.vue.d.ts} +3 -3
  57. package/dist/components/message/parts/ImagePart.vue.d.ts.map +1 -0
  58. package/dist/components/message/parts/SearchPart.vue.d.ts +12 -0
  59. package/dist/components/message/parts/SearchPart.vue.d.ts.map +1 -0
  60. package/dist/components/{chat/messages/ExecutionSteps.vue.d.ts → message/parts/TextPart.vue.d.ts} +2 -9
  61. package/dist/components/message/parts/TextPart.vue.d.ts.map +1 -0
  62. package/dist/components/message/parts/ThinkingPart.vue.d.ts +12 -0
  63. package/dist/components/message/parts/ThinkingPart.vue.d.ts.map +1 -0
  64. package/dist/components/message/parts/ToolCallPart.vue.d.ts +19 -0
  65. package/dist/components/message/parts/ToolCallPart.vue.d.ts.map +1 -0
  66. package/dist/components/message/parts/ToolResultPart.vue.d.ts +14 -0
  67. package/dist/components/message/parts/ToolResultPart.vue.d.ts.map +1 -0
  68. package/dist/components/message/parts/index.d.ts +12 -0
  69. package/dist/components/message/parts/index.d.ts.map +1 -0
  70. package/dist/components/message/tool-results/DefaultToolResult.vue.d.ts +4 -0
  71. package/dist/components/message/tool-results/DefaultToolResult.vue.d.ts.map +1 -0
  72. package/dist/components/message/tool-results/SearchResults.vue.d.ts +4 -0
  73. package/dist/components/message/tool-results/SearchResults.vue.d.ts.map +1 -0
  74. package/dist/components/message/tool-results/WeatherCard.vue.d.ts +4 -0
  75. package/dist/components/message/tool-results/WeatherCard.vue.d.ts.map +1 -0
  76. package/dist/components/message/tool-results/index.d.ts +7 -0
  77. package/dist/components/message/tool-results/index.d.ts.map +1 -0
  78. package/dist/components/message/welcome-types.d.ts +28 -0
  79. package/dist/components/message/welcome-types.d.ts.map +1 -0
  80. package/dist/composables/useChat.d.ts +99 -44
  81. package/dist/composables/useChat.d.ts.map +1 -1
  82. package/dist/composables/useImageUpload.d.ts +55 -0
  83. package/dist/composables/useImageUpload.d.ts.map +1 -0
  84. package/dist/index.d.ts +25 -26
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +55871 -1252
  87. package/dist/style.css +1 -1
  88. package/dist/types/index.d.ts +113 -53
  89. package/dist/types/index.d.ts.map +1 -1
  90. package/dist/utils/fileIcon.d.ts +13 -0
  91. package/dist/utils/fileIcon.d.ts.map +1 -0
  92. package/package.json +12 -6
  93. package/src/adapter.ts +12 -70
  94. package/src/components/ChatPanel.vue +329 -110
  95. package/src/components/common/ConfirmDialog.vue +208 -0
  96. package/src/components/common/CopyButton.vue +71 -0
  97. package/src/components/common/IndexingSettings.vue +580 -0
  98. package/src/components/common/SettingsPanel.vue +293 -0
  99. package/src/components/common/Toast.vue +90 -0
  100. package/src/components/common/ToggleSwitch.vue +75 -0
  101. package/src/components/{chat/ui → header}/ChatHeader.vue +170 -93
  102. package/src/components/input/AtFilePicker.vue +657 -0
  103. package/src/components/input/ChatInput.vue +653 -0
  104. package/src/components/input/DropdownSelector.vue +322 -0
  105. package/src/components/input/ImagePreviewModal.vue +238 -0
  106. package/src/components/input/at-views/AtBranchView.vue +63 -0
  107. package/src/components/input/at-views/AtBrowserView.vue +63 -0
  108. package/src/components/input/at-views/AtChatsView.vue +63 -0
  109. package/src/components/input/at-views/AtDocsView.vue +63 -0
  110. package/src/components/input/at-views/AtFilesView.vue +255 -0
  111. package/src/components/input/at-views/AtTerminalsView.vue +63 -0
  112. package/src/components/message/ContentRenderer.vue +61 -0
  113. package/src/components/message/MessageBubble.vue +411 -0
  114. package/src/components/message/PartsRenderer.vue +101 -0
  115. package/src/components/message/ToolResultRenderer.vue +27 -0
  116. package/src/components/message/WelcomeMessage.vue +308 -0
  117. package/src/components/message/blocks/CodeBlock.vue +113 -0
  118. package/src/components/message/blocks/TextBlock.vue +21 -0
  119. package/src/components/message/blocks/index.ts +6 -0
  120. package/src/components/message/parts/CollapsibleCard.vue +135 -0
  121. package/src/components/message/parts/ErrorPart.vue +51 -0
  122. package/src/components/message/parts/ImagePart.vue +98 -0
  123. package/src/components/message/parts/SearchPart.vue +101 -0
  124. package/src/components/message/parts/TextPart.vue +28 -0
  125. package/src/components/message/parts/ThinkingPart.vue +54 -0
  126. package/src/components/message/parts/ToolCallPart.vue +460 -0
  127. package/src/components/message/parts/ToolResultPart.vue +78 -0
  128. package/src/components/message/parts/index.ts +13 -0
  129. package/src/components/message/tool-results/DefaultToolResult.vue +43 -0
  130. package/src/components/message/tool-results/SearchResults.vue +133 -0
  131. package/src/components/message/tool-results/WeatherCard.vue +139 -0
  132. package/src/components/message/tool-results/index.ts +7 -0
  133. package/src/components/message/welcome-types.ts +47 -0
  134. package/src/composables/useChat.ts +807 -155
  135. package/src/composables/useImageUpload.ts +228 -0
  136. package/src/index.ts +93 -46
  137. package/src/styles.css +47 -0
  138. package/src/types/index.ts +146 -98
  139. package/src/utils/fileIcon.ts +49 -0
  140. package/dist/components/ChatInput.vue.d.ts.map +0 -1
  141. package/dist/components/chat/SearchResultBlock.vue.d.ts.map +0 -1
  142. package/dist/components/chat/ThinkingBlock.vue.d.ts.map +0 -1
  143. package/dist/components/chat/ToolCallBlock.vue.d.ts.map +0 -1
  144. package/dist/components/chat/messages/ExecutionSteps.vue.d.ts.map +0 -1
  145. package/dist/components/chat/messages/MessageBubble.vue.d.ts +0 -28
  146. package/dist/components/chat/messages/MessageBubble.vue.d.ts.map +0 -1
  147. package/dist/components/chat/ui/ChatHeader.vue.d.ts.map +0 -1
  148. package/dist/components/chat/ui/WelcomeMessage.vue.d.ts +0 -7
  149. package/dist/components/chat/ui/WelcomeMessage.vue.d.ts.map +0 -1
  150. package/dist/preload/preload.d.ts +0 -6
  151. package/dist/preload/preload.d.ts.map +0 -1
  152. package/src/components/ChatInput.vue +0 -649
  153. package/src/components/chat/SearchResultBlock.vue +0 -155
  154. package/src/components/chat/ThinkingBlock.vue +0 -109
  155. package/src/components/chat/ToolCallBlock.vue +0 -213
  156. package/src/components/chat/messages/ExecutionSteps.vue +0 -281
  157. package/src/components/chat/messages/MessageBubble.vue +0 -272
  158. package/src/components/chat/ui/WelcomeMessage.vue +0 -135
  159. package/src/preload/preload.ts +0 -79
@@ -0,0 +1,133 @@
1
+ <template>
2
+ <div class="search-results-card">
3
+ <div class="search-header">
4
+ <Icon icon="lucide:search" width="16" />
5
+ <span>搜索结果</span>
6
+ <span class="search-count">{{ results.length }} 条</span>
7
+ </div>
8
+ <div class="search-list">
9
+ <a
10
+ v-for="(item, index) in results"
11
+ :key="index"
12
+ :href="item.url"
13
+ target="_blank"
14
+ rel="noopener noreferrer"
15
+ class="search-item"
16
+ @click.prevent="openExternal(item.url)"
17
+ >
18
+ <div class="item-title">{{ item.title }}</div>
19
+ <div v-if="item.snippet" class="item-snippet">{{ item.snippet }}</div>
20
+ <div class="item-url">{{ getDomain(item.url) }}</div>
21
+ </a>
22
+ </div>
23
+ </div>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import { computed } from 'vue'
28
+ import { Icon } from '@iconify/vue'
29
+ import type { ToolRendererProps, SearchResultItem } from '@huyooo/ai-chat-shared'
30
+
31
+ const props = defineProps<ToolRendererProps>()
32
+
33
+ const results = computed<SearchResultItem[]>(() => {
34
+ const result = props.toolResult
35
+ if (Array.isArray(result)) {
36
+ return result as SearchResultItem[]
37
+ }
38
+ if (typeof result === 'object' && result !== null && 'results' in result) {
39
+ return (result as { results: SearchResultItem[] }).results
40
+ }
41
+ return []
42
+ })
43
+
44
+ /** 获取域名 */
45
+ function getDomain(url: string): string {
46
+ try {
47
+ return new URL(url).hostname
48
+ } catch {
49
+ return url
50
+ }
51
+ }
52
+
53
+ /** 打开外部链接 */
54
+ function openExternal(url: string) {
55
+ const bridge = (window as { aiChatBridge?: { openExternal: (url: string) => Promise<void> } }).aiChatBridge
56
+ if (bridge?.openExternal) {
57
+ bridge.openExternal(url)
58
+ } else {
59
+ window.open(url, '_blank')
60
+ }
61
+ }
62
+ </script>
63
+
64
+ <style scoped>
65
+ .search-results-card {
66
+ background: var(--chat-muted, #2d2d2d);
67
+ border-radius: 8px;
68
+ overflow: hidden;
69
+ }
70
+
71
+ .search-header {
72
+ display: flex;
73
+ align-items: center;
74
+ gap: 8px;
75
+ padding: 10px 12px;
76
+ background: rgba(0, 0, 0, 0.2);
77
+ color: var(--chat-text-muted, #888);
78
+ font-size: 13px;
79
+ }
80
+
81
+ .search-count {
82
+ margin-left: auto;
83
+ font-size: 12px;
84
+ opacity: 0.7;
85
+ }
86
+
87
+ .search-list {
88
+ display: flex;
89
+ flex-direction: column;
90
+ }
91
+
92
+ .search-item {
93
+ display: block;
94
+ padding: 10px 12px;
95
+ text-decoration: none;
96
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
97
+ transition: background 0.15s;
98
+ }
99
+
100
+ .search-item:last-child {
101
+ border-bottom: none;
102
+ }
103
+
104
+ .search-item:hover {
105
+ background: rgba(255, 255, 255, 0.05);
106
+ }
107
+
108
+ .item-title {
109
+ font-size: 14px;
110
+ color: var(--chat-text, #ccc);
111
+ font-weight: 500;
112
+ margin-bottom: 4px;
113
+ overflow: hidden;
114
+ text-overflow: ellipsis;
115
+ white-space: nowrap;
116
+ }
117
+
118
+ .item-snippet {
119
+ font-size: 12px;
120
+ color: var(--chat-text-muted, #888);
121
+ line-height: 1.4;
122
+ margin-bottom: 4px;
123
+ display: -webkit-box;
124
+ -webkit-line-clamp: 2;
125
+ -webkit-box-orient: vertical;
126
+ overflow: hidden;
127
+ }
128
+
129
+ .item-url {
130
+ font-size: 11px;
131
+ color: var(--chat-text-muted, #666);
132
+ }
133
+ </style>
@@ -0,0 +1,139 @@
1
+ <template>
2
+ <div class="weather-card">
3
+ <div class="weather-header">
4
+ <Icon icon="lucide:cloud-sun" width="24" class="weather-icon" />
5
+ <div class="weather-location">{{ weather.city }}</div>
6
+ </div>
7
+ <div class="weather-main">
8
+ <div class="weather-temp">{{ weather.temperature }}°</div>
9
+ <div class="weather-condition">{{ weather.condition }}</div>
10
+ </div>
11
+ <div v-if="weather.humidity || weather.wind" class="weather-details">
12
+ <div v-if="weather.humidity" class="weather-detail">
13
+ <Icon icon="lucide:droplets" width="14" />
14
+ <span>{{ weather.humidity }}%</span>
15
+ </div>
16
+ <div v-if="weather.wind" class="weather-detail">
17
+ <Icon icon="lucide:wind" width="14" />
18
+ <span>{{ weather.wind }}</span>
19
+ </div>
20
+ </div>
21
+ <!-- 预报 -->
22
+ <div v-if="weather.forecast?.length" class="weather-forecast">
23
+ <div v-for="item in weather.forecast" :key="item.date" class="forecast-item">
24
+ <div class="forecast-date">{{ item.date }}</div>
25
+ <div class="forecast-temp">{{ item.low }}° / {{ item.high }}°</div>
26
+ <div class="forecast-condition">{{ item.condition }}</div>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </template>
31
+
32
+ <script setup lang="ts">
33
+ import { computed } from 'vue'
34
+ import { Icon } from '@iconify/vue'
35
+ import type { ToolRendererProps, WeatherData } from '@huyooo/ai-chat-shared'
36
+
37
+ const props = defineProps<ToolRendererProps>()
38
+
39
+ const weather = computed<WeatherData>(() => {
40
+ const result = props.toolResult
41
+ if (typeof result === 'object' && result !== null) {
42
+ return result as WeatherData
43
+ }
44
+ // 默认值
45
+ return {
46
+ city: '未知',
47
+ temperature: 0,
48
+ condition: '未知',
49
+ }
50
+ })
51
+ </script>
52
+
53
+ <style scoped>
54
+ .weather-card {
55
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
56
+ border-radius: 12px;
57
+ padding: 16px;
58
+ color: #fff;
59
+ min-width: 200px;
60
+ }
61
+
62
+ .weather-header {
63
+ display: flex;
64
+ align-items: center;
65
+ gap: 8px;
66
+ margin-bottom: 12px;
67
+ }
68
+
69
+ .weather-icon {
70
+ opacity: 0.9;
71
+ }
72
+
73
+ .weather-location {
74
+ font-size: 14px;
75
+ font-weight: 500;
76
+ }
77
+
78
+ .weather-main {
79
+ margin-bottom: 12px;
80
+ }
81
+
82
+ .weather-temp {
83
+ font-size: 48px;
84
+ font-weight: 300;
85
+ line-height: 1;
86
+ }
87
+
88
+ .weather-condition {
89
+ font-size: 14px;
90
+ opacity: 0.9;
91
+ margin-top: 4px;
92
+ }
93
+
94
+ .weather-details {
95
+ display: flex;
96
+ gap: 16px;
97
+ padding-top: 12px;
98
+ border-top: 1px solid rgba(255, 255, 255, 0.2);
99
+ }
100
+
101
+ .weather-detail {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: 4px;
105
+ font-size: 13px;
106
+ opacity: 0.9;
107
+ }
108
+
109
+ .weather-forecast {
110
+ margin-top: 12px;
111
+ padding-top: 12px;
112
+ border-top: 1px solid rgba(255, 255, 255, 0.2);
113
+ display: flex;
114
+ gap: 12px;
115
+ overflow-x: auto;
116
+ }
117
+
118
+ .forecast-item {
119
+ text-align: center;
120
+ min-width: 60px;
121
+ }
122
+
123
+ .forecast-date {
124
+ font-size: 12px;
125
+ opacity: 0.8;
126
+ margin-bottom: 4px;
127
+ }
128
+
129
+ .forecast-temp {
130
+ font-size: 13px;
131
+ font-weight: 500;
132
+ }
133
+
134
+ .forecast-condition {
135
+ font-size: 11px;
136
+ opacity: 0.8;
137
+ margin-top: 2px;
138
+ }
139
+ </style>
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 工具结果渲染组件导出
3
+ */
4
+
5
+ export { default as DefaultToolResult } from './DefaultToolResult.vue'
6
+ export { default as WeatherCard } from './WeatherCard.vue'
7
+ export { default as SearchResults } from './SearchResults.vue'
@@ -0,0 +1,47 @@
1
+ /** 功能项 */
2
+ export interface WelcomeFeature {
3
+ name: string;
4
+ icon: string;
5
+ }
6
+
7
+ /** 快捷任务 */
8
+ export interface WelcomeTask {
9
+ name: string;
10
+ desc: string;
11
+ prompt: string;
12
+ icon: string;
13
+ }
14
+
15
+ /** 欢迎页配置 */
16
+ export interface WelcomeConfig {
17
+ /** 标题 */
18
+ title: string;
19
+ /** 副标题 */
20
+ subtitle: string;
21
+ /** 图标 */
22
+ icon: string;
23
+ /** 功能列表 */
24
+ features: WelcomeFeature[];
25
+ /** 快捷任务 */
26
+ tasks: WelcomeTask[];
27
+ }
28
+
29
+ /** 默认配置 */
30
+ export const defaultWelcomeConfig: WelcomeConfig = {
31
+ title: 'AI 助手',
32
+ subtitle: '智能对话 · 文档分析 · 内容创作',
33
+ icon: 'lucide:sparkles',
34
+ features: [
35
+ { name: '上下文引用', icon: 'lucide:at-sign' },
36
+ { name: '图片分析', icon: 'lucide:image' },
37
+ { name: '深度思考', icon: 'lucide:sparkles' },
38
+ { name: '联网搜索', icon: 'lucide:globe' },
39
+ ],
40
+ tasks: [
41
+ { name: '总结内容', desc: '快速总结文档要点', prompt: '帮我总结一下这段内容的主要要点', icon: 'lucide:file-text' },
42
+ { name: '翻译文本', desc: '多语言翻译助手', prompt: '帮我翻译这段文字', icon: 'lucide:languages' },
43
+ { name: '写作助手', desc: '帮助撰写文章', prompt: '帮我写一篇关于以下主题的文章:', icon: 'lucide:pen-tool' },
44
+ { name: '问答对话', desc: '回答各种问题', prompt: '我想了解一下:', icon: 'lucide:message-circle' },
45
+ ],
46
+ };
47
+