@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,98 @@
1
+ <template>
2
+ <div class="image-part">
3
+ <img
4
+ v-if="!error"
5
+ :src="url"
6
+ :alt="alt || '图片'"
7
+ class="image-content"
8
+ :style="{ display: loading ? 'none' : 'block' }"
9
+ @click="openPreview"
10
+ @load="onLoad"
11
+ @error="onError"
12
+ />
13
+ <div v-if="loading && !error" class="image-loading">
14
+ <Icon icon="lucide:loader-2" width="24" class="spinning" />
15
+ </div>
16
+ <div v-if="error" class="image-error">
17
+ <Icon icon="lucide:image-off" width="24" />
18
+ <span>图片加载失败</span>
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script setup lang="ts">
24
+ import { ref } from 'vue'
25
+ import { Icon } from '@iconify/vue'
26
+
27
+ const props = defineProps<{
28
+ url: string
29
+ alt?: string
30
+ }>()
31
+
32
+ const loading = ref(true)
33
+ const error = ref(false)
34
+
35
+ function onLoad() {
36
+ loading.value = false
37
+ error.value = false
38
+ }
39
+
40
+ function onError() {
41
+ loading.value = false
42
+ error.value = true
43
+ }
44
+
45
+ function openPreview() {
46
+ // 在新窗口打开图片
47
+ window.open(props.url, '_blank')
48
+ }
49
+ </script>
50
+
51
+ <style scoped>
52
+ .image-part {
53
+ position: relative;
54
+ margin: 8px 0;
55
+ max-width: 100%;
56
+ display: inline-block;
57
+ }
58
+
59
+ .image-content {
60
+ max-width: 100%;
61
+ max-height: 400px;
62
+ border-radius: 8px;
63
+ cursor: pointer;
64
+ transition: opacity 0.2s;
65
+ }
66
+
67
+ .image-content:hover {
68
+ opacity: 0.9;
69
+ }
70
+
71
+ .image-loading,
72
+ .image-error {
73
+ display: flex;
74
+ flex-direction: column;
75
+ align-items: center;
76
+ justify-content: center;
77
+ gap: 8px;
78
+ padding: 24px;
79
+ background: var(--chat-muted, #2a2a2a);
80
+ border-radius: 8px;
81
+ color: var(--chat-text-muted, #888);
82
+ min-width: 200px;
83
+ min-height: 150px;
84
+ }
85
+
86
+ .spinning {
87
+ animation: spin 1s linear infinite;
88
+ }
89
+
90
+ @keyframes spin {
91
+ from { transform: rotate(0deg); }
92
+ to { transform: rotate(360deg); }
93
+ }
94
+
95
+ .image-error span {
96
+ font-size: 13px;
97
+ }
98
+ </style>
@@ -0,0 +1,101 @@
1
+ <template>
2
+ <CollapsibleCard
3
+ v-model="expanded"
4
+ icon="lucide:search"
5
+ icon-color="var(--chat-accent, #3b82f6)"
6
+ :title="status === 'running' ? '搜索中...' : `搜索完成 (${results?.length || 0} 条结果)`"
7
+ :spinning="status === 'running'"
8
+ >
9
+ <div v-if="results?.length" class="search-results">
10
+ <a
11
+ v-for="(item, i) in results"
12
+ :key="i"
13
+ :href="item.url"
14
+ target="_blank"
15
+ class="search-item"
16
+ >
17
+ <div class="search-item-title">{{ item.title }}</div>
18
+ <div class="search-item-snippet">{{ item.snippet }}</div>
19
+ <div class="search-item-url">{{ item.url }}</div>
20
+ </a>
21
+ </div>
22
+ </CollapsibleCard>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import { ref, watch } from 'vue'
27
+ import CollapsibleCard from './CollapsibleCard.vue'
28
+ import type { SearchResult, StepsExpandedType } from '../../../types'
29
+
30
+ const props = withDefaults(defineProps<{
31
+ query?: string
32
+ results?: SearchResult[]
33
+ status: 'running' | 'done'
34
+ expandedType?: StepsExpandedType
35
+ }>(), {
36
+ expandedType: 'auto'
37
+ })
38
+
39
+ // 根据模式计算初始状态
40
+ function getInitialExpanded(): boolean {
41
+ if (props.expandedType === 'open') return true
42
+ if (props.expandedType === 'close') return false
43
+ return props.status === 'running'
44
+ }
45
+
46
+ const expanded = ref(getInitialExpanded())
47
+
48
+ // auto 模式下:状态变化时自动折叠/展开
49
+ watch(() => props.status, (newStatus) => {
50
+ if (props.expandedType === 'auto') {
51
+ expanded.value = newStatus === 'running'
52
+ }
53
+ })
54
+ </script>
55
+
56
+ <style scoped>
57
+ .search-results {
58
+ display: flex;
59
+ flex-direction: column;
60
+ gap: 8px;
61
+ }
62
+
63
+ .search-item {
64
+ display: block;
65
+ padding: 8px;
66
+ border-radius: 6px;
67
+ background: var(--chat-bg, #1e1e1e);
68
+ text-decoration: none;
69
+ transition: background 0.15s;
70
+ }
71
+
72
+ .search-item:hover {
73
+ background: var(--chat-hover, #333);
74
+ }
75
+
76
+ .search-item-title {
77
+ font-size: 13px;
78
+ font-weight: 500;
79
+ color: var(--chat-accent, #3b82f6);
80
+ margin-bottom: 4px;
81
+ }
82
+
83
+ .search-item-snippet {
84
+ font-size: 12px;
85
+ color: var(--chat-text-muted, #888);
86
+ line-height: 1.4;
87
+ margin-bottom: 4px;
88
+ display: -webkit-box;
89
+ -webkit-line-clamp: 2;
90
+ -webkit-box-orient: vertical;
91
+ overflow: hidden;
92
+ }
93
+
94
+ .search-item-url {
95
+ font-size: 11px;
96
+ color: var(--chat-text-muted, #666);
97
+ overflow: hidden;
98
+ text-overflow: ellipsis;
99
+ white-space: nowrap;
100
+ }
101
+ </style>
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <div
3
+ v-if="text"
4
+ class="text-part markdown-content"
5
+ v-html="html"
6
+ />
7
+ </template>
8
+
9
+ <script setup lang="ts">
10
+ import { computed } from 'vue'
11
+ import { renderMarkdown } from '@huyooo/ai-chat-shared'
12
+
13
+ const props = defineProps<{
14
+ text: string
15
+ }>()
16
+
17
+ const html = computed(() => renderMarkdown(props.text))
18
+ </script>
19
+
20
+ <style scoped>
21
+ .text-part {
22
+ font-size: 14px;
23
+ line-height: 1.7;
24
+ color: var(--chat-text, #ccc);
25
+ word-break: break-word;
26
+ overflow-wrap: break-word;
27
+ }
28
+ </style>
@@ -0,0 +1,54 @@
1
+ <template>
2
+ <CollapsibleCard
3
+ v-model="expanded"
4
+ icon="lucide:lightbulb"
5
+ icon-color="var(--chat-accent, #f59e0b)"
6
+ :title="status === 'running' ? '思考中...' : '思考完成'"
7
+ :subtitle="duration && status === 'done' ? `(${duration}s)` : undefined"
8
+ >
9
+ <div class="thinking-content">{{ text }}</div>
10
+ </CollapsibleCard>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ import { ref, watch } from 'vue'
15
+ import CollapsibleCard from './CollapsibleCard.vue'
16
+ import type { StepsExpandedType } from '../../../types'
17
+
18
+ const props = withDefaults(defineProps<{
19
+ text: string
20
+ status: 'running' | 'done'
21
+ duration?: number
22
+ expandedType?: StepsExpandedType
23
+ }>(), {
24
+ expandedType: 'auto'
25
+ })
26
+
27
+ // 根据模式计算初始状态
28
+ function getInitialExpanded(): boolean {
29
+ if (props.expandedType === 'open') return true
30
+ if (props.expandedType === 'close') return false
31
+ return props.status === 'running'
32
+ }
33
+
34
+ const expanded = ref(getInitialExpanded())
35
+
36
+ // auto 模式下:状态变化时自动折叠/展开
37
+ watch(() => props.status, (newStatus) => {
38
+ if (props.expandedType === 'auto') {
39
+ expanded.value = newStatus === 'running'
40
+ }
41
+ })
42
+ </script>
43
+
44
+ <style scoped>
45
+ .thinking-content {
46
+ font-size: 13px;
47
+ line-height: 1.5;
48
+ color: var(--chat-text-muted, #999);
49
+ white-space: pre-wrap;
50
+ word-break: break-word;
51
+ overflow-wrap: break-word;
52
+ margin: 0;
53
+ }
54
+ </style>