@myassis/gateway 1.0.1 → 1.0.3
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/api/index.js +69 -59
- package/dist/config/index.js +2 -2
- package/dist/index.js +85 -11
- package/dist/middleware/auth.js +9 -25
- package/dist/middleware/errorHandler.js +1 -1
- package/dist/routes/agent.js +30 -19
- package/dist/routes/auth.js +35 -26
- package/dist/routes/chat.js +1 -1
- package/dist/routes/models.js +11 -14
- package/dist/routes/service.js +3 -6
- package/dist/routes/settings.js +11 -9
- package/dist/routes/skillHub.js +10 -6
- package/dist/routes/skills.js +13 -10
- package/dist/routes/tasks.js +6 -3
- package/dist/routes/upload.js +5 -2
- package/dist/routes/version.js +4 -4
- package/dist/services/LocalTaskService.js +2 -2
- package/dist/services/NotificationService.js +4 -4
- package/dist/services/ServiceManager.js +12 -12
- package/dist/services/TaskSchedulerService.js +21 -12
- package/dist/services/TaskService.js +25 -22
- package/dist/services/WebSocketService.js +16 -6
- package/dist/services/agent/Agent.js +7 -7
- package/dist/services/agent/AgentManager.js +26 -18
- package/dist/services/agent/AgentStore.js +1 -1
- package/dist/services/dataService.js +63 -73
- package/dist/services/index.js +9 -9
- package/dist/services/llm/LLMClient.js +11 -9
- package/dist/services/memory/MemoryManager.js +180 -17
- package/dist/services/model/index.js +1 -1
- package/dist/services/session/MigrationManager.js +1 -1
- package/dist/services/session/Session.js +74 -50
- package/dist/services/session/SessionManager.js +14 -7
- package/dist/services/session/SessionStore.js +2 -28
- package/dist/services/session/index.js +2 -2
- package/dist/services/systemPrompt.js +9 -5
- package/dist/services/task/PushTokenStore.js +2 -20
- package/dist/services/task/TaskStore.js +2 -21
- package/dist/services/tools/edit.js +122 -148
- package/dist/services/tools/exec.js +1 -1
- package/dist/services/tools/fetch.js +1 -1
- package/dist/services/tools/file.js +4 -9
- package/dist/services/tools/index.js +18 -17
- package/dist/services/tools/model.js +9 -7
- package/dist/services/tools/sessionsSpawn.js +54 -0
- package/dist/services/tools/skill.js +14 -13
- package/dist/services/tools/task.js +3 -5
- package/dist/stores/authStore.js +52 -66
- package/dist/stores/index.js +3 -3
- package/dist/stores/persistStore.js +37 -3
- package/package.json +7 -3
- package/scripts/fix-dist-imports.js +95 -0
- package/scripts/fix-imports.js +90 -0
- package/scripts/postbuild.js +39 -0
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
* 基于 SQLite 数据库的任务调度
|
|
4
4
|
* 每分钟检查待执行任务并发送通知
|
|
5
5
|
*/
|
|
6
|
-
import { taskStore } from './task/TaskStore';
|
|
7
|
-
import { webSocketService } from './WebSocketService';
|
|
8
|
-
import {
|
|
9
|
-
import { getLogger, getUTCTimeKey, formatUTCForLog, holidayService } from '@
|
|
10
|
-
import { tasksService } from './dataService';
|
|
6
|
+
import { taskStore } from './task/TaskStore.js';
|
|
7
|
+
import { webSocketService } from './WebSocketService.js';
|
|
8
|
+
import { getSessionManager } from './session.js';
|
|
9
|
+
import { getLogger, getUTCTimeKey, formatUTCForLog, holidayService } from '@myassis/shared';
|
|
10
|
+
import { tasksService } from './dataService.js';
|
|
11
|
+
import { authStore } from '@/stores';
|
|
11
12
|
const logger = getLogger('TaskSchedulerService');
|
|
12
13
|
const EXPIRED_THRESHOLD = 60 * 60 * 1000; // 1小时
|
|
13
14
|
const CHECK_INTERVAL = 60 * 1000; // 1分钟
|
|
@@ -65,13 +66,17 @@ class TaskSchedulerService {
|
|
|
65
66
|
try {
|
|
66
67
|
const now = Date.now();
|
|
67
68
|
const nowBeforeHour = now - EXPIRED_THRESHOLD;
|
|
68
|
-
const
|
|
69
|
-
if (!
|
|
69
|
+
const authMap = authStore.getAll();
|
|
70
|
+
if (!authMap) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const response = await Promise.all(Array.from(authMap.values()).map(x => tasksService.list(x.user.id)));
|
|
74
|
+
if (response.some(x => !x.success)) {
|
|
70
75
|
logger.error('获取任务失败');
|
|
71
76
|
return;
|
|
72
77
|
}
|
|
73
78
|
// 获取过期待执行任务
|
|
74
|
-
const tasks = response.data.filter(x => x.scheduledAt < nowBeforeHour && x.status !== 'completed' && x.status !== 'expired' && x.status !== 'error');
|
|
79
|
+
const tasks = response.flatMap(x => x.data).filter(x => x.scheduledAt < nowBeforeHour && x.status !== 'completed' && x.status !== 'expired' && x.status !== 'error');
|
|
75
80
|
if (tasks.length > 0) {
|
|
76
81
|
for (let task of tasks) {
|
|
77
82
|
await tasksService.updateStatus(task.id, 'expired');
|
|
@@ -90,13 +95,17 @@ class TaskSchedulerService {
|
|
|
90
95
|
const now = Date.now();
|
|
91
96
|
const nowBeforeHour = now - EXPIRED_THRESHOLD;
|
|
92
97
|
const timeKey = getUTCTimeKey(new Date());
|
|
93
|
-
const
|
|
94
|
-
if (!
|
|
98
|
+
const authMap = authStore.getAll();
|
|
99
|
+
if (!authMap) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const response = await Promise.all(Array.from(authMap.values()).map(x => tasksService.list(x.user.id)));
|
|
103
|
+
if (response.some(x => !x.success)) {
|
|
95
104
|
logger.error('获取任务失败');
|
|
96
105
|
return;
|
|
97
106
|
}
|
|
98
107
|
// 获取待执行任务
|
|
99
|
-
const tasks = response.data.filter(x => x.scheduledAt >= nowBeforeHour && x.scheduledAt <= now && x.status === 'pending');
|
|
108
|
+
const tasks = response.flatMap(x => x.data).filter(x => x.scheduledAt >= nowBeforeHour && x.scheduledAt <= now && x.status === 'pending');
|
|
100
109
|
if (tasks.length > 0) {
|
|
101
110
|
logger.info(`Found ${tasks.length} tasks to execute at ${timeKey}`);
|
|
102
111
|
for (const task of tasks) {
|
|
@@ -152,7 +161,7 @@ class TaskSchedulerService {
|
|
|
152
161
|
*/
|
|
153
162
|
async executeTaskLocally(task) {
|
|
154
163
|
try {
|
|
155
|
-
const currentSession =
|
|
164
|
+
const currentSession = getSessionManager(task.userId).getCurrentSession();
|
|
156
165
|
if (!currentSession) {
|
|
157
166
|
logger.warn(`No current session found, cannot execute task: ${task.title}`);
|
|
158
167
|
return;
|
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
* - platformApply === currentPlatform → 本地 SQLite 存储(localTaskService)
|
|
8
8
|
* - platformApply !== currentPlatform → 服务器 API(tasksApi)
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
10
|
+
import { authStore } from '@/stores';
|
|
11
|
+
import { tasksApi } from '../api.js';
|
|
12
|
+
import { localTaskService } from './LocalTaskService.js';
|
|
13
|
+
import { getLogger } from '@myassis/shared';
|
|
14
|
+
import { getPlatform } from '@myassis/shared/dist/utils/system.js';
|
|
14
15
|
// 当前网关平台标识
|
|
15
16
|
const CURRENT_PLATFORM = process.env.GATEWAY_PLATFORM || getPlatform();
|
|
16
17
|
const logger = getLogger('TaskService');
|
|
@@ -29,7 +30,7 @@ class TaskService {
|
|
|
29
30
|
/**
|
|
30
31
|
* 创建任务(自动路由)
|
|
31
32
|
*/
|
|
32
|
-
async createTask(data) {
|
|
33
|
+
async createTask(data, token) {
|
|
33
34
|
const isLocal = isLocalTask(data.platformApply);
|
|
34
35
|
logger.info('[TaskService] 创建任务', {
|
|
35
36
|
title: data.title,
|
|
@@ -73,19 +74,19 @@ class TaskService {
|
|
|
73
74
|
? (typeof data.endTime === 'object' ? new Date(data.endTime).toISOString() : data.endTime)
|
|
74
75
|
: undefined,
|
|
75
76
|
platform_apply: data.platformApply,
|
|
76
|
-
});
|
|
77
|
+
}, token);
|
|
77
78
|
return { id: String(result.id || result), isLocal: false };
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
/**
|
|
81
82
|
* 获取任务(自动路由 - 先本地后服务器)
|
|
82
83
|
*/
|
|
83
|
-
async getTask(taskId) {
|
|
84
|
+
async getTask(taskId, token) {
|
|
84
85
|
const localTask = localTaskService.getTask(taskId);
|
|
85
86
|
if (localTask)
|
|
86
87
|
return localTask;
|
|
87
88
|
try {
|
|
88
|
-
const result = await tasksApi.get(taskId);
|
|
89
|
+
const result = await tasksApi.get(taskId, token);
|
|
89
90
|
return this.transformServerTask(result);
|
|
90
91
|
}
|
|
91
92
|
catch (error) {
|
|
@@ -99,12 +100,14 @@ class TaskService {
|
|
|
99
100
|
async listTasks(params) {
|
|
100
101
|
const localResult = localTaskService.listTasks(params);
|
|
101
102
|
let serverTasks = [];
|
|
103
|
+
const userId = params.userId;
|
|
104
|
+
const token = authStore.get(userId).accessToken;
|
|
102
105
|
try {
|
|
103
106
|
const serverResult = await tasksApi.list({
|
|
104
|
-
status: params
|
|
105
|
-
page: params
|
|
106
|
-
pageSize: params
|
|
107
|
-
});
|
|
107
|
+
status: params.status,
|
|
108
|
+
page: params.page ? String(params.page) : undefined,
|
|
109
|
+
pageSize: params.pageSize ? String(params.pageSize) : undefined,
|
|
110
|
+
}, token);
|
|
108
111
|
if (Array.isArray(serverResult)) {
|
|
109
112
|
serverTasks = serverResult.map(t => this.transformServerTask(t)).filter(Boolean);
|
|
110
113
|
}
|
|
@@ -126,7 +129,7 @@ class TaskService {
|
|
|
126
129
|
/**
|
|
127
130
|
* 更新任务(自动路由)
|
|
128
131
|
*/
|
|
129
|
-
async updateTask(taskId, data) {
|
|
132
|
+
async updateTask(taskId, data, token) {
|
|
130
133
|
const localTask = localTaskService.getTask(taskId);
|
|
131
134
|
if (localTask) {
|
|
132
135
|
const result = localTaskService.updateTask(taskId, data);
|
|
@@ -151,7 +154,7 @@ class TaskService {
|
|
|
151
154
|
? (typeof data.endTime === 'object' ? new Date(data.endTime).toISOString() : data.endTime)
|
|
152
155
|
: undefined,
|
|
153
156
|
status: data.status,
|
|
154
|
-
});
|
|
157
|
+
}, token);
|
|
155
158
|
return true;
|
|
156
159
|
}
|
|
157
160
|
catch (error) {
|
|
@@ -163,14 +166,14 @@ class TaskService {
|
|
|
163
166
|
/**
|
|
164
167
|
* 删除任务(自动路由)
|
|
165
168
|
*/
|
|
166
|
-
async deleteTask(taskId) {
|
|
169
|
+
async deleteTask(taskId, token) {
|
|
167
170
|
const localTask = localTaskService.getTask(taskId);
|
|
168
171
|
if (localTask) {
|
|
169
172
|
return localTaskService.deleteTask(taskId);
|
|
170
173
|
}
|
|
171
174
|
else {
|
|
172
175
|
try {
|
|
173
|
-
await tasksApi.delete(taskId);
|
|
176
|
+
await tasksApi.delete(taskId, token);
|
|
174
177
|
return true;
|
|
175
178
|
}
|
|
176
179
|
catch (error) {
|
|
@@ -182,7 +185,7 @@ class TaskService {
|
|
|
182
185
|
/**
|
|
183
186
|
* 更新任务状态
|
|
184
187
|
*/
|
|
185
|
-
async updateTaskStatus(taskId, status) {
|
|
188
|
+
async updateTaskStatus(taskId, status, token) {
|
|
186
189
|
const localTask = localTaskService.getTask(taskId);
|
|
187
190
|
if (localTask) {
|
|
188
191
|
await localTaskService.updateTaskStatus(taskId, status);
|
|
@@ -190,7 +193,7 @@ class TaskService {
|
|
|
190
193
|
}
|
|
191
194
|
else {
|
|
192
195
|
try {
|
|
193
|
-
await tasksApi.updateStatus(taskId, { status });
|
|
196
|
+
await tasksApi.updateStatus(taskId, { status }, token);
|
|
194
197
|
return true;
|
|
195
198
|
}
|
|
196
199
|
catch (error) {
|
|
@@ -202,14 +205,14 @@ class TaskService {
|
|
|
202
205
|
/**
|
|
203
206
|
* 完成任务
|
|
204
207
|
*/
|
|
205
|
-
async completeTask(taskId) {
|
|
206
|
-
return this.updateTaskStatus(taskId, 'completed');
|
|
208
|
+
async completeTask(taskId, token) {
|
|
209
|
+
return this.updateTaskStatus(taskId, 'completed', token);
|
|
207
210
|
}
|
|
208
211
|
/**
|
|
209
212
|
* 取消任务
|
|
210
213
|
*/
|
|
211
|
-
async cancelTask(taskId) {
|
|
212
|
-
return this.updateTaskStatus(taskId, 'cancelled');
|
|
214
|
+
async cancelTask(taskId, token) {
|
|
215
|
+
return this.updateTaskStatus(taskId, 'cancelled', token);
|
|
213
216
|
}
|
|
214
217
|
/**
|
|
215
218
|
* 转换服务器任务格式
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { WebSocketServer, WebSocket } from 'ws';
|
|
6
6
|
import { authStore } from '../stores/index.js';
|
|
7
|
-
import { getLogger } from '@
|
|
7
|
+
import { getLogger } from '@myassis/shared';
|
|
8
8
|
const logger = getLogger('WebSocketService');
|
|
9
9
|
class WebSocketService {
|
|
10
10
|
wss = null;
|
|
@@ -93,13 +93,23 @@ class WebSocketService {
|
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
95
|
* 从请求中提取用户标识
|
|
96
|
-
*
|
|
96
|
+
* 支持两种方式:
|
|
97
|
+
* 1. URL 查询参数 ?token=xxx(Desktop WebSocket 连接)
|
|
98
|
+
* 2. 直接使用 authStore 中的用户 ID
|
|
97
99
|
*/
|
|
98
100
|
getClientKey(req) {
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
// 优先从 URL 查询参数中提取 token
|
|
102
|
+
let token = null;
|
|
103
|
+
const url = req.url || '';
|
|
104
|
+
const match = url.match(/[?&]token=([^&]+)/);
|
|
105
|
+
if (match) {
|
|
106
|
+
token = decodeURIComponent(match[1]);
|
|
107
|
+
}
|
|
108
|
+
if (token) {
|
|
109
|
+
const userId = authStore.getUserId(token);
|
|
110
|
+
if (userId) {
|
|
111
|
+
return String(userId);
|
|
112
|
+
}
|
|
103
113
|
}
|
|
104
114
|
return null;
|
|
105
115
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
-
import {
|
|
2
|
+
import { getSessionManager } from '../session/SessionManager.js';
|
|
3
3
|
/**
|
|
4
4
|
* Agent - Business logic entity
|
|
5
5
|
* Represents an AI agent with independent system prompt and multiple sessions
|
|
@@ -16,7 +16,7 @@ export class Agent {
|
|
|
16
16
|
updatedAt;
|
|
17
17
|
isCurrent; // 是否是当前正在查看的 Agent
|
|
18
18
|
store;
|
|
19
|
-
constructor(data, store
|
|
19
|
+
constructor(data, store) {
|
|
20
20
|
this.id = data.id;
|
|
21
21
|
this.userId = data.userId;
|
|
22
22
|
this.name = data.name;
|
|
@@ -33,14 +33,14 @@ export class Agent {
|
|
|
33
33
|
* Get all sessions under this agent
|
|
34
34
|
*/
|
|
35
35
|
getSessions() {
|
|
36
|
-
const allSessions =
|
|
36
|
+
const allSessions = getSessionManager(this.userId).getUserSessions();
|
|
37
37
|
return allSessions.filter(s => s.agentId === this.id);
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* Create new session under this agent
|
|
41
41
|
*/
|
|
42
42
|
createSession(config = {}) {
|
|
43
|
-
const session =
|
|
43
|
+
const session = getSessionManager(this.userId).createSession({
|
|
44
44
|
id: config.id || uuidv4(),
|
|
45
45
|
title: config.title || '新会话',
|
|
46
46
|
selectModelId: config.selectModelId,
|
|
@@ -55,7 +55,7 @@ export class Agent {
|
|
|
55
55
|
const session = this.getSession(sessionId);
|
|
56
56
|
if (!session)
|
|
57
57
|
return null;
|
|
58
|
-
return
|
|
58
|
+
return getSessionManager(this.userId).updateSession(sessionId, data);
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
61
|
* Delete session under this agent
|
|
@@ -64,13 +64,13 @@ export class Agent {
|
|
|
64
64
|
const session = this.getSession(sessionId);
|
|
65
65
|
if (!session)
|
|
66
66
|
return false;
|
|
67
|
-
return
|
|
67
|
+
return getSessionManager(this.userId).deleteSession(sessionId);
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
70
|
* Get session under this agent
|
|
71
71
|
*/
|
|
72
72
|
getSession(sessionId) {
|
|
73
|
-
const session =
|
|
73
|
+
const session = getSessionManager(this.userId).getSession(sessionId);
|
|
74
74
|
if (session && session.agentId === this.id) {
|
|
75
75
|
return session;
|
|
76
76
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
-
import { Agent } from './Agent';
|
|
3
|
-
import {
|
|
2
|
+
import { Agent } from './Agent.js';
|
|
3
|
+
import { getSessionManager } from '../session/SessionManager.js';
|
|
4
4
|
import { authStore } from '@/stores/authStore';
|
|
5
|
-
import { getLogger } from '@
|
|
5
|
+
import { getLogger } from '@myassis/shared';
|
|
6
6
|
import appConfig from '@/config';
|
|
7
7
|
const logger = getLogger('AgentManager');
|
|
8
8
|
/**
|
|
@@ -13,8 +13,10 @@ export class AgentManager {
|
|
|
13
13
|
store;
|
|
14
14
|
agents = null;
|
|
15
15
|
initialized = false;
|
|
16
|
-
|
|
16
|
+
userId;
|
|
17
|
+
constructor(store, userId) {
|
|
17
18
|
this.store = store;
|
|
19
|
+
this.userId = userId;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Initialize - Load all agents from database on startup
|
|
@@ -34,12 +36,12 @@ export class AgentManager {
|
|
|
34
36
|
// Load all agents from database
|
|
35
37
|
const agentDataList = this.store.findByUserId(userId);
|
|
36
38
|
for (const agentData of agentDataList) {
|
|
37
|
-
const agent = new Agent(agentData, this.store
|
|
39
|
+
const agent = new Agent(agentData, this.store);
|
|
38
40
|
this.agents.set(agent.id, agent);
|
|
39
41
|
}
|
|
40
|
-
// If no agents exist, create default "
|
|
42
|
+
// If no agents exist, create default "我的助手" agent
|
|
41
43
|
if (this.agents.size === 0) {
|
|
42
|
-
logger.info('No agents found, creating default "
|
|
44
|
+
logger.info('No agents found, creating default "我的助手" agent');
|
|
43
45
|
this.createDefaultAgent(userId);
|
|
44
46
|
}
|
|
45
47
|
// Ensure exactly one agent has isCurrent=true
|
|
@@ -58,11 +60,11 @@ export class AgentManager {
|
|
|
58
60
|
* Get current user ID
|
|
59
61
|
*/
|
|
60
62
|
getCurrentUserId() {
|
|
61
|
-
const user = authStore.getUser();
|
|
63
|
+
const user = authStore.getUser(this.userId);
|
|
62
64
|
return user ? String(user.id) : null;
|
|
63
65
|
}
|
|
64
66
|
/**
|
|
65
|
-
* Create default "
|
|
67
|
+
* Create default "我的助手" agent
|
|
66
68
|
*/
|
|
67
69
|
createDefaultAgent(userId) {
|
|
68
70
|
const agentData = {
|
|
@@ -78,7 +80,7 @@ export class AgentManager {
|
|
|
78
80
|
isCurrent: true,
|
|
79
81
|
};
|
|
80
82
|
this.store.insert(agentData);
|
|
81
|
-
const agent = new Agent(agentData, this.store
|
|
83
|
+
const agent = new Agent(agentData, this.store);
|
|
82
84
|
this.agents.set(agent.id, agent);
|
|
83
85
|
// Create default session
|
|
84
86
|
agent.createSession({ title: '新会话' });
|
|
@@ -95,7 +97,7 @@ export class AgentManager {
|
|
|
95
97
|
return [];
|
|
96
98
|
const agentDataList = this.store.findByUserId(userId);
|
|
97
99
|
return agentDataList.map(data => {
|
|
98
|
-
const sessions =
|
|
100
|
+
const sessions = getSessionManager(this.userId).getUserSessions();
|
|
99
101
|
const agentSessions = sessions
|
|
100
102
|
.filter(s => s.agentId === data.id)
|
|
101
103
|
.map(s => ({
|
|
@@ -146,7 +148,7 @@ export class AgentManager {
|
|
|
146
148
|
updatedAt: Date.now(),
|
|
147
149
|
};
|
|
148
150
|
this.store.insert(agentData);
|
|
149
|
-
const agent = new Agent(agentData, this.store
|
|
151
|
+
const agent = new Agent(agentData, this.store);
|
|
150
152
|
this.agents.set(agent.id, agent);
|
|
151
153
|
// Create default session
|
|
152
154
|
agent.createSession({ title: '新会话' });
|
|
@@ -186,7 +188,7 @@ export class AgentManager {
|
|
|
186
188
|
// Delete all sessions under this agent
|
|
187
189
|
const sessions = agent.getSessions();
|
|
188
190
|
for (const session of sessions) {
|
|
189
|
-
|
|
191
|
+
getSessionManager(this.userId).deleteSession(session.id);
|
|
190
192
|
}
|
|
191
193
|
// Delete agent
|
|
192
194
|
this.store.delete(agentId);
|
|
@@ -233,12 +235,15 @@ export class AgentManager {
|
|
|
233
235
|
* Get sessions under an agent
|
|
234
236
|
*/
|
|
235
237
|
getAgentSessions(agentId) {
|
|
236
|
-
const sessions =
|
|
238
|
+
const sessions = getSessionManager(this.userId).getUserSessions();
|
|
237
239
|
return sessions
|
|
238
240
|
.filter(s => s.agentId === agentId)
|
|
239
241
|
.map(s => ({
|
|
240
242
|
id: s.id,
|
|
241
243
|
title: s.title,
|
|
244
|
+
selectModelId: s.selectModelId,
|
|
245
|
+
isCurrent: s.isCurrent,
|
|
246
|
+
unreadCount: s.unreadCount,
|
|
242
247
|
createdAt: s.createdAt,
|
|
243
248
|
updatedAt: s.updatedAt,
|
|
244
249
|
}));
|
|
@@ -258,8 +263,11 @@ export class AgentManager {
|
|
|
258
263
|
}
|
|
259
264
|
}
|
|
260
265
|
// Export singleton
|
|
261
|
-
export let
|
|
262
|
-
export function initAgentManager(store) {
|
|
263
|
-
|
|
264
|
-
|
|
266
|
+
export let agentManagerMap = new Map();
|
|
267
|
+
export function initAgentManager(store, userId) {
|
|
268
|
+
if (agentManagerMap.has(userId)) {
|
|
269
|
+
return agentManagerMap.get(userId);
|
|
270
|
+
}
|
|
271
|
+
agentManagerMap.set(userId, new AgentManager(store, userId));
|
|
272
|
+
return agentManagerMap.get(userId);
|
|
265
273
|
}
|