gimc-ai-agent 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,299 @@
1
+ # gimc-ai-agent
2
+
3
+ AI 智能客服 Vue3 组件,基于 RAG 知识库的智能问答系统。
4
+
5
+ ## 安装
6
+
7
+ ### 1. 安装组件
8
+
9
+ ```bash
10
+ npm install gimc-ai-agent
11
+ ```
12
+
13
+ ### 2. 安装前置依赖
14
+
15
+ 本组件依赖 `element-plus`,请确保项目中已安装:
16
+
17
+ ```bash
18
+ npm install element-plus @element-plus/icons-vue
19
+ ```
20
+
21
+ ### 3. 配置 main.ts
22
+
23
+ 在项目入口文件中引入 Element Plus 和组件样式:
24
+
25
+ ```typescript
26
+ // main.ts
27
+ import { createApp } from 'vue'
28
+ import App from './App.vue'
29
+ import ElementPlus from 'element-plus'
30
+ import 'element-plus/dist/index.css'
31
+ import 'gimc-ai-agent/dist/style.css'
32
+
33
+ const app = createApp(App)
34
+ app.use(ElementPlus)
35
+ app.mount('#app')
36
+ ```
37
+
38
+ ### 4. 在组件中使用
39
+
40
+ ```vue
41
+ <template>
42
+ <!-- 建议配合登录状态控制显示 -->
43
+ <GimcAiAgent
44
+ v-if="isLoggedIn"
45
+ ref="agentRef"
46
+ :rag-knowledge-id="1"
47
+ :token="userToken"
48
+ title="智能客服"
49
+ @send="onSend"
50
+ @feedback="onFeedback"
51
+ @satisfaction="onSatisfaction"
52
+ />
53
+ </template>
54
+
55
+ <script setup lang="ts">
56
+ import { ref, computed } from 'vue'
57
+ import { GimcAiAgent } from 'gimc-ai-agent'
58
+ import type { FeedbackData } from 'gimc-ai-agent'
59
+
60
+ const agentRef = ref()
61
+
62
+ // 登录状态判断(根据实际业务修改)
63
+ const userToken = computed(() => localStorage.getItem('token') || '')
64
+ const isLoggedIn = computed(() => !!userToken.value)
65
+
66
+ // 事件监听
67
+ const onSend = (msg: string) => {
68
+ console.log('用户发送:', msg)
69
+ }
70
+
71
+ const onFeedback = (data: FeedbackData) => {
72
+ console.log('用户反馈:', data)
73
+ // 上报到后端
74
+ }
75
+
76
+ const onSatisfaction = (score: number) => {
77
+ console.log('满意度评分:', score)
78
+ }
79
+
80
+ // 主动调用方法
81
+ const openAgent = () => agentRef.value?.open()
82
+ const closeAgent = () => agentRef.value?.close()
83
+ const clearMessages = () => agentRef.value?.clearMessages()
84
+ </script>
85
+ ```
86
+
87
+ ## 完整安装步骤总结
88
+
89
+ ```bash
90
+ # 1. 安装组件和依赖
91
+ npm install gimc-ai-agent element-plus @element-plus/icons-vue
92
+
93
+ # 2. 在 main.ts 中配置
94
+ # - 引入 ElementPlus 并 use
95
+ # - 引入 'element-plus/dist/index.css'
96
+ # - 引入 'gimc-ai-agent/dist/style.css'
97
+
98
+ # 3. 在需要的页面中引入组件使用
99
+ # import { GimcAiAgent } from 'gimc-ai-agent'
100
+ ```
101
+
102
+ ## Props
103
+
104
+ | 属性 | 类型 | 默认值 | 必填 | 说明 |
105
+ |------|------|--------|------|------|
106
+ | `ragKnowledgeId` | `number` | - | ✅ | RAG 知识库 ID |
107
+ | `token` | `string` | - | - | 外部系统传入的认证 token(优先级高于 localStorage) |
108
+ | `title` | `string` | `'灵犀AI小助手'` | - | 标题 |
109
+ | `avatar` | `string` | 内置图标 | - | 头像 URL |
110
+ | `floatIcon` | `string` | 内置图标 | - | 悬浮按钮图标 URL |
111
+ | `position` | `{ right?: number; bottom?: number }` | `{ right: 8, bottom: 24 }` | - | 位置配置(单位:px) |
112
+ | `width` | `number` | `560` | - | 弹窗宽度(单位:px) |
113
+ | `welcomeText` | `string` | `'有任何问题,随时问我~'` | - | 欢迎语 |
114
+ | `idleTimeout` | `number` | `180000` | - | 空闲超时时间(ms) |
115
+ | `typingSpeed` | `number` | `30` | - | 打字机速度(ms) |
116
+ | `showSatisfaction` | `boolean` | `true` | - | 是否显示满意度评价 |
117
+ | `showFeedback` | `boolean` | `true` | - | 是否显示反馈功能 |
118
+
119
+ ## Events
120
+
121
+ | 事件 | 参数 | 说明 |
122
+ |------|------|------|
123
+ | `open` | - | 弹窗打开时触发 |
124
+ | `close` | - | 弹窗关闭时触发 |
125
+ | `send` | `message: string` | 用户发送消息时触发 |
126
+ | `feedback` | `FeedbackData` | 用户提交反馈时触发 |
127
+ | `satisfaction` | `score: number` | 用户评分时触发(1-5) |
128
+ | `article-click` | `Article` | 点击文章时触发 |
129
+ | `session-end` | - | 会话自动结束时触发 |
130
+
131
+ ## Slots
132
+
133
+ | 插槽名 | 说明 |
134
+ |--------|------|
135
+ | `float-button` | 自定义悬浮按钮 |
136
+ | `header` | 自定义头部区域 |
137
+ | `welcome` | 自定义欢迎区域 |
138
+ | `quick-actions` | 自定义快捷操作区域 |
139
+
140
+ ## Expose 方法
141
+
142
+ | 方法 | 说明 |
143
+ |------|------|
144
+ | `open()` | 打开弹窗 |
145
+ | `close()` | 关闭弹窗 |
146
+ | `clearMessages()` | 清空消息记录 |
147
+ | `sendMessage(content: string)` | 主动发送消息 |
148
+
149
+ ## 类型定义
150
+
151
+ ```typescript
152
+ interface Message {
153
+ role: 'user' | 'assistant'
154
+ content: string
155
+ timestamp?: string
156
+ showFeedback?: boolean
157
+ feedback?: 'resolved' | 'unresolved' | null
158
+ suggestions?: string[]
159
+ isTyping?: boolean
160
+ }
161
+
162
+ interface Article {
163
+ title: string
164
+ url: string
165
+ }
166
+
167
+ interface QuickAction {
168
+ label: string
169
+ icon?: string
170
+ onClick?: () => void
171
+ url?: string
172
+ }
173
+
174
+ interface FeedbackData {
175
+ messageId: string
176
+ type: string
177
+ resolved: boolean
178
+ detail?: string
179
+ }
180
+
181
+ interface Position {
182
+ right?: number
183
+ bottom?: number
184
+ }
185
+ ```
186
+
187
+ ## 登录状态控制
188
+
189
+ 组件本身不包含登录校验逻辑,建议在业务系统中通过 `v-if` 控制显示:
190
+
191
+ ```vue
192
+ <template>
193
+ <!-- 方式1:使用 Pinia store -->
194
+ <GimcAiAgent
195
+ v-if="userStore.isLoggedIn"
196
+ :rag-knowledge-id="1"
197
+ :token="userStore.token"
198
+ />
199
+
200
+ <!-- 方式2:使用 computed token 判断 -->
201
+ <GimcAiAgent
202
+ v-if="!!token"
203
+ :rag-knowledge-id="1"
204
+ :token="token"
205
+ />
206
+ </template>
207
+
208
+ <script setup>
209
+ import { computed } from 'vue'
210
+ import { useUserStore } from '@/stores/user'
211
+
212
+ const userStore = useUserStore()
213
+ const token = computed(() => localStorage.getItem('token'))
214
+ </script>
215
+ ```
216
+
217
+ ## Token 认证配置
218
+
219
+ 组件支持两种 token 传递方式:
220
+
221
+ ### 方式1:通过 prop 传递(推荐用于外部系统集成)
222
+
223
+ 当组件被外部系统调用时,可以通过 `token` prop 传递认证令牌:
224
+
225
+ ```vue
226
+ <template>
227
+ <GimcAiAgent
228
+ :rag-knowledge-id="1"
229
+ :token="externalToken"
230
+ />
231
+ </template>
232
+
233
+ <script setup>
234
+ import { ref } from 'vue'
235
+ import { GimcAiAgent } from 'gimc-ai-agent'
236
+
237
+ // 外部系统传入的 token
238
+ const externalToken = ref('your-external-token-here')
239
+ </script>
240
+ ```
241
+
242
+ ### 方式2:使用 localStorage(默认兼容)
243
+
244
+ 如果没有传递 `token` prop,组件会自动从 `localStorage` 中读取 `gimc-ai-agent-token`:
245
+
246
+ ```javascript
247
+ // 在登录成功后设置 token
248
+ localStorage.setItem('gimc-ai-agent-token', 'your-token-here')
249
+ ```
250
+
251
+ **优先级说明**:
252
+ - 如果同时存在 `token` prop 和 localStorage 中的 token,优先使用 `token` prop
253
+ - 这样可以确保外部系统集成时的灵活性
254
+
255
+ ## RAG 知识库配置
256
+
257
+ 本组件需要配合 RAG 知识库后端使用。确保:
258
+
259
+ 1. 后端已部署 RAG 知识库服务
260
+ 2. 创建知识库并获取 `ragKnowledgeId`
261
+ 3. 配置好后端 API 地址(通过环境变量)
262
+ 4. 确保用户已通过认证(提供有效的 token)
263
+
264
+ ## 自定义插槽示例
265
+
266
+ ```vue
267
+ <GimcAiAgent :rag-knowledge-id="1" :token="token">
268
+ <template #float-button>
269
+ <div class="custom-button">
270
+ <img src="/custom-icon.png" />
271
+ </div>
272
+ </template>
273
+
274
+ <template #welcome>
275
+ <div class="custom-welcome">
276
+ <h2>欢迎使用智能助手</h2>
277
+ <p>我可以帮你解答各种问题</p>
278
+ </div>
279
+ </template>
280
+ </GimcAiAgent>
281
+ ```
282
+
283
+ ## 后端接口要求
284
+
285
+ 组件会调用以下后端接口(基于配置的 API 地址):
286
+
287
+ - `POST /api/rag-knowledge/answer/stream` - 流式问答接口
288
+ - `GET /api/rag-knowledge/session/list` - 获取会话列表
289
+ - `GET /api/rag-knowledge/session/messages` - 获取历史消息
290
+ - `GET /api/rag-knowledge/questions/suggested` - 获取推荐问题
291
+ - `GET /api/rag-knowledge/questions/recommended` - 获取相关问题
292
+ - `POST /api/rag-knowledge/feedback` - 提交反馈
293
+ - `PUT /api/rag-knowledge/feedback` - 更新反馈
294
+ - `DELETE /api/rag-knowledge/feedback/{id}` - 删除反馈
295
+ - `POST /api/rag-knowledge/stop` - 停止生成
296
+
297
+ ## License
298
+
299
+ MIT
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,33 @@
1
+ import type { AxiosRequestConfig } from 'axios';
2
+ interface RequestConfig extends AxiosRequestConfig {
3
+ singleThread?: boolean;
4
+ }
5
+ /**
6
+ * 配置 API
7
+ */
8
+ export declare function setApiConfig(config: {
9
+ baseUrl?: string;
10
+ token?: string;
11
+ headers?: Record<string, string>;
12
+ }): void;
13
+ /**
14
+ * 获取当前配置
15
+ */
16
+ export declare function getApiConfig(): {
17
+ baseUrl: string;
18
+ token: string;
19
+ headers: Record<string, string>;
20
+ };
21
+ /**
22
+ * 通用请求方法
23
+ */
24
+ export declare function request<T = any>(config: RequestConfig): Promise<T>;
25
+ /**
26
+ * GET 请求
27
+ */
28
+ export declare function get<T = any>(url: string, config?: RequestConfig): Promise<T>;
29
+ /**
30
+ * POST 请求
31
+ */
32
+ export declare function post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T>;
33
+ export default request;
@@ -0,0 +1,3 @@
1
+ export declare const defaultFloatIcon: string;
2
+ export declare const defaultFloatIconHover: string;
3
+ export declare const defaultAvatarIcon: string;
@@ -0,0 +1,82 @@
1
+ import type { Article, FeedbackData } from '../types';
2
+ type __VLS_Props = {
3
+ /** RAG 知识库 ID(必填) */
4
+ ragKnowledgeId: number;
5
+ /** 标题 */
6
+ title?: string;
7
+ /** 头像 URL */
8
+ avatar?: string;
9
+ /** 悬浮按钮图标 URL */
10
+ floatIcon?: string;
11
+ /** 位置配置 */
12
+ position?: {
13
+ right?: number;
14
+ bottom?: number;
15
+ };
16
+ /** 弹窗宽度 */
17
+ width?: number;
18
+ /** 欢迎语 */
19
+ welcomeText?: string;
20
+ /** 空闲超时时间(ms) */
21
+ idleTimeout?: number;
22
+ /** 打字机速度(ms) */
23
+ typingSpeed?: number;
24
+ /** 是否显示满意度评价 */
25
+ showSatisfaction?: boolean;
26
+ /** 是否显示反馈功能 */
27
+ showFeedback?: boolean;
28
+ /** 外部系统传入的 token */
29
+ token?: string;
30
+ };
31
+ declare var __VLS_1: {}, __VLS_9: {}, __VLS_24: {}, __VLS_125: {};
32
+ type __VLS_Slots = {} & {
33
+ 'float-button'?: (props: typeof __VLS_1) => any;
34
+ } & {
35
+ header?: (props: typeof __VLS_9) => any;
36
+ } & {
37
+ welcome?: (props: typeof __VLS_24) => any;
38
+ } & {
39
+ 'quick-actions'?: (props: typeof __VLS_125) => any;
40
+ };
41
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
42
+ open: () => void;
43
+ close: () => void;
44
+ clearMessages: () => void;
45
+ sendMessage: (content: string) => Promise<void>;
46
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
47
+ open: () => any;
48
+ close: () => any;
49
+ send: (message: string) => any;
50
+ feedback: (data: FeedbackData) => any;
51
+ satisfaction: (score: number) => any;
52
+ "article-click": (article: Article) => any;
53
+ "session-end": () => any;
54
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
55
+ onOpen?: (() => any) | undefined;
56
+ onClose?: (() => any) | undefined;
57
+ onSend?: ((message: string) => any) | undefined;
58
+ onFeedback?: ((data: FeedbackData) => any) | undefined;
59
+ onSatisfaction?: ((score: number) => any) | undefined;
60
+ "onArticle-click"?: ((article: Article) => any) | undefined;
61
+ "onSession-end"?: (() => any) | undefined;
62
+ }>, {
63
+ title: string;
64
+ position: {
65
+ right?: number;
66
+ bottom?: number;
67
+ };
68
+ width: number;
69
+ welcomeText: string;
70
+ idleTimeout: number;
71
+ typingSpeed: number;
72
+ showSatisfaction: boolean;
73
+ showFeedback: boolean;
74
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
75
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
76
+ declare const _default: typeof __VLS_export;
77
+ export default _default;
78
+ type __VLS_WithSlots<T, S> = T & {
79
+ new (): {
80
+ $slots: S;
81
+ };
82
+ };