@huyooo/ai-chat-frontend-vue 0.1.3 → 0.1.6
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/dist/adapter.d.ts +3 -35
- package/dist/adapter.d.ts.map +1 -1
- package/dist/components/ChatInput.vue.d.ts +2 -2
- package/dist/composables/useChat.d.ts +6 -2
- package/dist/composables/useChat.d.ts.map +1 -1
- package/dist/index.d.ts +16 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +87 -67
- package/dist/types/index.d.ts +9 -40
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/adapter.ts +40 -70
- package/src/composables/useChat.ts +6 -7
- package/src/index.ts +27 -17
- package/src/types/index.ts +21 -43
package/dist/adapter.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export type ChatProgressType = 'thinking' | 'search_start' | 'search_result' | 'tool_call' | 'tool_result' | 'text_delta' | 'text' | 'done' | 'error';
|
|
1
|
+
import { ChatAdapter as ChatAdapterType, ChatMode, ThinkingMode } from '@huyooo/ai-chat-bridge-electron/renderer';
|
|
2
|
+
export type ChatAdapter = ChatAdapterType;
|
|
4
3
|
/** 思考数据 */
|
|
5
4
|
export interface ThinkingData {
|
|
6
5
|
content: string;
|
|
@@ -21,13 +20,6 @@ export interface ImageData {
|
|
|
21
20
|
base64: string;
|
|
22
21
|
mimeType: string;
|
|
23
22
|
}
|
|
24
|
-
/** 聊天进度事件 */
|
|
25
|
-
export interface ChatProgress {
|
|
26
|
-
type: ChatProgressType;
|
|
27
|
-
data: string | ThinkingData | ToolCallData | ToolResultData | {
|
|
28
|
-
results: SearchResult[];
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
23
|
/** 发送消息选项 */
|
|
32
24
|
export interface SendMessageOptions {
|
|
33
25
|
mode: ChatMode;
|
|
@@ -56,32 +48,8 @@ export interface SaveMessageOptions {
|
|
|
56
48
|
toolCalls?: string;
|
|
57
49
|
searchResults?: string;
|
|
58
50
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Chat Adapter 接口
|
|
61
|
-
* 所有后端通信实现都需要实现此接口
|
|
62
|
-
*/
|
|
63
|
-
export interface ChatAdapter {
|
|
64
|
-
/** 获取所有会话 */
|
|
65
|
-
getSessions(): Promise<SessionRecord[]>;
|
|
66
|
-
/** 创建新会话 */
|
|
67
|
-
createSession(options: CreateSessionOptions): Promise<SessionRecord>;
|
|
68
|
-
/** 更新会话 */
|
|
69
|
-
updateSession(sessionId: string, options: UpdateSessionOptions): Promise<void>;
|
|
70
|
-
/** 删除会话 */
|
|
71
|
-
deleteSession(sessionId: string): Promise<void>;
|
|
72
|
-
/** 获取会话消息 */
|
|
73
|
-
getMessages(sessionId: string): Promise<MessageRecord[]>;
|
|
74
|
-
/** 保存消息 */
|
|
75
|
-
saveMessage(options: SaveMessageOptions): Promise<MessageRecord>;
|
|
76
|
-
/** 发送消息并获取流式响应 */
|
|
77
|
-
sendMessage(content: string, options: SendMessageOptions, images?: string[]): AsyncGenerator<ChatProgress, void, unknown>;
|
|
78
|
-
/** 取消当前请求 */
|
|
79
|
-
cancel(): void;
|
|
80
|
-
/** 设置工作目录 */
|
|
81
|
-
setWorkingDir?(dir: string): void;
|
|
82
|
-
}
|
|
83
51
|
/**
|
|
84
52
|
* 创建空 Adapter(用于测试或无后端场景)
|
|
85
53
|
*/
|
|
86
|
-
export declare function createNullAdapter():
|
|
54
|
+
export declare function createNullAdapter(): ChatAdapterType;
|
|
87
55
|
//# sourceMappingURL=adapter.d.ts.map
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,IAAI,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAA;AAGtH,MAAM,MAAM,WAAW,GAAG,eAAe,CAAA;AAGzC,WAAW;AACX,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,aAAa;AACb,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AAED,aAAa;AACb,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,WAAW;AACX,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,aAAa;AACb,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,OAAO,CAAA;IACxB,YAAY,EAAE,YAAY,CAAA;CAC3B;AAED,aAAa;AACb,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,aAAa;AACb,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB;AAED,aAAa;AACb,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,eAAe,CA2DnD"}
|
|
@@ -22,7 +22,7 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {
|
|
|
22
22
|
"remove-image": (index: number) => any;
|
|
23
23
|
"upload-image": () => any;
|
|
24
24
|
"at-context": () => any;
|
|
25
|
-
"update:mode": (mode: ChatMode) => any;
|
|
25
|
+
"update:mode": (mode: import('@huyooo/ai-chat-bridge-electron/renderer').ChatMode) => any;
|
|
26
26
|
"update:model": (model: string) => any;
|
|
27
27
|
"update:webSearch": (enabled: boolean) => any;
|
|
28
28
|
"update:thinking": (enabled: boolean) => any;
|
|
@@ -32,7 +32,7 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {
|
|
|
32
32
|
"onRemove-image"?: ((index: number) => any) | undefined;
|
|
33
33
|
"onUpload-image"?: (() => any) | undefined;
|
|
34
34
|
"onAt-context"?: (() => any) | undefined;
|
|
35
|
-
"onUpdate:mode"?: ((mode: ChatMode) => any) | undefined;
|
|
35
|
+
"onUpdate:mode"?: ((mode: import('@huyooo/ai-chat-bridge-electron/renderer').ChatMode) => any) | undefined;
|
|
36
36
|
"onUpdate:model"?: ((model: string) => any) | undefined;
|
|
37
37
|
"onUpdate:webSearch"?: ((enabled: boolean) => any) | undefined;
|
|
38
38
|
"onUpdate:thinking"?: ((enabled: boolean) => any) | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ChatAdapter } from '
|
|
2
|
-
import { ChatMessage
|
|
1
|
+
import { ChatAdapter, ChatMode, SessionRecord } from '@huyooo/ai-chat-bridge-electron/renderer';
|
|
2
|
+
import { ChatMessage } from '../types';
|
|
3
3
|
export interface UseChatOptions {
|
|
4
4
|
/** Adapter 实例 */
|
|
5
5
|
adapter?: ChatAdapter;
|
|
@@ -14,6 +14,8 @@ export interface UseChatOptions {
|
|
|
14
14
|
export declare function useChat(options?: UseChatOptions): {
|
|
15
15
|
sessions: import('vue').Ref<{
|
|
16
16
|
id: string;
|
|
17
|
+
appId: string | null;
|
|
18
|
+
userId: string | null;
|
|
17
19
|
title: string;
|
|
18
20
|
model: string;
|
|
19
21
|
mode: ChatMode;
|
|
@@ -21,6 +23,8 @@ export declare function useChat(options?: UseChatOptions): {
|
|
|
21
23
|
updatedAt: Date;
|
|
22
24
|
}[], SessionRecord[] | {
|
|
23
25
|
id: string;
|
|
26
|
+
appId: string | null;
|
|
27
|
+
userId: string | null;
|
|
24
28
|
title: string;
|
|
25
29
|
model: string;
|
|
26
30
|
mode: ChatMode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/composables/useChat.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/composables/useChat.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACV,WAAW,EAEX,QAAQ,EACR,aAAa,EAEd,MAAM,0CAA0C,CAAA;AAEjD,OAAO,KAAK,EAAE,WAAW,EAA0B,MAAM,UAAU,CAAA;AAsBnE,MAAM,WAAW,cAAc;IAC7B,iBAAiB;IACjB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,WAAW;IACX,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW;IACX,WAAW,CAAC,EAAE,QAAQ,CAAA;CACvB;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAuCV,MAAM;;+BAsCN,MAAM;;wBAgGb,MAAM,WAAW,MAAM,EAAE;;6BAmIpB,MAAM;sCAoBH,MAAM;qBAwC5B,QAAQ;sBACP,MAAM;0BACF,OAAO;yBACR,OAAO;+BAlCI,MAAM;EAuCzC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @huyooo/ai-chat-frontend
|
|
2
|
+
* @huyooo/ai-chat-frontend-vue
|
|
3
3
|
*
|
|
4
|
-
* AI Chat 前端组件库
|
|
4
|
+
* AI Chat 前端组件库 - Vue 版本
|
|
5
5
|
*
|
|
6
6
|
* 使用 adapter 模式,与后端通信方式解耦
|
|
7
7
|
*/
|
|
8
|
-
export type { ChatAdapter, ChatProgress, ChatProgressType,
|
|
8
|
+
export type { ChatAdapter, ChatProgress, ChatProgressType, ChatOptions, ChatMode, ModelConfig, ModelProvider, ThinkingMode, SessionRecord, MessageRecord, } from '@huyooo/ai-chat-bridge-electron/renderer';
|
|
9
|
+
export type { ThinkingData, ToolCallData, ToolResultData, ImageData, SendMessageOptions, CreateSessionOptions, UpdateSessionOptions, SaveMessageOptions, } from './adapter';
|
|
9
10
|
export { createNullAdapter } from './adapter';
|
|
10
11
|
export { useChat } from './composables/useChat';
|
|
11
12
|
export type { UseChatOptions } from './composables/useChat';
|
|
@@ -18,20 +19,24 @@ export { default as ExecutionSteps } from './components/chat/messages/ExecutionS
|
|
|
18
19
|
export { default as ThinkingBlock } from './components/chat/ThinkingBlock.vue';
|
|
19
20
|
export { default as ToolCallBlock } from './components/chat/ToolCallBlock.vue';
|
|
20
21
|
export { default as SearchResultBlock } from './components/chat/SearchResultBlock.vue';
|
|
21
|
-
export type { ChatMessage,
|
|
22
|
+
export type { ChatMessage, SearchResult, ToolCall, ChatSession, MediaOperation, AiModel, DiffStat, } from './types';
|
|
22
23
|
export { DEFAULT_MODELS, FileType } from './types';
|
|
23
24
|
/**
|
|
24
25
|
* 使用说明:
|
|
25
26
|
*
|
|
26
|
-
* 1.
|
|
27
|
-
* import
|
|
28
|
-
* const adapter = createElectronAdapter();
|
|
27
|
+
* 1. 导入样式:
|
|
28
|
+
* import '@huyooo/ai-chat-frontend-vue/style.css'
|
|
29
29
|
*
|
|
30
|
-
* 2.
|
|
30
|
+
* 2. 创建 adapter 和使用组件:
|
|
31
|
+
* import { ChatPanel } from '@huyooo/ai-chat-frontend-vue'
|
|
32
|
+
* import { createElectronAdapter } from '@huyooo/ai-chat-bridge-electron/renderer'
|
|
33
|
+
* const adapter = createElectronAdapter()
|
|
31
34
|
* <ChatPanel :adapter="adapter" />
|
|
32
35
|
*
|
|
33
|
-
* 3. 或使用 useChat composable:
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
+
* 3. 或使用 useChat composable 自定义 UI:
|
|
37
|
+
* import { useChat } from '@huyooo/ai-chat-frontend-vue'
|
|
38
|
+
* import { createElectronAdapter } from '@huyooo/ai-chat-bridge-electron/renderer'
|
|
39
|
+
* const adapter = createElectronAdapter()
|
|
40
|
+
* const chat = useChat({ adapter })
|
|
36
41
|
*/
|
|
37
42
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,YAAY,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,QAAQ,EACR,WAAW,EACX,aAAa,EACb,YAAY,EACZ,aAAa,EACb,aAAa,GACd,MAAM,0CAA0C,CAAA;AAGjD,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,SAAS,EACT,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAGlE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAGlE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAG5E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAGpF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,8CAA8C,CAAC;AACxF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAG1F,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAGvF,YAAY,EACV,WAAW,EACX,YAAY,EACZ,QAAQ,EAER,WAAW,EACX,cAAc,EACd,OAAO,EACP,QAAQ,GACT,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnD;;;;;;;;;;;;;;;;;GAiBG"}
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
|
-
import { ref as M, shallowRef as Ae, defineComponent as K, computed as H, onMounted as oe, onUnmounted as fe, createElementBlock as i, openBlock as n, createElementVNode as t, Fragment as B, renderList as q, normalizeClass as E, toDisplayString as z, withModifiers as X, createVNode as S, unref as l, createCommentVNode as p, markRaw as W, createBlock as k, resolveDynamicComponent as te, watch as ae, withDirectives as Ne, vModelText as Be, reactive as
|
|
2
|
-
import { X as ne, Plus as de, Clock as He, Trash2 as ve, MoreHorizontal as We, XCircle as qe, Download as Ve, Copy as ke, MessageSquare as Pe, Settings as
|
|
1
|
+
import { ref as M, shallowRef as Ae, defineComponent as K, computed as H, onMounted as oe, onUnmounted as fe, createElementBlock as i, openBlock as n, createElementVNode as t, Fragment as B, renderList as q, normalizeClass as E, toDisplayString as z, withModifiers as X, createVNode as S, unref as l, createCommentVNode as p, markRaw as W, createBlock as k, resolveDynamicComponent as te, watch as ae, withDirectives as Ne, vModelText as Be, reactive as Oe, toRef as Le, provide as Ue, nextTick as _e } from "vue";
|
|
2
|
+
import { X as ne, Plus as de, Clock as He, Trash2 as ve, MoreHorizontal as We, XCircle as qe, Download as Ve, Copy as ke, MessageSquare as Pe, Settings as Fe, Code as Je, FileText as pe, Search as ye, MessageCircle as be, Sparkles as Ce, Zap as he, ChevronDown as j, Check as se, AtSign as Ge, Globe as ie, ImageIcon as Ke, Square as Qe, ArrowUp as Xe, Mic as je, Loader2 as ee, Lightbulb as $e, RefreshCw as Ze, Video as Ye, Image as ge, Terminal as et } from "lucide-vue-next";
|
|
3
3
|
function tt() {
|
|
4
4
|
return {
|
|
5
|
+
async getModels() {
|
|
6
|
+
return [];
|
|
7
|
+
},
|
|
5
8
|
async getSessions() {
|
|
6
9
|
return [];
|
|
7
10
|
},
|
|
11
|
+
async getSession() {
|
|
12
|
+
return null;
|
|
13
|
+
},
|
|
8
14
|
async createSession(e) {
|
|
9
15
|
return {
|
|
10
16
|
id: Date.now().toString(),
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
appId: null,
|
|
18
|
+
userId: null,
|
|
19
|
+
title: (e == null ? void 0 : e.title) || "新对话",
|
|
20
|
+
model: (e == null ? void 0 : e.model) || "",
|
|
21
|
+
mode: (e == null ? void 0 : e.mode) || "agent",
|
|
14
22
|
createdAt: /* @__PURE__ */ new Date(),
|
|
15
23
|
updatedAt: /* @__PURE__ */ new Date()
|
|
16
24
|
};
|
|
17
25
|
},
|
|
18
26
|
async updateSession() {
|
|
27
|
+
return null;
|
|
19
28
|
},
|
|
20
29
|
async deleteSession() {
|
|
21
30
|
},
|
|
@@ -28,12 +37,23 @@ function tt() {
|
|
|
28
37
|
sessionId: e.sessionId,
|
|
29
38
|
role: e.role,
|
|
30
39
|
content: e.content,
|
|
31
|
-
thinking: e.thinking,
|
|
32
|
-
toolCalls: e.toolCalls,
|
|
33
|
-
searchResults: e.searchResults,
|
|
40
|
+
thinking: e.thinking || null,
|
|
41
|
+
toolCalls: e.toolCalls || null,
|
|
42
|
+
searchResults: e.searchResults || null,
|
|
43
|
+
operationIds: null,
|
|
34
44
|
timestamp: /* @__PURE__ */ new Date()
|
|
35
45
|
};
|
|
36
46
|
},
|
|
47
|
+
async deleteMessagesAfter() {
|
|
48
|
+
},
|
|
49
|
+
async getOperations() {
|
|
50
|
+
return [];
|
|
51
|
+
},
|
|
52
|
+
async getTrashItems() {
|
|
53
|
+
return [];
|
|
54
|
+
},
|
|
55
|
+
async restoreFromTrash() {
|
|
56
|
+
},
|
|
37
57
|
async *sendMessage() {
|
|
38
58
|
yield { type: "text", data: "无可用的 Adapter" }, yield { type: "done", data: "" };
|
|
39
59
|
},
|
|
@@ -66,12 +86,12 @@ function st(e = {}) {
|
|
|
66
86
|
async function P() {
|
|
67
87
|
try {
|
|
68
88
|
const d = await h.getSessions();
|
|
69
|
-
c.value = d, d.length > 0 && !f.value && await
|
|
89
|
+
c.value = d, d.length > 0 && !f.value && await L(d[0].id);
|
|
70
90
|
} catch (d) {
|
|
71
91
|
console.error("加载会话失败:", d);
|
|
72
92
|
}
|
|
73
93
|
}
|
|
74
|
-
async function
|
|
94
|
+
async function L(d) {
|
|
75
95
|
if (f.value !== d) {
|
|
76
96
|
f.value = d;
|
|
77
97
|
try {
|
|
@@ -84,7 +104,7 @@ function st(e = {}) {
|
|
|
84
104
|
}
|
|
85
105
|
}
|
|
86
106
|
}
|
|
87
|
-
async function
|
|
107
|
+
async function F() {
|
|
88
108
|
try {
|
|
89
109
|
const d = await h.createSession({
|
|
90
110
|
title: "新对话",
|
|
@@ -98,7 +118,7 @@ function st(e = {}) {
|
|
|
98
118
|
}
|
|
99
119
|
async function I(d) {
|
|
100
120
|
try {
|
|
101
|
-
await h.deleteSession(d), c.value = c.value.filter((w) => w.id !== d), f.value === d && (c.value.length > 0 ? await
|
|
121
|
+
await h.deleteSession(d), c.value = c.value.filter((w) => w.id !== d), f.value === d && (c.value.length > 0 ? await L(c.value[0].id) : (f.value = null, s.value = []));
|
|
102
122
|
} catch (w) {
|
|
103
123
|
console.error("删除会话失败:", w);
|
|
104
124
|
}
|
|
@@ -106,7 +126,7 @@ function st(e = {}) {
|
|
|
106
126
|
async function T() {
|
|
107
127
|
f.value && await I(f.value);
|
|
108
128
|
}
|
|
109
|
-
function
|
|
129
|
+
function J(d, w) {
|
|
110
130
|
const r = s.value[d];
|
|
111
131
|
if (r) {
|
|
112
132
|
switch (w.type) {
|
|
@@ -213,10 +233,10 @@ function st(e = {}) {
|
|
|
213
233
|
},
|
|
214
234
|
w
|
|
215
235
|
))
|
|
216
|
-
if ((u = N.value) != null && u.signal.aborted || (
|
|
236
|
+
if ((u = N.value) != null && u.signal.aborted || (J(U, o), o.type === "done" || o.type === "error"))
|
|
217
237
|
break;
|
|
218
238
|
} catch (o) {
|
|
219
|
-
console.error("发送消息失败:", o),
|
|
239
|
+
console.error("发送消息失败:", o), J(U, {
|
|
220
240
|
type: "error",
|
|
221
241
|
data: o instanceof Error ? o.message : String(o)
|
|
222
242
|
});
|
|
@@ -274,8 +294,8 @@ function st(e = {}) {
|
|
|
274
294
|
thinking: x,
|
|
275
295
|
// 会话方法
|
|
276
296
|
loadSessions: P,
|
|
277
|
-
switchSession:
|
|
278
|
-
createNewSession:
|
|
297
|
+
switchSession: L,
|
|
298
|
+
createNewSession: F,
|
|
279
299
|
deleteSession: I,
|
|
280
300
|
deleteCurrentSession: T,
|
|
281
301
|
// 消息方法
|
|
@@ -385,10 +405,10 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
385
405
|
function P() {
|
|
386
406
|
s.value = !s.value, m.value = !1;
|
|
387
407
|
}
|
|
388
|
-
function
|
|
408
|
+
function L() {
|
|
389
409
|
m.value = !m.value, s.value = !1;
|
|
390
410
|
}
|
|
391
|
-
function
|
|
411
|
+
function F() {
|
|
392
412
|
a("new-session"), s.value = !1;
|
|
393
413
|
}
|
|
394
414
|
function I(C) {
|
|
@@ -420,14 +440,14 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
420
440
|
break;
|
|
421
441
|
}
|
|
422
442
|
}
|
|
423
|
-
function
|
|
443
|
+
function J(C) {
|
|
424
444
|
const v = C.target;
|
|
425
445
|
D.value && !D.value.contains(v) && (s.value = !1), y.value && !y.value.contains(v) && (m.value = !1);
|
|
426
446
|
}
|
|
427
447
|
return oe(() => {
|
|
428
|
-
document.addEventListener("click",
|
|
448
|
+
document.addEventListener("click", J);
|
|
429
449
|
}), fe(() => {
|
|
430
|
-
document.removeEventListener("click",
|
|
450
|
+
document.removeEventListener("click", J);
|
|
431
451
|
}), (C, v) => (n(), i("div", at, [
|
|
432
452
|
t("div", ot, [
|
|
433
453
|
f.value.length === 0 ? (n(), i("span", it, " New Chat ")) : (n(!0), i(B, { key: 1 }, q(f.value, (b) => (n(), i("div", {
|
|
@@ -472,7 +492,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
472
492
|
t("button", {
|
|
473
493
|
class: "icon-btn small",
|
|
474
494
|
title: "新建对话",
|
|
475
|
-
onClick:
|
|
495
|
+
onClick: F
|
|
476
496
|
}, [
|
|
477
497
|
S(l(de), { size: 12 })
|
|
478
498
|
])
|
|
@@ -505,7 +525,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
505
525
|
t("button", {
|
|
506
526
|
class: E(["icon-btn", { active: m.value }]),
|
|
507
527
|
title: "更多选项",
|
|
508
|
-
onClick: X(
|
|
528
|
+
onClick: X(L, ["stop"])
|
|
509
529
|
}, [
|
|
510
530
|
S(l(We), { size: 14 })
|
|
511
531
|
], 2),
|
|
@@ -551,7 +571,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
551
571
|
class: "menu-item",
|
|
552
572
|
onClick: v[6] || (v[6] = (b) => T("settings"))
|
|
553
573
|
}, [
|
|
554
|
-
S(l(
|
|
574
|
+
S(l(Fe), { size: 14 }),
|
|
555
575
|
v[14] || (v[14] = t("span", null, "Agent 设置", -1))
|
|
556
576
|
])
|
|
557
577
|
])) : p("", !0)
|
|
@@ -581,7 +601,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
581
601
|
id: "code",
|
|
582
602
|
label: "写代码",
|
|
583
603
|
prompt: "帮我写一段代码",
|
|
584
|
-
icon: W(
|
|
604
|
+
icon: W(Je)
|
|
585
605
|
},
|
|
586
606
|
{
|
|
587
607
|
id: "explain",
|
|
@@ -629,10 +649,10 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
629
649
|
}, Tt = { class: "preview-images" }, xt = ["src"], Et = ["title", "onClick"], At = {
|
|
630
650
|
key: 0,
|
|
631
651
|
class: "preview-more"
|
|
632
|
-
}, Nt = { class: "input-field-wrapper" }, Bt = ["placeholder"],
|
|
652
|
+
}, Nt = { class: "input-field-wrapper" }, Bt = ["placeholder"], Ot = {
|
|
633
653
|
key: 1,
|
|
634
654
|
class: "input-controls"
|
|
635
|
-
},
|
|
655
|
+
}, Lt = { class: "input-left" }, Ut = ["onClick"], _t = ["onClick"], Ht = { class: "input-right" }, Wt = ["title"], qt = {
|
|
636
656
|
key: 1,
|
|
637
657
|
class: "icon-btn",
|
|
638
658
|
title: "语音输入"
|
|
@@ -661,13 +681,13 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
661
681
|
const x = [
|
|
662
682
|
{ value: "agent", label: "Agent", icon: W(he) },
|
|
663
683
|
{ value: "ask", label: "Ask", icon: W(be) }
|
|
664
|
-
], A = M(!1), N = M(!1), P = H(() => !f.value || y.value),
|
|
684
|
+
], A = M(!1), N = M(!1), P = H(() => !f.value || y.value), L = H(() => a.selectedImages.slice(0, 3)), F = H(() => a.selectedImages.length > 0 ? "描述你想要的效果..." : a.mode === "ask" ? "有什么问题想问我?" : "描述任务,@ 添加上下文"), I = H(() => {
|
|
665
685
|
const u = x.find((o) => o.value === a.mode);
|
|
666
686
|
return (u == null ? void 0 : u.label) || "Agent";
|
|
667
687
|
}), T = H(() => {
|
|
668
688
|
const u = x.find((o) => o.value === a.mode);
|
|
669
689
|
return (u == null ? void 0 : u.icon) || he;
|
|
670
|
-
}),
|
|
690
|
+
}), J = H(() => {
|
|
671
691
|
const u = a.models.find((o) => o.model === a.model);
|
|
672
692
|
return (u == null ? void 0 : u.displayName) || "Auto";
|
|
673
693
|
});
|
|
@@ -741,7 +761,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
741
761
|
}, [
|
|
742
762
|
e.selectedImages.length > 0 ? (n(), i("div", It, [
|
|
743
763
|
t("div", Tt, [
|
|
744
|
-
(n(!0), i(B, null, q(
|
|
764
|
+
(n(!0), i(B, null, q(L.value, ($, Z) => (n(), i("div", {
|
|
745
765
|
key: `${$}-${Z}`,
|
|
746
766
|
class: "preview-item"
|
|
747
767
|
}, [
|
|
@@ -767,7 +787,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
767
787
|
ref_key: "inputRef",
|
|
768
788
|
ref: m,
|
|
769
789
|
"onUpdate:modelValue": o[0] || (o[0] = ($) => s.value = $),
|
|
770
|
-
placeholder:
|
|
790
|
+
placeholder: F.value,
|
|
771
791
|
rows: "1",
|
|
772
792
|
class: "input-field",
|
|
773
793
|
onKeydown: U,
|
|
@@ -777,8 +797,8 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
777
797
|
[Be, s.value]
|
|
778
798
|
])
|
|
779
799
|
]),
|
|
780
|
-
P.value ? (n(), i("div",
|
|
781
|
-
t("div",
|
|
800
|
+
P.value ? (n(), i("div", Ot, [
|
|
801
|
+
t("div", Lt, [
|
|
782
802
|
t("div", {
|
|
783
803
|
class: "selector mode-selector",
|
|
784
804
|
onClick: X(C, ["stop"])
|
|
@@ -814,7 +834,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
814
834
|
class: "selector model-selector",
|
|
815
835
|
onClick: X(v, ["stop"])
|
|
816
836
|
}, [
|
|
817
|
-
t("span", null, z(
|
|
837
|
+
t("span", null, z(J.value), 1),
|
|
818
838
|
S(l(j), {
|
|
819
839
|
size: 10,
|
|
820
840
|
class: "chevron"
|
|
@@ -893,10 +913,10 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
893
913
|
}), Se = /* @__PURE__ */ Q(Vt, [["__scopeId", "data-v-79ec50ab"]]), Pt = {
|
|
894
914
|
key: 0,
|
|
895
915
|
class: "execution-steps"
|
|
896
|
-
},
|
|
916
|
+
}, Ft = {
|
|
897
917
|
key: 0,
|
|
898
918
|
class: "step thinking-step"
|
|
899
|
-
},
|
|
919
|
+
}, Jt = { class: "step-icon" }, Gt = { class: "step-title" }, Kt = {
|
|
900
920
|
key: 0,
|
|
901
921
|
class: "step-content"
|
|
902
922
|
}, Qt = { class: "thinking-content" }, Xt = {
|
|
@@ -920,7 +940,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
920
940
|
toolCalls: {}
|
|
921
941
|
},
|
|
922
942
|
setup(e) {
|
|
923
|
-
const h = e, g = M(!1), a = M(!0), c =
|
|
943
|
+
const h = e, g = M(!1), a = M(!0), c = Oe({}), f = H(() => {
|
|
924
944
|
var y, x;
|
|
925
945
|
return h.thinking || h.searching || ((y = h.searchResults) == null ? void 0 : y.length) || ((x = h.toolCalls) == null ? void 0 : x.length) || h.loading && !h.hasContent;
|
|
926
946
|
});
|
|
@@ -949,14 +969,14 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
949
969
|
}[y] || y;
|
|
950
970
|
}
|
|
951
971
|
return (y, x) => {
|
|
952
|
-
var A, N, P,
|
|
972
|
+
var A, N, P, L, F;
|
|
953
973
|
return f.value ? (n(), i("div", Pt, [
|
|
954
|
-
e.thinking || e.loading && !e.hasContent && !((A = e.toolCalls) != null && A.length) ? (n(), i("div",
|
|
974
|
+
e.thinking || e.loading && !e.hasContent && !((A = e.toolCalls) != null && A.length) ? (n(), i("div", Ft, [
|
|
955
975
|
t("div", {
|
|
956
976
|
class: "step-header",
|
|
957
977
|
onClick: x[0] || (x[0] = (I) => g.value = !g.value)
|
|
958
978
|
}, [
|
|
959
|
-
t("div",
|
|
979
|
+
t("div", Jt, [
|
|
960
980
|
e.thinkingComplete ? (n(), k(l($e), {
|
|
961
981
|
key: 1,
|
|
962
982
|
size: 14
|
|
@@ -993,13 +1013,13 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
993
1013
|
}))
|
|
994
1014
|
]),
|
|
995
1015
|
t("span", Zt, z(e.searching ? "正在搜索..." : `找到 ${((P = e.searchResults) == null ? void 0 : P.length) || 0} 条结果`), 1),
|
|
996
|
-
(
|
|
1016
|
+
(L = e.searchResults) != null && L.length ? (n(), k(l(j), {
|
|
997
1017
|
key: 0,
|
|
998
1018
|
size: 14,
|
|
999
1019
|
class: E(["step-chevron", { expanded: a.value }])
|
|
1000
1020
|
}, null, 8, ["class"])) : p("", !0)
|
|
1001
1021
|
]),
|
|
1002
|
-
(
|
|
1022
|
+
(F = e.searchResults) != null && F.length && a.value ? (n(), i("div", Yt, [
|
|
1003
1023
|
t("div", en, [
|
|
1004
1024
|
(n(!0), i(B, null, q(e.searchResults, (I, T) => (n(), i("a", {
|
|
1005
1025
|
key: T,
|
|
@@ -1019,7 +1039,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1019
1039
|
}, [
|
|
1020
1040
|
t("div", {
|
|
1021
1041
|
class: "step-header",
|
|
1022
|
-
onClick: (
|
|
1042
|
+
onClick: (J) => s(T)
|
|
1023
1043
|
}, [
|
|
1024
1044
|
t("div", an, [
|
|
1025
1045
|
I.status === "running" ? (n(), k(l(ee), {
|
|
@@ -1176,11 +1196,11 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1176
1196
|
webSearch: A,
|
|
1177
1197
|
thinking: N,
|
|
1178
1198
|
loadSessions: P,
|
|
1179
|
-
switchSession:
|
|
1180
|
-
createNewSession:
|
|
1199
|
+
switchSession: L,
|
|
1200
|
+
createNewSession: F,
|
|
1181
1201
|
deleteSession: I,
|
|
1182
1202
|
sendMessage: T,
|
|
1183
|
-
cancelRequest:
|
|
1203
|
+
cancelRequest: J,
|
|
1184
1204
|
copyMessage: C,
|
|
1185
1205
|
regenerateMessage: v,
|
|
1186
1206
|
setMode: b,
|
|
@@ -1188,13 +1208,13 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1188
1208
|
setWebSearch: G,
|
|
1189
1209
|
setThinking: d,
|
|
1190
1210
|
setWorkingDirectory: w
|
|
1191
|
-
} = c, r = M([]), R = M(null), U =
|
|
1211
|
+
} = c, r = M([]), R = M(null), U = Le(g, "models");
|
|
1192
1212
|
Ue("chatAdapter", g.adapter), oe(() => {
|
|
1193
1213
|
P();
|
|
1194
1214
|
}), ae(
|
|
1195
1215
|
() => g.workingDir,
|
|
1196
|
-
(
|
|
1197
|
-
|
|
1216
|
+
(O) => {
|
|
1217
|
+
O && w(O);
|
|
1198
1218
|
},
|
|
1199
1219
|
{ immediate: !0 }
|
|
1200
1220
|
);
|
|
@@ -1204,17 +1224,17 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1204
1224
|
ae(m, () => {
|
|
1205
1225
|
Y();
|
|
1206
1226
|
}, { flush: "post" });
|
|
1207
|
-
function u(
|
|
1208
|
-
T(
|
|
1227
|
+
function u(O) {
|
|
1228
|
+
T(O, r.value.length > 0 ? r.value : void 0), r.value = [];
|
|
1209
1229
|
}
|
|
1210
|
-
function o(
|
|
1211
|
-
T(
|
|
1230
|
+
function o(O) {
|
|
1231
|
+
T(O);
|
|
1212
1232
|
}
|
|
1213
|
-
function $(
|
|
1214
|
-
m.value = m.value.slice(0,
|
|
1233
|
+
function $(O, re) {
|
|
1234
|
+
m.value = m.value.slice(0, O), T(re);
|
|
1215
1235
|
}
|
|
1216
|
-
function Z(
|
|
1217
|
-
|
|
1236
|
+
function Z(O) {
|
|
1237
|
+
O >= 0 && O < r.value.length && r.value.splice(O, 1);
|
|
1218
1238
|
}
|
|
1219
1239
|
function ce() {
|
|
1220
1240
|
console.log("上传图片");
|
|
@@ -1243,14 +1263,14 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1243
1263
|
function Ee() {
|
|
1244
1264
|
console.log("Agent 设置");
|
|
1245
1265
|
}
|
|
1246
|
-
return (
|
|
1266
|
+
return (O, re) => (n(), i("div", $n, [
|
|
1247
1267
|
e.hideHeader ? p("", !0) : (n(), k($t, {
|
|
1248
1268
|
key: 0,
|
|
1249
1269
|
sessions: l(f),
|
|
1250
1270
|
"current-session-id": l(s),
|
|
1251
1271
|
"show-close": !!e.onClose,
|
|
1252
|
-
onNewSession: l(
|
|
1253
|
-
onSwitchSession: l(
|
|
1272
|
+
onNewSession: l(F),
|
|
1273
|
+
onSwitchSession: l(L),
|
|
1254
1274
|
onDeleteSession: l(I),
|
|
1255
1275
|
onClose: ze,
|
|
1256
1276
|
onClearAll: Re,
|
|
@@ -1294,7 +1314,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1294
1314
|
"web-search-enabled": l(A),
|
|
1295
1315
|
"thinking-enabled": l(N),
|
|
1296
1316
|
onSend: u,
|
|
1297
|
-
onCancel: l(
|
|
1317
|
+
onCancel: l(J),
|
|
1298
1318
|
onRemoveImage: Z,
|
|
1299
1319
|
onUploadImage: ce,
|
|
1300
1320
|
onAtContext: Me,
|
|
@@ -1305,7 +1325,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1305
1325
|
}, null, 8, ["selected-images", "is-loading", "mode", "model", "models", "web-search-enabled", "thinking-enabled", "onCancel", "onUpdate:mode", "onUpdate:model", "onUpdate:webSearch", "onUpdate:thinking"])
|
|
1306
1326
|
]));
|
|
1307
1327
|
}
|
|
1308
|
-
}),
|
|
1328
|
+
}), Jn = /* @__PURE__ */ Q(wn, [["__scopeId", "data-v-2332ad8f"]]), Sn = { class: "thinking-icon" }, Mn = { class: "thinking-title" }, zn = {
|
|
1309
1329
|
key: 0,
|
|
1310
1330
|
class: "thinking-content"
|
|
1311
1331
|
}, Rn = { class: "thinking-text" }, Dn = /* @__PURE__ */ K({
|
|
@@ -1426,7 +1446,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1426
1446
|
])) : p("", !0)
|
|
1427
1447
|
], 2));
|
|
1428
1448
|
}
|
|
1429
|
-
}), Kn = /* @__PURE__ */ Q(Bn, [["__scopeId", "data-v-7098f4a3"]]),
|
|
1449
|
+
}), Kn = /* @__PURE__ */ Q(Bn, [["__scopeId", "data-v-7098f4a3"]]), On = { class: "search-block" }, Ln = { class: "search-icon" }, Un = { class: "search-title" }, _n = {
|
|
1430
1450
|
key: 0,
|
|
1431
1451
|
class: "search-results"
|
|
1432
1452
|
}, Hn = ["href"], Wn = { class: "result-title" }, qn = { class: "result-url" }, Vn = /* @__PURE__ */ K({
|
|
@@ -1444,12 +1464,12 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1444
1464
|
return a;
|
|
1445
1465
|
}
|
|
1446
1466
|
}
|
|
1447
|
-
return (a, c) => (n(), i("div",
|
|
1467
|
+
return (a, c) => (n(), i("div", On, [
|
|
1448
1468
|
t("div", {
|
|
1449
1469
|
class: "search-header",
|
|
1450
1470
|
onClick: c[0] || (c[0] = (f) => h.value = !h.value)
|
|
1451
1471
|
}, [
|
|
1452
|
-
t("div",
|
|
1472
|
+
t("div", Ln, [
|
|
1453
1473
|
e.searching ? (n(), k(l(ee), {
|
|
1454
1474
|
key: 0,
|
|
1455
1475
|
size: 14,
|
|
@@ -1483,7 +1503,7 @@ const at = { class: "chat-header" }, ot = { class: "tabs-container" }, it = {
|
|
|
1483
1503
|
export {
|
|
1484
1504
|
$t as ChatHeader,
|
|
1485
1505
|
Se as ChatInput,
|
|
1486
|
-
|
|
1506
|
+
Jn as ChatPanel,
|
|
1487
1507
|
we as DEFAULT_MODELS,
|
|
1488
1508
|
dn as ExecutionSteps,
|
|
1489
1509
|
lt as FileType,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { ChatMode as ChatModeType, ModelConfig as ModelConfigType, ModelProvider as ModelProviderType, ThinkingMode as ThinkingModeType, SessionRecord as SessionRecordType, MessageRecord as MessageRecordType } from '@huyooo/ai-chat-bridge-electron/renderer';
|
|
2
|
+
export type ChatMode = ChatModeType;
|
|
3
|
+
export type ModelConfig = ModelConfigType;
|
|
4
|
+
export type ModelProvider = ModelProviderType;
|
|
5
|
+
export type ThinkingMode = ThinkingModeType;
|
|
6
|
+
export type SessionRecord = SessionRecordType;
|
|
7
|
+
export type MessageRecord = MessageRecordType;
|
|
4
8
|
/** 搜索结果 */
|
|
5
9
|
export interface SearchResult {
|
|
6
10
|
title: string;
|
|
@@ -14,22 +18,7 @@ export interface ToolCall {
|
|
|
14
18
|
result?: string;
|
|
15
19
|
status: 'running' | 'success' | 'error';
|
|
16
20
|
}
|
|
17
|
-
/**
|
|
18
|
-
export type ModelProvider = 'openrouter' | 'doubao' | 'deepseek' | 'qwen' | 'gemini' | 'ark';
|
|
19
|
-
/** 模型配置 */
|
|
20
|
-
export interface ModelConfig {
|
|
21
|
-
provider: ModelProvider;
|
|
22
|
-
model: string;
|
|
23
|
-
displayName: string;
|
|
24
|
-
supportsTools: boolean;
|
|
25
|
-
supportsWebSearch: boolean;
|
|
26
|
-
supportedThinkingModes: ThinkingMode[];
|
|
27
|
-
}
|
|
28
|
-
/** 思考模式 */
|
|
29
|
-
export type ThinkingMode = 'enabled' | 'disabled';
|
|
30
|
-
/** 聊天模式 */
|
|
31
|
-
export type ChatMode = 'agent' | 'ask';
|
|
32
|
-
/** 聊天消息 */
|
|
21
|
+
/** 聊天消息(前端显示用) */
|
|
33
22
|
export interface ChatMessage {
|
|
34
23
|
id: string;
|
|
35
24
|
role: 'user' | 'assistant';
|
|
@@ -44,28 +33,8 @@ export interface ChatMessage {
|
|
|
44
33
|
loading?: boolean;
|
|
45
34
|
timestamp?: Date;
|
|
46
35
|
}
|
|
47
|
-
/** 会话记录 */
|
|
48
|
-
export interface SessionRecord {
|
|
49
|
-
id: string;
|
|
50
|
-
title: string;
|
|
51
|
-
model: string;
|
|
52
|
-
mode: ChatMode;
|
|
53
|
-
createdAt: Date;
|
|
54
|
-
updatedAt: Date;
|
|
55
|
-
}
|
|
56
|
-
/** 消息记录 */
|
|
57
|
-
export interface MessageRecord {
|
|
58
|
-
id: string;
|
|
59
|
-
sessionId: string;
|
|
60
|
-
role: 'user' | 'assistant';
|
|
61
|
-
content: string;
|
|
62
|
-
thinking?: string;
|
|
63
|
-
toolCalls?: string;
|
|
64
|
-
searchResults?: string;
|
|
65
|
-
timestamp: Date;
|
|
66
|
-
}
|
|
67
36
|
/** 默认模型列表 */
|
|
68
|
-
export declare const DEFAULT_MODELS:
|
|
37
|
+
export declare const DEFAULT_MODELS: ModelConfigType[];
|
|
69
38
|
/** @deprecated 使用 SessionRecord */
|
|
70
39
|
export interface ChatSession {
|
|
71
40
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huyooo/ai-chat-frontend-vue",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "AI Chat Frontend - Vue components with adapter pattern",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"vue": "^3.4.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
+
"@huyooo/ai-chat-bridge-electron": "^0.1.6",
|
|
32
33
|
"lucide-vue-next": "^0.460.0",
|
|
33
34
|
"vscode-uri": "^3.1.0"
|
|
34
35
|
},
|
package/src/adapter.ts
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Chat Adapter
|
|
3
|
-
*
|
|
2
|
+
* Chat Adapter 辅助类型和工具
|
|
3
|
+
* 核心 ChatAdapter 接口从 bridge-electron 导入
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type { ChatAdapter as ChatAdapterType, ChatMode, ThinkingMode } from '@huyooo/ai-chat-bridge-electron/renderer'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
export type
|
|
10
|
-
|
|
11
|
-
| 'search_start'
|
|
12
|
-
| 'search_result'
|
|
13
|
-
| 'tool_call'
|
|
14
|
-
| 'tool_result'
|
|
15
|
-
| 'text_delta'
|
|
16
|
-
| 'text'
|
|
17
|
-
| 'done'
|
|
18
|
-
| 'error'
|
|
8
|
+
// 重新导出 ChatAdapter 类型供内部组件使用
|
|
9
|
+
export type ChatAdapter = ChatAdapterType
|
|
10
|
+
import type { SearchResult } from './types'
|
|
19
11
|
|
|
20
12
|
/** 思考数据 */
|
|
21
13
|
export interface ThinkingData {
|
|
@@ -41,12 +33,6 @@ export interface ImageData {
|
|
|
41
33
|
mimeType: string
|
|
42
34
|
}
|
|
43
35
|
|
|
44
|
-
/** 聊天进度事件 */
|
|
45
|
-
export interface ChatProgress {
|
|
46
|
-
type: ChatProgressType
|
|
47
|
-
data: string | ThinkingData | ToolCallData | ToolResultData | { results: SearchResult[] }
|
|
48
|
-
}
|
|
49
|
-
|
|
50
36
|
/** 发送消息选项 */
|
|
51
37
|
export interface SendMessageOptions {
|
|
52
38
|
mode: ChatMode
|
|
@@ -79,78 +65,62 @@ export interface SaveMessageOptions {
|
|
|
79
65
|
searchResults?: string
|
|
80
66
|
}
|
|
81
67
|
|
|
82
|
-
/**
|
|
83
|
-
* Chat Adapter 接口
|
|
84
|
-
* 所有后端通信实现都需要实现此接口
|
|
85
|
-
*/
|
|
86
|
-
export interface ChatAdapter {
|
|
87
|
-
/** 获取所有会话 */
|
|
88
|
-
getSessions(): Promise<SessionRecord[]>
|
|
89
|
-
|
|
90
|
-
/** 创建新会话 */
|
|
91
|
-
createSession(options: CreateSessionOptions): Promise<SessionRecord>
|
|
92
|
-
|
|
93
|
-
/** 更新会话 */
|
|
94
|
-
updateSession(sessionId: string, options: UpdateSessionOptions): Promise<void>
|
|
95
|
-
|
|
96
|
-
/** 删除会话 */
|
|
97
|
-
deleteSession(sessionId: string): Promise<void>
|
|
98
|
-
|
|
99
|
-
/** 获取会话消息 */
|
|
100
|
-
getMessages(sessionId: string): Promise<MessageRecord[]>
|
|
101
|
-
|
|
102
|
-
/** 保存消息 */
|
|
103
|
-
saveMessage(options: SaveMessageOptions): Promise<MessageRecord>
|
|
104
|
-
|
|
105
|
-
/** 发送消息并获取流式响应 */
|
|
106
|
-
sendMessage(
|
|
107
|
-
content: string,
|
|
108
|
-
options: SendMessageOptions,
|
|
109
|
-
images?: string[]
|
|
110
|
-
): AsyncGenerator<ChatProgress, void, unknown>
|
|
111
|
-
|
|
112
|
-
/** 取消当前请求 */
|
|
113
|
-
cancel(): void
|
|
114
|
-
|
|
115
|
-
/** 设置工作目录 */
|
|
116
|
-
setWorkingDir?(dir: string): void
|
|
117
|
-
}
|
|
118
|
-
|
|
119
68
|
/**
|
|
120
69
|
* 创建空 Adapter(用于测试或无后端场景)
|
|
121
70
|
*/
|
|
122
|
-
export function createNullAdapter():
|
|
71
|
+
export function createNullAdapter(): ChatAdapterType {
|
|
123
72
|
return {
|
|
73
|
+
async getModels() {
|
|
74
|
+
return []
|
|
75
|
+
},
|
|
124
76
|
async getSessions() {
|
|
125
77
|
return []
|
|
126
78
|
},
|
|
127
|
-
async
|
|
79
|
+
async getSession() {
|
|
80
|
+
return null
|
|
81
|
+
},
|
|
82
|
+
async createSession(params) {
|
|
128
83
|
return {
|
|
129
84
|
id: Date.now().toString(),
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
85
|
+
appId: null,
|
|
86
|
+
userId: null,
|
|
87
|
+
title: params?.title || '新对话',
|
|
88
|
+
model: params?.model || '',
|
|
89
|
+
mode: (params?.mode || 'agent') as ChatMode,
|
|
133
90
|
createdAt: new Date(),
|
|
134
91
|
updatedAt: new Date(),
|
|
135
92
|
}
|
|
136
93
|
},
|
|
137
|
-
async updateSession() {
|
|
94
|
+
async updateSession() {
|
|
95
|
+
return null
|
|
96
|
+
},
|
|
138
97
|
async deleteSession() {},
|
|
139
98
|
async getMessages() {
|
|
140
99
|
return []
|
|
141
100
|
},
|
|
142
|
-
async saveMessage(
|
|
101
|
+
async saveMessage(params) {
|
|
143
102
|
return {
|
|
144
103
|
id: Date.now().toString(),
|
|
145
|
-
sessionId:
|
|
146
|
-
role:
|
|
147
|
-
content:
|
|
148
|
-
thinking:
|
|
149
|
-
toolCalls:
|
|
150
|
-
searchResults:
|
|
104
|
+
sessionId: params.sessionId,
|
|
105
|
+
role: params.role,
|
|
106
|
+
content: params.content,
|
|
107
|
+
thinking: params.thinking || null,
|
|
108
|
+
toolCalls: params.toolCalls || null,
|
|
109
|
+
searchResults: params.searchResults || null,
|
|
110
|
+
operationIds: null,
|
|
151
111
|
timestamp: new Date(),
|
|
152
112
|
}
|
|
153
113
|
},
|
|
114
|
+
async deleteMessagesAfter() {},
|
|
115
|
+
async getOperations() {
|
|
116
|
+
return []
|
|
117
|
+
},
|
|
118
|
+
async getTrashItems() {
|
|
119
|
+
return []
|
|
120
|
+
},
|
|
121
|
+
async restoreFromTrash() {
|
|
122
|
+
return undefined
|
|
123
|
+
},
|
|
154
124
|
async *sendMessage() {
|
|
155
125
|
yield { type: 'text', data: '无可用的 Adapter' }
|
|
156
126
|
yield { type: 'done', data: '' }
|
|
@@ -4,17 +4,16 @@
|
|
|
4
4
|
* 使用 Adapter 模式解耦后端通信
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { ref,
|
|
8
|
-
import type { ChatAdapter, ChatProgress } from '../adapter'
|
|
9
|
-
import { createNullAdapter } from '../adapter'
|
|
7
|
+
import { ref, shallowRef } from 'vue'
|
|
10
8
|
import type {
|
|
11
|
-
|
|
9
|
+
ChatAdapter,
|
|
10
|
+
ChatProgress,
|
|
12
11
|
ChatMode,
|
|
13
12
|
SessionRecord,
|
|
14
13
|
MessageRecord,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} from '../types'
|
|
14
|
+
} from '@huyooo/ai-chat-bridge-electron/renderer'
|
|
15
|
+
import { createNullAdapter } from '../adapter'
|
|
16
|
+
import type { ChatMessage, SearchResult, ToolCall } from '../types'
|
|
18
17
|
|
|
19
18
|
/** 生成唯一 ID */
|
|
20
19
|
function generateId(): string {
|
package/src/index.ts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @huyooo/ai-chat-frontend
|
|
2
|
+
* @huyooo/ai-chat-frontend-vue
|
|
3
3
|
*
|
|
4
|
-
* AI Chat 前端组件库
|
|
4
|
+
* AI Chat 前端组件库 - Vue 版本
|
|
5
5
|
*
|
|
6
6
|
* 使用 adapter 模式,与后端通信方式解耦
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
//
|
|
9
|
+
// 从 bridge-electron 重新导出核心类型,确保类型一致性
|
|
10
|
+
// 注意:createElectronAdapter 需要从 @huyooo/ai-chat-bridge-electron/renderer 单独导入
|
|
10
11
|
export type {
|
|
11
12
|
ChatAdapter,
|
|
12
13
|
ChatProgress,
|
|
13
14
|
ChatProgressType,
|
|
15
|
+
ChatOptions,
|
|
16
|
+
ChatMode,
|
|
17
|
+
ModelConfig,
|
|
18
|
+
ModelProvider,
|
|
19
|
+
ThinkingMode,
|
|
20
|
+
SessionRecord,
|
|
21
|
+
MessageRecord,
|
|
22
|
+
} from '@huyooo/ai-chat-bridge-electron/renderer'
|
|
23
|
+
|
|
24
|
+
// 导出本地定义的辅助类型
|
|
25
|
+
export type {
|
|
14
26
|
ThinkingData,
|
|
15
27
|
ToolCallData,
|
|
16
28
|
ToolResultData,
|
|
@@ -47,15 +59,9 @@ export { default as ThinkingBlock } from './components/chat/ThinkingBlock.vue';
|
|
|
47
59
|
export { default as ToolCallBlock } from './components/chat/ToolCallBlock.vue';
|
|
48
60
|
export { default as SearchResultBlock } from './components/chat/SearchResultBlock.vue';
|
|
49
61
|
|
|
50
|
-
//
|
|
62
|
+
// 导出前端特有类型(不与 bridge-electron 重复)
|
|
51
63
|
export type {
|
|
52
64
|
ChatMessage,
|
|
53
|
-
ChatMode,
|
|
54
|
-
ModelConfig,
|
|
55
|
-
ModelProvider,
|
|
56
|
-
ThinkingMode,
|
|
57
|
-
SessionRecord,
|
|
58
|
-
MessageRecord,
|
|
59
65
|
SearchResult,
|
|
60
66
|
ToolCall,
|
|
61
67
|
// 向后兼容
|
|
@@ -69,14 +75,18 @@ export { DEFAULT_MODELS, FileType } from './types';
|
|
|
69
75
|
/**
|
|
70
76
|
* 使用说明:
|
|
71
77
|
*
|
|
72
|
-
* 1.
|
|
73
|
-
* import
|
|
74
|
-
* const adapter = createElectronAdapter();
|
|
78
|
+
* 1. 导入样式:
|
|
79
|
+
* import '@huyooo/ai-chat-frontend-vue/style.css'
|
|
75
80
|
*
|
|
76
|
-
* 2.
|
|
81
|
+
* 2. 创建 adapter 和使用组件:
|
|
82
|
+
* import { ChatPanel } from '@huyooo/ai-chat-frontend-vue'
|
|
83
|
+
* import { createElectronAdapter } from '@huyooo/ai-chat-bridge-electron/renderer'
|
|
84
|
+
* const adapter = createElectronAdapter()
|
|
77
85
|
* <ChatPanel :adapter="adapter" />
|
|
78
86
|
*
|
|
79
|
-
* 3. 或使用 useChat composable:
|
|
80
|
-
*
|
|
81
|
-
*
|
|
87
|
+
* 3. 或使用 useChat composable 自定义 UI:
|
|
88
|
+
* import { useChat } from '@huyooo/ai-chat-frontend-vue'
|
|
89
|
+
* import { createElectronAdapter } from '@huyooo/ai-chat-bridge-electron/renderer'
|
|
90
|
+
* const adapter = createElectronAdapter()
|
|
91
|
+
* const chat = useChat({ adapter })
|
|
82
92
|
*/
|
package/src/types/index.ts
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AI Chat 前端类型定义
|
|
3
|
+
* 核心类型从 bridge-electron 导出,保持类型一致性
|
|
3
4
|
*/
|
|
4
5
|
|
|
6
|
+
// 从 bridge-electron 导入类型
|
|
7
|
+
import type {
|
|
8
|
+
ChatMode as ChatModeType,
|
|
9
|
+
ModelConfig as ModelConfigType,
|
|
10
|
+
ModelProvider as ModelProviderType,
|
|
11
|
+
ThinkingMode as ThinkingModeType,
|
|
12
|
+
SessionRecord as SessionRecordType,
|
|
13
|
+
MessageRecord as MessageRecordType,
|
|
14
|
+
} from '@huyooo/ai-chat-bridge-electron/renderer'
|
|
15
|
+
|
|
16
|
+
// 重新导出核心类型
|
|
17
|
+
export type ChatMode = ChatModeType
|
|
18
|
+
export type ModelConfig = ModelConfigType
|
|
19
|
+
export type ModelProvider = ModelProviderType
|
|
20
|
+
export type ThinkingMode = ThinkingModeType
|
|
21
|
+
export type SessionRecord = SessionRecordType
|
|
22
|
+
export type MessageRecord = MessageRecordType
|
|
23
|
+
|
|
5
24
|
/** 搜索结果 */
|
|
6
25
|
export interface SearchResult {
|
|
7
26
|
title: string
|
|
@@ -17,26 +36,7 @@ export interface ToolCall {
|
|
|
17
36
|
status: 'running' | 'success' | 'error'
|
|
18
37
|
}
|
|
19
38
|
|
|
20
|
-
/**
|
|
21
|
-
export type ModelProvider = 'openrouter' | 'doubao' | 'deepseek' | 'qwen' | 'gemini' | 'ark'
|
|
22
|
-
|
|
23
|
-
/** 模型配置 */
|
|
24
|
-
export interface ModelConfig {
|
|
25
|
-
provider: ModelProvider
|
|
26
|
-
model: string
|
|
27
|
-
displayName: string
|
|
28
|
-
supportsTools: boolean
|
|
29
|
-
supportsWebSearch: boolean
|
|
30
|
-
supportedThinkingModes: ThinkingMode[]
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** 思考模式 */
|
|
34
|
-
export type ThinkingMode = 'enabled' | 'disabled'
|
|
35
|
-
|
|
36
|
-
/** 聊天模式 */
|
|
37
|
-
export type ChatMode = 'agent' | 'ask'
|
|
38
|
-
|
|
39
|
-
/** 聊天消息 */
|
|
39
|
+
/** 聊天消息(前端显示用) */
|
|
40
40
|
export interface ChatMessage {
|
|
41
41
|
id: string
|
|
42
42
|
role: 'user' | 'assistant'
|
|
@@ -52,30 +52,8 @@ export interface ChatMessage {
|
|
|
52
52
|
timestamp?: Date
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
/** 会话记录 */
|
|
56
|
-
export interface SessionRecord {
|
|
57
|
-
id: string
|
|
58
|
-
title: string
|
|
59
|
-
model: string
|
|
60
|
-
mode: ChatMode
|
|
61
|
-
createdAt: Date
|
|
62
|
-
updatedAt: Date
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** 消息记录 */
|
|
66
|
-
export interface MessageRecord {
|
|
67
|
-
id: string
|
|
68
|
-
sessionId: string
|
|
69
|
-
role: 'user' | 'assistant'
|
|
70
|
-
content: string
|
|
71
|
-
thinking?: string
|
|
72
|
-
toolCalls?: string
|
|
73
|
-
searchResults?: string
|
|
74
|
-
timestamp: Date
|
|
75
|
-
}
|
|
76
|
-
|
|
77
55
|
/** 默认模型列表 */
|
|
78
|
-
export const DEFAULT_MODELS:
|
|
56
|
+
export const DEFAULT_MODELS: ModelConfigType[] = [
|
|
79
57
|
{
|
|
80
58
|
provider: 'openrouter',
|
|
81
59
|
model: 'anthropic/claude-opus-4.5',
|