@huyooo/ai-chat-bridge-electron 0.1.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/dist/main/index.cjs +145 -0
- package/dist/main/index.d.cts +41 -0
- package/dist/main/index.d.ts +41 -0
- package/dist/main/index.js +125 -0
- package/dist/preload/index.cjs +68 -0
- package/dist/preload/index.d.cts +143 -0
- package/dist/preload/index.d.ts +143 -0
- package/dist/preload/index.js +43 -0
- package/dist/renderer/index.cjs +126 -0
- package/dist/renderer/index.d.cts +268 -0
- package/dist/renderer/index.d.ts +268 -0
- package/dist/renderer/index.js +105 -0
- package/package.json +60 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Electron Preload 桥接
|
|
3
|
+
*
|
|
4
|
+
* 在 preload 脚本中调用,暴露 API 给渲染进程
|
|
5
|
+
*/
|
|
6
|
+
/** 发送消息参数 */
|
|
7
|
+
interface SendMessageParams {
|
|
8
|
+
message: string;
|
|
9
|
+
images?: string[];
|
|
10
|
+
sessionId?: string;
|
|
11
|
+
options?: {
|
|
12
|
+
mode?: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
provider?: string;
|
|
15
|
+
enableWebSearch?: boolean;
|
|
16
|
+
thinkingMode?: string;
|
|
17
|
+
thinkingBudget?: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** 模型配置 */
|
|
21
|
+
interface ModelConfig$1 {
|
|
22
|
+
provider: string;
|
|
23
|
+
model: string;
|
|
24
|
+
displayName: string;
|
|
25
|
+
supportsTools: boolean;
|
|
26
|
+
supportsWebSearch: boolean;
|
|
27
|
+
supportedThinkingModes: string[];
|
|
28
|
+
}
|
|
29
|
+
/** 会话记录 */
|
|
30
|
+
interface SessionRecord$1 {
|
|
31
|
+
id: string;
|
|
32
|
+
appId: string | null;
|
|
33
|
+
userId: string | null;
|
|
34
|
+
title: string;
|
|
35
|
+
model: string;
|
|
36
|
+
mode: 'agent' | 'plan' | 'ask';
|
|
37
|
+
createdAt: Date;
|
|
38
|
+
updatedAt: Date;
|
|
39
|
+
}
|
|
40
|
+
/** 消息记录 */
|
|
41
|
+
interface MessageRecord$1 {
|
|
42
|
+
id: string;
|
|
43
|
+
sessionId: string;
|
|
44
|
+
role: 'user' | 'assistant';
|
|
45
|
+
content: string;
|
|
46
|
+
thinking?: string | null;
|
|
47
|
+
toolCalls?: string | null;
|
|
48
|
+
searchResults?: string | null;
|
|
49
|
+
operationIds?: string | null;
|
|
50
|
+
timestamp: Date;
|
|
51
|
+
}
|
|
52
|
+
/** 操作记录 */
|
|
53
|
+
interface OperationRecord$1 {
|
|
54
|
+
id: string;
|
|
55
|
+
sessionId: string;
|
|
56
|
+
messageId?: string | null;
|
|
57
|
+
command: string;
|
|
58
|
+
operationType: string;
|
|
59
|
+
affectedFiles: string;
|
|
60
|
+
status: string;
|
|
61
|
+
timestamp: Date;
|
|
62
|
+
}
|
|
63
|
+
/** 回收站记录 */
|
|
64
|
+
interface TrashRecord$1 {
|
|
65
|
+
id: string;
|
|
66
|
+
sessionId: string;
|
|
67
|
+
originalPath: string;
|
|
68
|
+
trashPath: string;
|
|
69
|
+
deletedAt: Date;
|
|
70
|
+
autoDeleteAt: Date;
|
|
71
|
+
}
|
|
72
|
+
interface AiChatBridge {
|
|
73
|
+
/** 获取可用模型 */
|
|
74
|
+
getModels(): Promise<ModelConfig$1[]>;
|
|
75
|
+
/** 发送消息 */
|
|
76
|
+
send(params: SendMessageParams): Promise<void>;
|
|
77
|
+
/** 取消当前请求 */
|
|
78
|
+
cancel(): Promise<void>;
|
|
79
|
+
/** 清空 Agent 内存历史 */
|
|
80
|
+
clearAgentHistory(): Promise<void>;
|
|
81
|
+
/** 获取 Agent 内存历史 */
|
|
82
|
+
getAgentHistory(): Promise<unknown[]>;
|
|
83
|
+
/** 设置工作目录 */
|
|
84
|
+
setWorkingDir(dir: string): Promise<void>;
|
|
85
|
+
/** 获取配置 */
|
|
86
|
+
getConfig(): Promise<unknown>;
|
|
87
|
+
/** 监听进度事件 */
|
|
88
|
+
onProgress(callback: (progress: unknown) => void): () => void;
|
|
89
|
+
/** 获取会话列表 */
|
|
90
|
+
getSessions(): Promise<SessionRecord$1[]>;
|
|
91
|
+
/** 获取单个会话 */
|
|
92
|
+
getSession(id: string): Promise<SessionRecord$1 | null>;
|
|
93
|
+
/** 创建会话 */
|
|
94
|
+
createSession(params?: {
|
|
95
|
+
title?: string;
|
|
96
|
+
model?: string;
|
|
97
|
+
mode?: string;
|
|
98
|
+
}): Promise<SessionRecord$1>;
|
|
99
|
+
/** 更新会话 */
|
|
100
|
+
updateSession(id: string, data: {
|
|
101
|
+
title?: string;
|
|
102
|
+
model?: string;
|
|
103
|
+
mode?: string;
|
|
104
|
+
}): Promise<SessionRecord$1 | null>;
|
|
105
|
+
/** 删除会话 */
|
|
106
|
+
deleteSession(id: string): Promise<{
|
|
107
|
+
success: boolean;
|
|
108
|
+
}>;
|
|
109
|
+
/** 获取会话消息 */
|
|
110
|
+
getMessages(sessionId: string): Promise<MessageRecord$1[]>;
|
|
111
|
+
/** 保存消息 */
|
|
112
|
+
saveMessage(params: {
|
|
113
|
+
sessionId: string;
|
|
114
|
+
role: 'user' | 'assistant';
|
|
115
|
+
content: string;
|
|
116
|
+
thinking?: string;
|
|
117
|
+
toolCalls?: string;
|
|
118
|
+
searchResults?: string;
|
|
119
|
+
operationIds?: string;
|
|
120
|
+
}): Promise<MessageRecord$1>;
|
|
121
|
+
/** 删除指定时间之后的消息(用于分叉) */
|
|
122
|
+
deleteMessagesAfter(sessionId: string, timestamp: number): Promise<{
|
|
123
|
+
success: boolean;
|
|
124
|
+
}>;
|
|
125
|
+
/** 获取操作日志 */
|
|
126
|
+
getOperations(sessionId: string): Promise<OperationRecord$1[]>;
|
|
127
|
+
/** 获取回收站 */
|
|
128
|
+
getTrashItems(): Promise<TrashRecord$1[]>;
|
|
129
|
+
/** 恢复回收站项目 */
|
|
130
|
+
restoreFromTrash(id: string): Promise<TrashRecord$1 | undefined>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Electron 渲染进程 Adapter
|
|
135
|
+
*
|
|
136
|
+
* 在渲染进程中使用,创建 ChatAdapter
|
|
137
|
+
*/
|
|
138
|
+
|
|
139
|
+
type ChatProgressType = 'thinking' | 'search_start' | 'search_result' | 'tool_call' | 'tool_result' | 'text' | 'text_delta' | 'image' | 'video' | 'done' | 'error';
|
|
140
|
+
interface ChatProgress {
|
|
141
|
+
type: ChatProgressType;
|
|
142
|
+
data: unknown;
|
|
143
|
+
}
|
|
144
|
+
type ChatMode = 'agent' | 'plan' | 'ask';
|
|
145
|
+
type ModelProvider = 'doubao' | 'deepseek';
|
|
146
|
+
type ThinkingMode = 'enabled' | 'disabled';
|
|
147
|
+
interface ChatOptions {
|
|
148
|
+
mode?: ChatMode;
|
|
149
|
+
model?: string;
|
|
150
|
+
provider?: ModelProvider;
|
|
151
|
+
enableWebSearch?: boolean;
|
|
152
|
+
thinkingMode?: ThinkingMode;
|
|
153
|
+
thinkingBudget?: number;
|
|
154
|
+
}
|
|
155
|
+
interface ModelConfig {
|
|
156
|
+
provider: ModelProvider;
|
|
157
|
+
model: string;
|
|
158
|
+
displayName: string;
|
|
159
|
+
supportsTools: boolean;
|
|
160
|
+
supportsWebSearch: boolean;
|
|
161
|
+
supportedThinkingModes: ThinkingMode[];
|
|
162
|
+
}
|
|
163
|
+
interface SessionRecord {
|
|
164
|
+
id: string;
|
|
165
|
+
appId: string | null;
|
|
166
|
+
userId: string | null;
|
|
167
|
+
title: string;
|
|
168
|
+
model: string;
|
|
169
|
+
mode: ChatMode;
|
|
170
|
+
createdAt: Date;
|
|
171
|
+
updatedAt: Date;
|
|
172
|
+
}
|
|
173
|
+
interface MessageRecord {
|
|
174
|
+
id: string;
|
|
175
|
+
sessionId: string;
|
|
176
|
+
role: 'user' | 'assistant';
|
|
177
|
+
content: string;
|
|
178
|
+
thinking?: string | null;
|
|
179
|
+
toolCalls?: string | null;
|
|
180
|
+
searchResults?: string | null;
|
|
181
|
+
operationIds?: string | null;
|
|
182
|
+
timestamp: Date;
|
|
183
|
+
}
|
|
184
|
+
interface OperationRecord {
|
|
185
|
+
id: string;
|
|
186
|
+
sessionId: string;
|
|
187
|
+
messageId?: string | null;
|
|
188
|
+
command: string;
|
|
189
|
+
operationType: string;
|
|
190
|
+
affectedFiles: string;
|
|
191
|
+
status: string;
|
|
192
|
+
timestamp: Date;
|
|
193
|
+
}
|
|
194
|
+
interface TrashRecord {
|
|
195
|
+
id: string;
|
|
196
|
+
sessionId: string;
|
|
197
|
+
originalPath: string;
|
|
198
|
+
trashPath: string;
|
|
199
|
+
deletedAt: Date;
|
|
200
|
+
autoDeleteAt: Date;
|
|
201
|
+
}
|
|
202
|
+
interface ChatAdapter {
|
|
203
|
+
/** 获取可用模型 */
|
|
204
|
+
getModels(): Promise<ModelConfig[]>;
|
|
205
|
+
/** 发送消息,返回异步迭代器 */
|
|
206
|
+
sendMessage(message: string, options?: ChatOptions, images?: string[]): AsyncIterable<ChatProgress>;
|
|
207
|
+
/** 取消当前请求 */
|
|
208
|
+
cancel(): void;
|
|
209
|
+
/** 清空 Agent 内存历史 */
|
|
210
|
+
clearAgentHistory?(): void;
|
|
211
|
+
/** 获取 Agent 内存历史 */
|
|
212
|
+
getAgentHistory?(): Promise<unknown[]>;
|
|
213
|
+
/** 设置工作目录 */
|
|
214
|
+
setWorkingDir?(dir: string): void;
|
|
215
|
+
/** 获取会话列表 */
|
|
216
|
+
getSessions(): Promise<SessionRecord[]>;
|
|
217
|
+
/** 获取单个会话 */
|
|
218
|
+
getSession(id: string): Promise<SessionRecord | null>;
|
|
219
|
+
/** 创建会话 */
|
|
220
|
+
createSession(params?: {
|
|
221
|
+
title?: string;
|
|
222
|
+
model?: string;
|
|
223
|
+
mode?: string;
|
|
224
|
+
}): Promise<SessionRecord>;
|
|
225
|
+
/** 更新会话 */
|
|
226
|
+
updateSession(id: string, data: {
|
|
227
|
+
title?: string;
|
|
228
|
+
model?: string;
|
|
229
|
+
mode?: string;
|
|
230
|
+
}): Promise<SessionRecord | null>;
|
|
231
|
+
/** 删除会话 */
|
|
232
|
+
deleteSession(id: string): Promise<void>;
|
|
233
|
+
/** 获取会话消息 */
|
|
234
|
+
getMessages(sessionId: string): Promise<MessageRecord[]>;
|
|
235
|
+
/** 保存消息 */
|
|
236
|
+
saveMessage(params: {
|
|
237
|
+
sessionId: string;
|
|
238
|
+
role: 'user' | 'assistant';
|
|
239
|
+
content: string;
|
|
240
|
+
thinking?: string;
|
|
241
|
+
toolCalls?: string;
|
|
242
|
+
searchResults?: string;
|
|
243
|
+
operationIds?: string;
|
|
244
|
+
}): Promise<MessageRecord>;
|
|
245
|
+
/** 删除指定时间之后的消息(用于分叉) */
|
|
246
|
+
deleteMessagesAfter(sessionId: string, timestamp: number): Promise<void>;
|
|
247
|
+
/** 获取操作日志 */
|
|
248
|
+
getOperations(sessionId: string): Promise<OperationRecord[]>;
|
|
249
|
+
/** 获取回收站 */
|
|
250
|
+
getTrashItems(): Promise<TrashRecord[]>;
|
|
251
|
+
/** 恢复回收站项目 */
|
|
252
|
+
restoreFromTrash(id: string): Promise<TrashRecord | undefined>;
|
|
253
|
+
}
|
|
254
|
+
declare global {
|
|
255
|
+
interface Window {
|
|
256
|
+
aiChatBridge?: AiChatBridge;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
interface CreateAdapterOptions {
|
|
260
|
+
/** 全局变量名 */
|
|
261
|
+
bridgeName?: string;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* 创建 Electron Adapter
|
|
265
|
+
*/
|
|
266
|
+
declare function createElectronAdapter(options?: CreateAdapterOptions): ChatAdapter;
|
|
267
|
+
|
|
268
|
+
export { type ChatAdapter, type ChatMode, type ChatOptions, type ChatProgress, type ChatProgressType, type CreateAdapterOptions, type MessageRecord, type ModelConfig, type ModelProvider, type OperationRecord, type SessionRecord, type ThinkingMode, type TrashRecord, createElectronAdapter };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// src/renderer/index.ts
|
|
2
|
+
function createElectronAdapter(options = {}) {
|
|
3
|
+
const { bridgeName = "aiChatBridge" } = options;
|
|
4
|
+
const getBridge = () => {
|
|
5
|
+
const bridge = window[bridgeName];
|
|
6
|
+
if (!bridge) {
|
|
7
|
+
throw new Error(`AI Chat Bridge not found. Make sure to call exposeElectronBridge() in preload.`);
|
|
8
|
+
}
|
|
9
|
+
return bridge;
|
|
10
|
+
};
|
|
11
|
+
return {
|
|
12
|
+
// ============ Chat API ============
|
|
13
|
+
async getModels() {
|
|
14
|
+
const bridge = getBridge();
|
|
15
|
+
const models = await bridge.getModels();
|
|
16
|
+
return models.map((m) => ({
|
|
17
|
+
...m,
|
|
18
|
+
provider: m.provider,
|
|
19
|
+
supportedThinkingModes: m.supportedThinkingModes
|
|
20
|
+
}));
|
|
21
|
+
},
|
|
22
|
+
async *sendMessage(message, options2, images) {
|
|
23
|
+
const bridge = getBridge();
|
|
24
|
+
const queue = [];
|
|
25
|
+
let resolveNext = null;
|
|
26
|
+
let done = false;
|
|
27
|
+
const cleanup = bridge.onProgress((progress) => {
|
|
28
|
+
queue.push(progress);
|
|
29
|
+
resolveNext?.();
|
|
30
|
+
if (progress.type === "done" || progress.type === "error") {
|
|
31
|
+
done = true;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
bridge.send({ message, images, options: options2 });
|
|
35
|
+
try {
|
|
36
|
+
while (!done || queue.length > 0) {
|
|
37
|
+
while (queue.length === 0 && !done) {
|
|
38
|
+
await new Promise((r) => resolveNext = r);
|
|
39
|
+
}
|
|
40
|
+
if (queue.length > 0) {
|
|
41
|
+
const progress = queue.shift();
|
|
42
|
+
yield progress;
|
|
43
|
+
if (progress.type === "done" || progress.type === "error") {
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} finally {
|
|
49
|
+
cleanup();
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
cancel() {
|
|
53
|
+
getBridge().cancel();
|
|
54
|
+
},
|
|
55
|
+
clearAgentHistory() {
|
|
56
|
+
getBridge().clearAgentHistory();
|
|
57
|
+
},
|
|
58
|
+
async getAgentHistory() {
|
|
59
|
+
return getBridge().getAgentHistory();
|
|
60
|
+
},
|
|
61
|
+
setWorkingDir(dir) {
|
|
62
|
+
getBridge().setWorkingDir(dir);
|
|
63
|
+
},
|
|
64
|
+
// ============ Sessions API ============
|
|
65
|
+
async getSessions() {
|
|
66
|
+
return getBridge().getSessions();
|
|
67
|
+
},
|
|
68
|
+
async getSession(id) {
|
|
69
|
+
return getBridge().getSession(id);
|
|
70
|
+
},
|
|
71
|
+
async createSession(params) {
|
|
72
|
+
return getBridge().createSession(params);
|
|
73
|
+
},
|
|
74
|
+
async updateSession(id, data) {
|
|
75
|
+
return getBridge().updateSession(id, data);
|
|
76
|
+
},
|
|
77
|
+
async deleteSession(id) {
|
|
78
|
+
await getBridge().deleteSession(id);
|
|
79
|
+
},
|
|
80
|
+
// ============ Messages API ============
|
|
81
|
+
async getMessages(sessionId) {
|
|
82
|
+
return getBridge().getMessages(sessionId);
|
|
83
|
+
},
|
|
84
|
+
async saveMessage(params) {
|
|
85
|
+
return getBridge().saveMessage(params);
|
|
86
|
+
},
|
|
87
|
+
async deleteMessagesAfter(sessionId, timestamp) {
|
|
88
|
+
await getBridge().deleteMessagesAfter(sessionId, timestamp);
|
|
89
|
+
},
|
|
90
|
+
// ============ Operations API ============
|
|
91
|
+
async getOperations(sessionId) {
|
|
92
|
+
return getBridge().getOperations(sessionId);
|
|
93
|
+
},
|
|
94
|
+
// ============ Trash API ============
|
|
95
|
+
async getTrashItems() {
|
|
96
|
+
return getBridge().getTrashItems();
|
|
97
|
+
},
|
|
98
|
+
async restoreFromTrash(id) {
|
|
99
|
+
return getBridge().restoreFromTrash(id);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export {
|
|
104
|
+
createElectronAdapter
|
|
105
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@huyooo/ai-chat-bridge-electron",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI Chat Electron Bridge - IPC integration for Electron apps",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/main/index.cjs",
|
|
7
|
+
"module": "./dist/main/index.js",
|
|
8
|
+
"types": "./dist/main/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
"./main": {
|
|
11
|
+
"types": "./dist/main/index.d.ts",
|
|
12
|
+
"import": "./dist/main/index.js",
|
|
13
|
+
"require": "./dist/main/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./preload": {
|
|
16
|
+
"types": "./dist/preload/index.d.ts",
|
|
17
|
+
"import": "./dist/preload/index.js",
|
|
18
|
+
"require": "./dist/preload/index.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./renderer": {
|
|
21
|
+
"types": "./dist/renderer/index.d.ts",
|
|
22
|
+
"import": "./dist/renderer/index.js",
|
|
23
|
+
"require": "./dist/renderer/index.cjs"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsup",
|
|
31
|
+
"dev": "tsup --watch",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"clean": "rm -rf dist"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@huyooo/ai-chat-core": "*",
|
|
37
|
+
"@huyooo/ai-chat-storage": "*"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"electron": ">=20.0.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^22.0.0",
|
|
44
|
+
"electron": "^33.0.0",
|
|
45
|
+
"tsup": "^8.0.0",
|
|
46
|
+
"typescript": "^5.0.0"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"ai",
|
|
50
|
+
"chat",
|
|
51
|
+
"electron",
|
|
52
|
+
"ipc",
|
|
53
|
+
"bridge"
|
|
54
|
+
],
|
|
55
|
+
"author": "huyooo",
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
}
|
|
60
|
+
}
|