@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
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
-
import { getLogger } from '@
|
|
3
|
-
import { SessionStore } from './SessionStore';
|
|
2
|
+
import { getLogger } from '@myassis/shared';
|
|
3
|
+
import { SessionStore } from './SessionStore.js';
|
|
4
4
|
import { AgentStore } from '@/services/agent/AgentStore';
|
|
5
|
+
import { authStore } from '@/stores/authStore';
|
|
5
6
|
import { toModel } from '@/services/models';
|
|
6
7
|
import { executeTool, getToolDefinitions } from '@/services/tools';
|
|
7
|
-
import { getSystemPromptAsync } from '../systemPrompt';
|
|
8
|
-
import { LLMClient, parseAruments } from '../llm/LLMClient';
|
|
8
|
+
import { getSystemPromptAsync } from '../systemPrompt.js';
|
|
9
|
+
import { LLMClient, parseAruments } from '../llm/LLMClient.js';
|
|
9
10
|
import { modelsService, settingsService } from '@/services/dataService';
|
|
10
|
-
import { MemoryManager } from '../memory/MemoryManager';
|
|
11
|
-
import { sessionManager } from './SessionManager';
|
|
11
|
+
import { MemoryManager } from '../memory/MemoryManager.js';
|
|
12
12
|
import { appConfig } from '@/config';
|
|
13
|
+
import { getSessionManager } from './SessionManager.js';
|
|
13
14
|
const logger = getLogger('Session');
|
|
14
15
|
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
15
16
|
// AgentStore 单例 - 需要通过 SessionStore 获取数据库实例
|
|
@@ -46,7 +47,6 @@ export class Session {
|
|
|
46
47
|
unreadCount = 0;
|
|
47
48
|
currentMessageId = null;
|
|
48
49
|
abortController = null;
|
|
49
|
-
toolCalls;
|
|
50
50
|
toInsertMessages;
|
|
51
51
|
constructor(data) {
|
|
52
52
|
this.id = data.id;
|
|
@@ -103,16 +103,13 @@ export class Session {
|
|
|
103
103
|
return this.messages.reduce((total, msg) => total + msg.content.length, 0);
|
|
104
104
|
}
|
|
105
105
|
// ========== Message Operations ==========
|
|
106
|
-
|
|
107
|
-
* Add user message
|
|
108
|
-
*/
|
|
109
|
-
addUserMessage(content, userMessageId, attachments) {
|
|
106
|
+
getUserMessage(content, userMessageId, attachments) {
|
|
110
107
|
// 将附件统一为 Attachment 对象格式
|
|
111
108
|
const normalizedAttachments = (attachments || []).map((att) => {
|
|
112
109
|
if (typeof att === 'string') {
|
|
113
110
|
// URL 字符串格式,转换为对象
|
|
114
111
|
const url = att;
|
|
115
|
-
const name = url.split('/').pop() || 'attachment';
|
|
112
|
+
const name = url.split('/').pop().split('?')[0] || 'attachment';
|
|
116
113
|
const ext = name.split('.').pop()?.toLowerCase() || '';
|
|
117
114
|
const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'];
|
|
118
115
|
const videoExts = ['mp4', 'avi', 'mov', 'mkv', 'webm'];
|
|
@@ -145,6 +142,13 @@ export class Session {
|
|
|
145
142
|
createdAt: Date.now(),
|
|
146
143
|
modelName: ''
|
|
147
144
|
};
|
|
145
|
+
return message;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Add user message
|
|
149
|
+
*/
|
|
150
|
+
addUserMessage(content, userMessageId, attachments) {
|
|
151
|
+
const message = this.getUserMessage(content, userMessageId, attachments);
|
|
148
152
|
this.messages.push(message);
|
|
149
153
|
this.toInsertMessages.push(message);
|
|
150
154
|
return message;
|
|
@@ -375,15 +379,27 @@ export class Session {
|
|
|
375
379
|
* Stream chat response (SSE) - 使用 ModelSelector 根据选择的模型调用
|
|
376
380
|
* 支持工具调用流程
|
|
377
381
|
*/
|
|
378
|
-
async streamChat(content, attachments = [], res, userMessageId, assistantMessageId) {
|
|
382
|
+
async streamChat(content, attachments = [], res, userMessageId, assistantMessageId, childAgent = false) {
|
|
383
|
+
// 如果正在生成,等待当前生成完成(最多等待 2 秒)
|
|
384
|
+
if (this.isGenerating) {
|
|
385
|
+
const maxWait = 2000;
|
|
386
|
+
const startTime = Date.now();
|
|
387
|
+
while (this.isGenerating && Date.now() - startTime < maxWait) {
|
|
388
|
+
await sleep(100);
|
|
389
|
+
}
|
|
390
|
+
// 超时后强制中断
|
|
391
|
+
if (this.isGenerating) {
|
|
392
|
+
this.stopGenerating();
|
|
393
|
+
}
|
|
394
|
+
}
|
|
379
395
|
// Add user message
|
|
380
396
|
this.getAbortController();
|
|
381
397
|
this.isGenerating = true;
|
|
382
|
-
|
|
383
|
-
const settings = await settingsService.get();
|
|
398
|
+
const token = authStore.get(this.userId).accessToken;
|
|
399
|
+
const settings = await settingsService.get(token);
|
|
384
400
|
const streamDelay = this.getStreamDelay(settings.streamSpeed);
|
|
385
401
|
this.currentMessageId = assistantMessageId;
|
|
386
|
-
const memoryManager = new MemoryManager(this, this.abortController.signal);
|
|
402
|
+
const memoryManager = new MemoryManager(this, this.abortController.signal, childAgent);
|
|
387
403
|
const historyMessages = await memoryManager.getHistoryMessagesAsync();
|
|
388
404
|
// SSE 辅助方法:res 为 null 时跳过写入(本地执行模式)
|
|
389
405
|
const sendSSE = (res, data) => {
|
|
@@ -433,8 +449,13 @@ export class Session {
|
|
|
433
449
|
messages.unshift({ role: 'system', content: systemPrompt, attachments: [] });
|
|
434
450
|
}
|
|
435
451
|
//插入用户消息
|
|
436
|
-
|
|
437
|
-
|
|
452
|
+
if (!childAgent) {
|
|
453
|
+
this.addUserMessage(content, userMessageId, attachments);
|
|
454
|
+
messages.push(this.messages.at(-1));
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
messages.push(this.getUserMessage(content, userMessageId, attachments));
|
|
458
|
+
}
|
|
438
459
|
let toolCall = null;
|
|
439
460
|
let modelNames = [];
|
|
440
461
|
//用于后续的消息滑动处理
|
|
@@ -450,6 +471,7 @@ export class Session {
|
|
|
450
471
|
message.reasoning_content = message.reasoning_content.substring(0, 100) + '...(内容过长已截断)';
|
|
451
472
|
}
|
|
452
473
|
};
|
|
474
|
+
const toolCalls = [];
|
|
453
475
|
// 递归处理函数(支持多轮工具调用)
|
|
454
476
|
const processModelResponse = async () => {
|
|
455
477
|
if (!this.abortController || !this.abortController.signal || this.abortController.signal.aborted) {
|
|
@@ -460,7 +482,7 @@ export class Session {
|
|
|
460
482
|
// 清理旧工具调用:只保留最近 keep 轮的完整上下文
|
|
461
483
|
{
|
|
462
484
|
const MAX_TOOL_PAIRS = keep;
|
|
463
|
-
const allToolCallItems =
|
|
485
|
+
const allToolCallItems = toolCalls.flatMap(x => x.toolCalls);
|
|
464
486
|
// 1) 清理 this.toolCalls 中超出 keep 的 output(供前端展示用)
|
|
465
487
|
allToolCallItems.forEach((item, index) => {
|
|
466
488
|
if (index < allToolCallItems.length - MAX_TOOL_PAIRS) {
|
|
@@ -498,7 +520,7 @@ export class Session {
|
|
|
498
520
|
}
|
|
499
521
|
// 获取本地工具定义
|
|
500
522
|
const tools = getToolDefinitions();
|
|
501
|
-
const models = (await modelsService.list()).data.map(x => toModel(x));
|
|
523
|
+
const models = (await modelsService.list(token)).data.map(x => toModel(x));
|
|
502
524
|
// 使用 LLMClient 进行流式调用
|
|
503
525
|
if (!this.abortController || !this.abortController.signal || this.abortController.signal.aborted) {
|
|
504
526
|
throw Error('aborted');
|
|
@@ -568,7 +590,7 @@ export class Session {
|
|
|
568
590
|
}
|
|
569
591
|
// 执行工具调用并收集结果
|
|
570
592
|
const toolResults = [];
|
|
571
|
-
|
|
593
|
+
const startToolCall = async (pendingToolCall) => {
|
|
572
594
|
// 发送工具开始执行事件
|
|
573
595
|
const toolStartEvent = {
|
|
574
596
|
type: 'tool_call_execute',
|
|
@@ -581,7 +603,7 @@ export class Session {
|
|
|
581
603
|
};
|
|
582
604
|
sendSSE(res, toolStartEvent);
|
|
583
605
|
try {
|
|
584
|
-
const result = await executeTool(pendingToolCall.toolName, parseAruments(pendingToolCall.input), this.id, this.currentMessageId);
|
|
606
|
+
const result = await executeTool(pendingToolCall.toolName, parseAruments(pendingToolCall.input), this.id, this.currentMessageId, this.userId);
|
|
585
607
|
toolResults.push({
|
|
586
608
|
id: pendingToolCall.id,
|
|
587
609
|
name: pendingToolCall.toolName,
|
|
@@ -638,8 +660,9 @@ export class Session {
|
|
|
638
660
|
};
|
|
639
661
|
sendSSE(res, errorEvent);
|
|
640
662
|
}
|
|
641
|
-
}
|
|
642
|
-
|
|
663
|
+
};
|
|
664
|
+
await Promise.all(llmResult.toolCalls.map(x => startToolCall(x)));
|
|
665
|
+
toolCalls.push(toolCall);
|
|
643
666
|
// 将工具结果添加到消息历史(格式化为 tool 角色的消息)
|
|
644
667
|
for (const result of toolResults) {
|
|
645
668
|
const toolResultMessage = {
|
|
@@ -655,7 +678,7 @@ export class Session {
|
|
|
655
678
|
messages.push(toolResultMessage);
|
|
656
679
|
}
|
|
657
680
|
// 继续递归处理(带上工具结果继续调用模型)
|
|
658
|
-
await processModelResponse();
|
|
681
|
+
return await processModelResponse();
|
|
659
682
|
}
|
|
660
683
|
else {
|
|
661
684
|
// ========== 没有工具调用,保存消息并结束 ==========
|
|
@@ -672,34 +695,43 @@ export class Session {
|
|
|
672
695
|
await sleep(streamDelay);
|
|
673
696
|
}
|
|
674
697
|
}
|
|
675
|
-
|
|
698
|
+
if (!childAgent) {
|
|
699
|
+
this.addAssistantMessage(llmResult.content || llmResult.reasoningContent, toolCalls, [...new Set(modelNames)].join(','), this.currentMessageId);
|
|
700
|
+
}
|
|
676
701
|
sendSSE(res, { type: 'complete', modelName: [...new Set(modelNames)].join(",") });
|
|
677
702
|
sendSSE(res, { type: '[DONE]' });
|
|
703
|
+
return llmResult.content;
|
|
678
704
|
}
|
|
679
705
|
};
|
|
680
706
|
try {
|
|
681
|
-
await processModelResponse();
|
|
707
|
+
const result = await processModelResponse();
|
|
708
|
+
return { success: true, data: result };
|
|
682
709
|
}
|
|
683
710
|
catch (error) {
|
|
684
711
|
logger.error('stream chat ', error);
|
|
685
|
-
if (
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
712
|
+
if (!childAgent) {
|
|
713
|
+
if (toolCalls) {
|
|
714
|
+
this.addAssistantMessage('', toolCalls, [...new Set(modelNames)].join(','), this.currentMessageId);
|
|
715
|
+
}
|
|
716
|
+
if (error.message !== 'aborted') {
|
|
717
|
+
sendSSE(res, { type: 'error', error: error.message });
|
|
718
|
+
}
|
|
690
719
|
}
|
|
720
|
+
return { success: false, error: error.message };
|
|
691
721
|
}
|
|
692
722
|
finally {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
res
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
this.
|
|
723
|
+
if (!childAgent) {
|
|
724
|
+
this.isGenerating = false;
|
|
725
|
+
this.abortController = null;
|
|
726
|
+
if (res) {
|
|
727
|
+
res.end();
|
|
728
|
+
}
|
|
729
|
+
// 非当前查看的 session,助手回复完成后增加未读计数
|
|
730
|
+
getSessionManager(this.userId).onMessageComplete(this.id);
|
|
731
|
+
// 只在非 abort 的情况下保存(abort 由 stopGenerating 负责保存)
|
|
732
|
+
if (this.currentMessageId !== null) {
|
|
733
|
+
this.saveMessage();
|
|
734
|
+
}
|
|
703
735
|
}
|
|
704
736
|
}
|
|
705
737
|
}
|
|
@@ -712,14 +744,6 @@ export class Session {
|
|
|
712
744
|
this.abortController.abort();
|
|
713
745
|
this.abortController = null;
|
|
714
746
|
}
|
|
715
|
-
// stopGenerating 负责保存中断的消息,streamChat 的 finally 不再重复保存
|
|
716
|
-
if (this.currentMessageId) {
|
|
717
|
-
if (this.toolCalls && this.toolCalls.length > 0) {
|
|
718
|
-
this.addAssistantMessage('', this.toolCalls, this.currentMessageId);
|
|
719
|
-
}
|
|
720
|
-
this.saveMessage();
|
|
721
|
-
this.currentMessageId = null;
|
|
722
|
-
}
|
|
723
747
|
}
|
|
724
748
|
/**
|
|
725
749
|
* 获取 AbortController 用于中断请求
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
-
import { getLogger } from '@
|
|
2
|
+
import { getLogger } from '@myassis/shared';
|
|
3
3
|
const logger = getLogger('SessionManager');
|
|
4
|
-
import { sessionStore } from './SessionStore';
|
|
4
|
+
import { sessionStore } from './SessionStore.js';
|
|
5
5
|
import { authStore } from '@/stores/authStore';
|
|
6
|
-
import { Session } from './Session';
|
|
6
|
+
import { Session } from './Session.js';
|
|
7
7
|
/**
|
|
8
8
|
* SessionManager - Business logic layer
|
|
9
9
|
* Manages sessions in memory
|
|
@@ -11,7 +11,9 @@ import { Session } from './Session';
|
|
|
11
11
|
export class SessionManager {
|
|
12
12
|
sessions = null;
|
|
13
13
|
initialized = false;
|
|
14
|
-
|
|
14
|
+
userId;
|
|
15
|
+
constructor(userId) {
|
|
16
|
+
this.userId = userId;
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* Initialize - Load all sessions from database on startup
|
|
@@ -40,7 +42,7 @@ export class SessionManager {
|
|
|
40
42
|
* Get current user ID
|
|
41
43
|
*/
|
|
42
44
|
getCurrentUserId() {
|
|
43
|
-
const user = authStore.getUser();
|
|
45
|
+
const user = authStore.getUser(this.userId);
|
|
44
46
|
return user ? String(user.id) : null;
|
|
45
47
|
}
|
|
46
48
|
/**
|
|
@@ -251,5 +253,10 @@ export class SessionManager {
|
|
|
251
253
|
return sessionStore.getMigrationStatus();
|
|
252
254
|
}
|
|
253
255
|
}
|
|
254
|
-
|
|
255
|
-
export
|
|
256
|
+
export let sessionManagerMap = new Map();
|
|
257
|
+
export function getSessionManager(userId) {
|
|
258
|
+
if (!sessionManagerMap.has(userId)) {
|
|
259
|
+
sessionManagerMap.set(userId, new SessionManager(userId));
|
|
260
|
+
}
|
|
261
|
+
return sessionManagerMap.get(userId);
|
|
262
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import Database from 'better-sqlite3';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import fs from 'fs';
|
|
4
|
-
import { getLogger } from '@
|
|
5
|
-
import { MigrationManager } from './MigrationManager';
|
|
4
|
+
import { getLogger } from '@myassis/shared';
|
|
5
|
+
import { MigrationManager } from './MigrationManager.js';
|
|
6
6
|
const logger = getLogger('SessionStore');
|
|
7
7
|
/**
|
|
8
8
|
* SessionStore - Data access layer
|
|
@@ -22,36 +22,10 @@ export class SessionStore {
|
|
|
22
22
|
const migrationsDir = path.join(process.cwd(), 'migrations');
|
|
23
23
|
this.migrationManager = new MigrationManager(this.db, migrationsDir);
|
|
24
24
|
this.migrationManager.migrate();
|
|
25
|
-
this.ensureColumns();
|
|
26
25
|
logger.info(`Initialized at ${dbPath}`);
|
|
27
26
|
// 注册到全局供 Session 使用
|
|
28
27
|
global.__sessionStore = this;
|
|
29
28
|
}
|
|
30
|
-
/**
|
|
31
|
-
* Ensure required columns exist
|
|
32
|
-
*/
|
|
33
|
-
ensureColumns() {
|
|
34
|
-
// Ensure agent_id column in sessions
|
|
35
|
-
const sessionTableInfo = this.db.prepare("PRAGMA table_info(sessions)").all();
|
|
36
|
-
const hasAgentId = sessionTableInfo.some(col => col.name === 'agent_id');
|
|
37
|
-
if (!hasAgentId) {
|
|
38
|
-
this.db.exec("ALTER TABLE sessions ADD COLUMN agent_id TEXT");
|
|
39
|
-
logger.info('Added agent_id column to sessions');
|
|
40
|
-
}
|
|
41
|
-
// Ensure tool_calls column in messages
|
|
42
|
-
const msgTableInfo = this.db.prepare("PRAGMA table_info(messages)").all();
|
|
43
|
-
const hasToolCalls = msgTableInfo.some(col => col.name === 'tool_calls');
|
|
44
|
-
if (!hasToolCalls) {
|
|
45
|
-
this.db.exec("ALTER TABLE messages ADD COLUMN tool_calls TEXT");
|
|
46
|
-
logger.info('Added tool_calls column to messages');
|
|
47
|
-
}
|
|
48
|
-
// Ensure feedback column in messages
|
|
49
|
-
const hasFeedback = msgTableInfo.some(col => col.name === 'feedback');
|
|
50
|
-
if (!hasFeedback) {
|
|
51
|
-
this.db.exec("ALTER TABLE messages ADD COLUMN feedback TEXT");
|
|
52
|
-
logger.info('Added feedback column to messages');
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
29
|
/**
|
|
56
30
|
* Provide transaction method
|
|
57
31
|
*/
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// 导出 SessionManager(业务逻辑层)
|
|
2
|
-
export { SessionManager,
|
|
3
|
-
export { Session } from './Session';
|
|
2
|
+
export { SessionManager, getSessionManager } from './SessionManager.js';
|
|
3
|
+
export { Session } from './Session.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { authStore } from '@/stores';
|
|
1
2
|
import os from 'os';
|
|
2
|
-
import { settingsService, skillsService } from './dataService';
|
|
3
|
-
import { getLogger } from '@
|
|
3
|
+
import { settingsService, skillsService } from './dataService.js';
|
|
4
|
+
import { getLogger } from '@myassis/shared';
|
|
4
5
|
const logger = getLogger('SystemPrompt');
|
|
5
6
|
// 预设的对话风格模板
|
|
6
7
|
export const CHAT_STYLE_TEMPLATES = [
|
|
@@ -103,8 +104,9 @@ function getInstalledSkillsPrompt(skills) {
|
|
|
103
104
|
*/
|
|
104
105
|
export async function getSystemPromptAsync(agent, customPrompt) {
|
|
105
106
|
const osInfo = getOSInfo();
|
|
106
|
-
const
|
|
107
|
-
const
|
|
107
|
+
const token = authStore.get(agent.userId).accessToken;
|
|
108
|
+
const settings = (await settingsService.get(token)).data;
|
|
109
|
+
const skills = (await skillsService.list(token)).data;
|
|
108
110
|
const skillPrompts = getInstalledSkillsPrompt(skills);
|
|
109
111
|
const chineseLocalName = LANGUAGES.filter(x => x.code === settings.language)[0]?.chineseName ?? '简体中文';
|
|
110
112
|
const date = new Date();
|
|
@@ -112,6 +114,7 @@ export async function getSystemPromptAsync(agent, customPrompt) {
|
|
|
112
114
|
【当前运行环境】:${osInfo}。
|
|
113
115
|
【当前时间】:${date.toLocaleString(settings.language)},weekday:${date.getDay()}。
|
|
114
116
|
【语言】你的回复语言严格遵循用户设备系统语言:${chineseLocalName},无论用户使用任何语言提问,你都只使用【${chineseLocalName}】进行完整回复,不要混用其他语言。
|
|
117
|
+
【尽力原则】充分分析用户需求,尽力满足,不要偷懒,不要得过且过,要诚实,不能胡编乱造。
|
|
115
118
|
【工具调用】
|
|
116
119
|
1.逐步思考,分步骤调用工具,工具调用前尽量返回content,明确当前工具调用的目的。
|
|
117
120
|
2.工具调用的参数全部采用JSON语法,调用前先验证JSON语法正确后,再回复,切记未验证JSON语法就直接回复。
|
|
@@ -128,7 +131,7 @@ export async function getSystemPromptAsync(agent, customPrompt) {
|
|
|
128
131
|
【解决问题思路】
|
|
129
132
|
1.首先分析用户需求,根据需求罗列出实施计划。如果对需求不够明确,需要把计划罗列完后,让用户确认后再执行。
|
|
130
133
|
2.按照计划分步执行
|
|
131
|
-
3
|
|
134
|
+
3.所有步骤完成后,验证结果,比如编写程序,则需要执行类型检查
|
|
132
135
|
4.验证完全通过,总结完成情况,告诉用户
|
|
133
136
|
【代码规范】
|
|
134
137
|
## 1 面向对象代码设计
|
|
@@ -141,6 +144,7 @@ export async function getSystemPromptAsync(agent, customPrompt) {
|
|
|
141
144
|
## 3 修改已经存在的代码文件
|
|
142
145
|
1)修改Bug,找到Bug后精确替换,不要调整架构
|
|
143
146
|
2)修改业务功能,删除旧的业务功能,重新添加新的,不要在旧的上面做修改,直接删除旧功能,然后添加新功能
|
|
147
|
+
【代码提交】务必类型检查通过
|
|
144
148
|
${skillPrompts}`;
|
|
145
149
|
// 如果有自定义提示词,追加
|
|
146
150
|
if (customPrompt) {
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* PushTokenStore - 用户设备推送 Token 存储
|
|
3
3
|
* 使用 SQLite 管理用户的多设备推送 Token
|
|
4
4
|
*/
|
|
5
|
-
import { getLogger } from '@
|
|
5
|
+
import { getLogger } from '@myassis/shared';
|
|
6
6
|
const logger = getLogger('PushTokenStore');
|
|
7
|
-
import { sessionStore } from '../session/SessionStore';
|
|
7
|
+
import { sessionStore } from '../session/SessionStore.js';
|
|
8
8
|
export class PushTokenStore {
|
|
9
9
|
db;
|
|
10
10
|
constructor() {
|
|
@@ -25,26 +25,8 @@ export class PushTokenStore {
|
|
|
25
25
|
UNIQUE(user_id, token)
|
|
26
26
|
)
|
|
27
27
|
`);
|
|
28
|
-
// 确保 device_id 和 device_name 列存在(向后兼容)
|
|
29
|
-
this.ensureColumns();
|
|
30
28
|
logger.info('Tables initialized');
|
|
31
29
|
}
|
|
32
|
-
ensureColumns() {
|
|
33
|
-
const tableInfo = this.db.prepare("PRAGMA table_info(push_tokens)").all();
|
|
34
|
-
const columnNames = tableInfo.map((col) => col.name);
|
|
35
|
-
if (!columnNames.includes('device_id')) {
|
|
36
|
-
this.db.exec("ALTER TABLE push_tokens ADD COLUMN device_id TEXT");
|
|
37
|
-
logger.info('Added column: device_id');
|
|
38
|
-
}
|
|
39
|
-
if (!columnNames.includes('device_name')) {
|
|
40
|
-
this.db.exec("ALTER TABLE push_tokens ADD COLUMN device_name TEXT");
|
|
41
|
-
logger.info('Added column: device_name');
|
|
42
|
-
}
|
|
43
|
-
if (!columnNames.includes('provider')) {
|
|
44
|
-
this.db.exec("ALTER TABLE push_tokens ADD COLUMN provider TEXT DEFAULT 'expo'");
|
|
45
|
-
logger.info('Added column: provider');
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
30
|
/**
|
|
49
31
|
* 添加或更新 Push Token
|
|
50
32
|
*/
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* TaskStore - Gateway 任务数据访问层
|
|
3
3
|
* 操作 SQLite 数据库,与 AgentStore/SessionStore 共享同一个数据库实例
|
|
4
4
|
*/
|
|
5
|
-
import { getLogger } from '@
|
|
6
|
-
import { sessionStore } from '../session/SessionStore';
|
|
5
|
+
import { getLogger } from '@myassis/shared';
|
|
6
|
+
import { sessionStore } from '../session/SessionStore.js';
|
|
7
7
|
const logger = getLogger('TaskStore');
|
|
8
8
|
function rowToTaskData(row) {
|
|
9
9
|
return {
|
|
@@ -59,27 +59,8 @@ export class TaskStore {
|
|
|
59
59
|
updated_at INTEGER NOT NULL
|
|
60
60
|
)
|
|
61
61
|
`);
|
|
62
|
-
// 确保必要列存在(向后兼容)
|
|
63
|
-
this.ensureColumns();
|
|
64
62
|
logger.info('Tables initialized');
|
|
65
63
|
}
|
|
66
|
-
ensureColumns() {
|
|
67
|
-
const tableInfo = this.db.prepare("PRAGMA table_info(tasks)").all();
|
|
68
|
-
const columnNames = tableInfo.map((col) => col.name);
|
|
69
|
-
const requiredColumns = [
|
|
70
|
-
{ name: 'platform_apply', sql: 'ALTER TABLE tasks ADD COLUMN platform_apply TEXT' },
|
|
71
|
-
{ name: 'push_token', sql: 'ALTER TABLE tasks ADD COLUMN push_token TEXT' },
|
|
72
|
-
{ name: 'recurrence_rule', sql: 'ALTER TABLE tasks ADD COLUMN recurrence_rule TEXT' },
|
|
73
|
-
{ name: 'interval_value', sql: 'ALTER TABLE tasks ADD COLUMN interval_value INTEGER' },
|
|
74
|
-
{ name: 'interval_unit', sql: 'ALTER TABLE tasks ADD COLUMN interval_unit TEXT' },
|
|
75
|
-
];
|
|
76
|
-
for (const col of requiredColumns) {
|
|
77
|
-
if (!columnNames.includes(col.name)) {
|
|
78
|
-
this.db.exec(col.sql);
|
|
79
|
-
logger.info(`Added column: ${col.name}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
64
|
// ========== Task Operations ==========
|
|
84
65
|
insert(task) {
|
|
85
66
|
this.db.prepare(`
|