sema-core 2.0.0 → 2.0.1
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/core/Conversation.d.ts.map +1 -1
- package/dist/core/Conversation.js +22 -22
- package/dist/core/Conversation.js.map +1 -1
- package/dist/core/RunTools.d.ts.map +1 -1
- package/dist/core/RunTools.js +6 -6
- package/dist/core/RunTools.js.map +1 -1
- package/dist/core/SemaCore.d.ts +20 -24
- package/dist/core/SemaCore.d.ts.map +1 -1
- package/dist/core/SemaCore.js +50 -40
- package/dist/core/SemaCore.js.map +1 -1
- package/dist/core/SemaEngine.d.ts +24 -15
- package/dist/core/SemaEngine.d.ts.map +1 -1
- package/dist/core/SemaEngine.js +116 -206
- package/dist/core/SemaEngine.js.map +1 -1
- package/dist/core/SemaSession.d.ts +43 -0
- package/dist/core/SemaSession.d.ts.map +1 -0
- package/dist/core/SemaSession.js +72 -0
- package/dist/core/SemaSession.js.map +1 -0
- package/dist/core/SessionPool.d.ts +32 -0
- package/dist/core/SessionPool.d.ts.map +1 -0
- package/dist/core/SessionPool.js +89 -0
- package/dist/core/SessionPool.js.map +1 -0
- package/dist/events/EventSystem.d.ts +40 -12
- package/dist/events/EventSystem.d.ts.map +1 -1
- package/dist/events/EventSystem.js +83 -25
- package/dist/events/EventSystem.js.map +1 -1
- package/dist/events/types.d.ts +11 -5
- package/dist/events/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/manager/CronManager.d.ts +16 -5
- package/dist/manager/CronManager.d.ts.map +1 -1
- package/dist/manager/CronManager.js +46 -19
- package/dist/manager/CronManager.js.map +1 -1
- package/dist/manager/PermissionManager.d.ts +2 -2
- package/dist/manager/PermissionManager.d.ts.map +1 -1
- package/dist/manager/PermissionManager.js +18 -19
- package/dist/manager/PermissionManager.js.map +1 -1
- package/dist/manager/StateManager.d.ts +63 -134
- package/dist/manager/StateManager.d.ts.map +1 -1
- package/dist/manager/StateManager.js +140 -197
- package/dist/manager/StateManager.js.map +1 -1
- package/dist/manager/TaskManager.d.ts +28 -10
- package/dist/manager/TaskManager.d.ts.map +1 -1
- package/dist/manager/TaskManager.js +100 -39
- package/dist/manager/TaskManager.js.map +1 -1
- package/dist/prompt/design/design.d.ts.map +1 -1
- package/dist/prompt/design/design.js +15 -9
- package/dist/prompt/design/design.js.map +1 -1
- package/dist/prompt/system.d.ts +1 -1
- package/dist/prompt/system.d.ts.map +1 -1
- package/dist/prompt/system.js +5 -2
- package/dist/prompt/system.js.map +1 -1
- package/dist/services/agents/genSystemPrompt.d.ts +1 -1
- package/dist/services/agents/genSystemPrompt.js +1 -1
- package/dist/services/api/adapt/anthropic.d.ts +1 -1
- package/dist/services/api/adapt/anthropic.d.ts.map +1 -1
- package/dist/services/api/adapt/anthropic.js +7 -7
- package/dist/services/api/adapt/anthropic.js.map +1 -1
- package/dist/services/api/adapt/openai.d.ts +1 -1
- package/dist/services/api/adapt/openai.d.ts.map +1 -1
- package/dist/services/api/adapt/openai.js +7 -7
- package/dist/services/api/adapt/openai.js.map +1 -1
- package/dist/services/api/adapt/util.d.ts +2 -2
- package/dist/services/api/adapt/util.d.ts.map +1 -1
- package/dist/services/api/adapt/util.js +4 -4
- package/dist/services/api/adapt/util.js.map +1 -1
- package/dist/services/api/cache.d.ts +1 -1
- package/dist/services/api/cache.d.ts.map +1 -1
- package/dist/services/api/cache.js +7 -7
- package/dist/services/api/cache.js.map +1 -1
- package/dist/services/api/queryLLM.d.ts +14 -1
- package/dist/services/api/queryLLM.d.ts.map +1 -1
- package/dist/services/api/queryLLM.js +17 -17
- package/dist/services/api/queryLLM.js.map +1 -1
- package/dist/services/commands/runCommand.d.ts +1 -1
- package/dist/services/commands/runCommand.d.ts.map +1 -1
- package/dist/services/commands/runCommand.js +26 -26
- package/dist/services/commands/runCommand.js.map +1 -1
- package/dist/tools/CreateCron.d.ts +1 -1
- package/dist/tools/CreateCron.d.ts.map +1 -1
- package/dist/tools/CreateCron.js +2 -2
- package/dist/tools/CreateCron.js.map +1 -1
- package/dist/tools/CreateTodo.js +1 -1
- package/dist/tools/CreateTodo.js.map +1 -1
- package/dist/tools/EditNotebook.js +2 -2
- package/dist/tools/EditNotebook.js.map +1 -1
- package/dist/tools/FetchUrl.js +1 -1
- package/dist/tools/FetchUrl.js.map +1 -1
- package/dist/tools/GetTodo.js +1 -1
- package/dist/tools/GetTodo.js.map +1 -1
- package/dist/tools/ListTodos.js +1 -1
- package/dist/tools/ListTodos.js.map +1 -1
- package/dist/tools/PatchFile.js +2 -2
- package/dist/tools/PatchFile.js.map +1 -1
- package/dist/tools/PeekBgJob.d.ts.map +1 -1
- package/dist/tools/PeekBgJob.js +4 -3
- package/dist/tools/PeekBgJob.js.map +1 -1
- package/dist/tools/PickOption.js +3 -3
- package/dist/tools/PickOption.js.map +1 -1
- package/dist/tools/PlanToAgent.d.ts.map +1 -1
- package/dist/tools/PlanToAgent.js +10 -11
- package/dist/tools/PlanToAgent.js.map +1 -1
- package/dist/tools/RunShell.js +1 -1
- package/dist/tools/RunShell.js.map +1 -1
- package/dist/tools/SubAgent.d.ts.map +1 -1
- package/dist/tools/SubAgent.js +20 -17
- package/dist/tools/SubAgent.js.map +1 -1
- package/dist/tools/UpdateTodo.js +1 -1
- package/dist/tools/UpdateTodo.js.map +1 -1
- package/dist/tools/ViewFile.js +1 -1
- package/dist/tools/ViewFile.js.map +1 -1
- package/dist/tools/WriteFile.js +2 -2
- package/dist/tools/WriteFile.js.map +1 -1
- package/dist/tools/base/tools.d.ts +2 -2
- package/dist/tools/base/tools.d.ts.map +1 -1
- package/dist/tools/base/tools.js +10 -4
- package/dist/tools/base/tools.js.map +1 -1
- package/dist/types/agent.d.ts +2 -0
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/cron.d.ts +1 -0
- package/dist/types/cron.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/session.d.ts +18 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +3 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/task.d.ts +2 -0
- package/dist/types/task.d.ts.map +1 -1
- package/dist/util/compact.d.ts +2 -2
- package/dist/util/compact.d.ts.map +1 -1
- package/dist/util/compact.js +6 -7
- package/dist/util/compact.js.map +1 -1
- package/dist/util/file.d.ts +2 -0
- package/dist/util/file.d.ts.map +1 -1
- package/dist/util/file.js +11 -0
- package/dist/util/file.js.map +1 -1
- package/dist/util/fileReference.d.ts.map +1 -1
- package/dist/util/fileReference.js +4 -0
- package/dist/util/fileReference.js.map +1 -1
- package/dist/util/logLLM.d.ts +3 -3
- package/dist/util/logLLM.d.ts.map +1 -1
- package/dist/util/logLLM.js +10 -15
- package/dist/util/logLLM.js.map +1 -1
- package/dist/util/message.d.ts +1 -1
- package/dist/util/message.d.ts.map +1 -1
- package/dist/util/message.js +6 -6
- package/dist/util/message.js.map +1 -1
- package/dist/util/notifyRegistry.d.ts +18 -0
- package/dist/util/notifyRegistry.d.ts.map +1 -0
- package/dist/util/notifyRegistry.js +28 -0
- package/dist/util/notifyRegistry.js.map +1 -0
- package/dist/util/process.d.ts.map +1 -1
- package/dist/util/process.js +3 -4
- package/dist/util/process.js.map +1 -1
- package/dist/util/quickchat.d.ts +1 -1
- package/dist/util/quickchat.d.ts.map +1 -1
- package/dist/util/quickchat.js +12 -10
- package/dist/util/quickchat.js.map +1 -1
- package/dist/util/session.d.ts +4 -0
- package/dist/util/session.d.ts.map +1 -1
- package/dist/util/session.js +8 -1
- package/dist/util/session.js.map +1 -1
- package/dist/util/shell.d.ts +2 -0
- package/dist/util/shell.d.ts.map +1 -1
- package/dist/util/shell.js +20 -1
- package/dist/util/shell.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SessionEventBus } from '../events/EventSystem';
|
|
2
2
|
import type { AgentMode } from '../types';
|
|
3
|
+
import type { CreateSessionOptions } from '../types/session';
|
|
3
4
|
/**
|
|
4
|
-
* Sema 引擎 -
|
|
5
|
+
* Sema 引擎 - 单个会话的核心业务逻辑
|
|
6
|
+
* 每个会话一个实例,绑定固定的 sessionId
|
|
5
7
|
*/
|
|
6
8
|
export declare class SemaEngine {
|
|
7
|
-
|
|
9
|
+
readonly sessionId: string;
|
|
10
|
+
private readonly bus;
|
|
11
|
+
/** 当前正在执行的 processQuery Promise(用于 dispose 时等待) */
|
|
8
12
|
private currentProcessingPromise;
|
|
9
|
-
private
|
|
13
|
+
private readonly runtime;
|
|
10
14
|
emit: <T>(event: string, data: T) => boolean;
|
|
11
|
-
on: <T>(event: string, listener: (data: T) => void) =>
|
|
12
|
-
once: <T>(event: string, listener: (data: T) => void) =>
|
|
13
|
-
off: <T>(event: string, listener: (data: T) => void) =>
|
|
14
|
-
constructor();
|
|
15
|
+
on: <T>(event: string, listener: (data: T) => void) => SessionEventBus;
|
|
16
|
+
once: <T>(event: string, listener: (data: T) => void) => SessionEventBus;
|
|
17
|
+
off: <T>(event: string, listener: (data: T) => void) => SessionEventBus;
|
|
18
|
+
constructor(sessionId: string, bus: SessionEventBus);
|
|
15
19
|
/**
|
|
16
|
-
*
|
|
20
|
+
* 初始化会话:加载历史、发送 session:ready
|
|
17
21
|
*/
|
|
18
|
-
createSession(
|
|
22
|
+
createSession(opts?: CreateSessionOptions): Promise<void>;
|
|
19
23
|
/**
|
|
20
24
|
* 处理用户输入
|
|
21
25
|
* 如果当前正在处理中,将输入加入队列等待
|
|
@@ -31,22 +35,27 @@ export declare class SemaEngine {
|
|
|
31
35
|
private processQuery;
|
|
32
36
|
/**
|
|
33
37
|
* 中止当前正在进行的请求(仅处理 AbortController)
|
|
34
|
-
* 不更新状态,用于内部调用
|
|
35
38
|
*/
|
|
36
39
|
private abortCurrentRequest;
|
|
37
40
|
/**
|
|
38
41
|
* 中断当前会话
|
|
39
|
-
* 仅中断当前正在执行的请求,队列中的待处理输入不受影响
|
|
40
|
-
* 由 processQuery 的 finally 决定是否继续消费队列或设为 idle
|
|
41
42
|
*/
|
|
42
43
|
interruptSession(): void;
|
|
43
44
|
/**
|
|
44
|
-
* 更新 Agent
|
|
45
|
+
* 更新 Agent 模式(会话级)
|
|
45
46
|
*/
|
|
46
47
|
updateAgentMode(mode: AgentMode): void;
|
|
48
|
+
/**
|
|
49
|
+
* 更新自动编辑状态
|
|
50
|
+
*/
|
|
51
|
+
updateAutoEdit(enable: boolean): void;
|
|
47
52
|
private initialize;
|
|
48
53
|
/**
|
|
49
|
-
*
|
|
54
|
+
* 等待当前处理结束(最多 timeoutMs 毫秒)
|
|
55
|
+
*/
|
|
56
|
+
waitForIdle(timeoutMs?: number): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* 清理本会话资源(会话级,不触碰全局单例)
|
|
50
59
|
*/
|
|
51
60
|
dispose(): void;
|
|
52
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SemaEngine.d.ts","sourceRoot":"","sources":["../../src/core/SemaEngine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SemaEngine.d.ts","sourceRoot":"","sources":["../../src/core/SemaEngine.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAYxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;;GAGG;AACH,qBAAa,UAAU;aAaH,SAAS,EAAE,MAAM;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG;IAbtB,mDAAmD;IACnD,OAAO,CAAC,wBAAwB,CAA6B;IAE7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IAGzC,IAAI,GAAI,CAAC,EAAE,OAAO,MAAM,EAAE,MAAM,CAAC,aAAgC;IACjE,EAAE,GAAI,CAAC,EAAE,OAAO,MAAM,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,qBAAkC;IACrF,IAAI,GAAI,CAAC,EAAE,OAAO,MAAM,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,qBAAoC;IACzF,GAAG,GAAI,CAAC,EAAE,OAAO,MAAM,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,qBAAmC;gBAGrE,SAAS,EAAE,MAAM,EAChB,GAAG,EAAE,eAAe;IAevC;;OAEG;IACG,aAAa,CAAC,IAAI,GAAE,oBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsDnE;;;OAGG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IA+C/E;;OAEG;IACH,OAAO,CAAC,UAAU;IAqClB;;OAEG;YACW,YAAY;IAuJ1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAIxB;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAetC;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;YAKvB,UAAU;IA8BxB;;OAEG;IACG,WAAW,CAAC,SAAS,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnD;;OAEG;IACH,OAAO,IAAI,IAAI;CAQhB"}
|
package/dist/core/SemaEngine.js
CHANGED
|
@@ -1,42 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.SemaEngine = void 0;
|
|
37
|
-
const crypto = __importStar(require("crypto"));
|
|
38
4
|
const log_1 = require("../util/log");
|
|
39
|
-
const session_1 = require("../util/session");
|
|
40
5
|
const tokens_1 = require("../util/tokens");
|
|
41
6
|
const history_1 = require("../util/history");
|
|
42
7
|
const topic_1 = require("../util/topic");
|
|
@@ -47,138 +12,103 @@ const inputQueue_1 = require("../util/inputQueue");
|
|
|
47
12
|
const genSystemPrompt_1 = require("../services/agents/genSystemPrompt");
|
|
48
13
|
const ConfManager_1 = require("../manager/ConfManager");
|
|
49
14
|
const ModelManager_1 = require("../manager/ModelManager");
|
|
50
|
-
const EventSystem_1 = require("../events/EventSystem");
|
|
51
15
|
const errors_1 = require("../types/errors");
|
|
52
16
|
const Conversation_1 = require("./Conversation");
|
|
53
17
|
const StateManager_1 = require("../manager/StateManager");
|
|
18
|
+
const session_1 = require("../util/session");
|
|
54
19
|
const runCommand_1 = require("../services/commands/runCommand");
|
|
55
20
|
const TaskManager_1 = require("../manager/TaskManager");
|
|
56
21
|
const CronManager_1 = require("../manager/CronManager");
|
|
57
22
|
const quickchat_1 = require("../util/quickchat");
|
|
58
23
|
const tool_1 = require("../prompt/tool");
|
|
59
24
|
/**
|
|
60
|
-
* Sema 引擎 -
|
|
25
|
+
* Sema 引擎 - 单个会话的核心业务逻辑
|
|
26
|
+
* 每个会话一个实例,绑定固定的 sessionId
|
|
61
27
|
*/
|
|
62
28
|
class SemaEngine {
|
|
63
|
-
constructor() {
|
|
64
|
-
|
|
65
|
-
this.
|
|
66
|
-
|
|
29
|
+
constructor(sessionId, bus) {
|
|
30
|
+
this.sessionId = sessionId;
|
|
31
|
+
this.bus = bus;
|
|
32
|
+
/** 当前正在执行的 processQuery Promise(用于 dispose 时等待) */
|
|
67
33
|
this.currentProcessingPromise = null;
|
|
68
|
-
//
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
73
|
-
this.
|
|
74
|
-
//
|
|
75
|
-
(0, TaskManager_1.getTaskManager)().setNotifyCallback((msg) => {
|
|
34
|
+
// 公共事件接口(会话级,自动按 sessionId 路由)
|
|
35
|
+
this.emit = (event, data) => this.bus.emit(event, data);
|
|
36
|
+
this.on = (event, listener) => this.bus.on(event, listener);
|
|
37
|
+
this.once = (event, listener) => this.bus.once(event, listener);
|
|
38
|
+
this.off = (event, listener) => this.bus.off(event, listener);
|
|
39
|
+
this.runtime = (0, StateManager_1.getStateManager)().session(sessionId);
|
|
40
|
+
// 注入后台任务通知回调:完成后将通知注入本会话输入队列
|
|
41
|
+
(0, TaskManager_1.getTaskManager)().setNotifyCallback(sessionId, (msg) => {
|
|
76
42
|
this.processUserInput(msg, undefined, true);
|
|
77
43
|
});
|
|
78
44
|
// 注入 Cron 定时任务通知回调
|
|
79
|
-
(0, CronManager_1.getCronManager)().setNotifyCallback((msg) => {
|
|
45
|
+
(0, CronManager_1.getCronManager)().setNotifyCallback(sessionId, (msg) => {
|
|
80
46
|
this.processUserInput(msg, undefined, true);
|
|
81
47
|
});
|
|
82
48
|
}
|
|
83
49
|
/**
|
|
84
|
-
*
|
|
50
|
+
* 初始化会话:加载历史、发送 session:ready
|
|
85
51
|
*/
|
|
86
|
-
async createSession(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// 如果当前正在处理,中断并等待旧会话结束,然后 fall through 到下方统一创建新会话
|
|
91
|
-
if (mainAgentState.getCurrentState() === 'processing') {
|
|
92
|
-
this.pendingSession = finalSessionId; // 直接覆盖,只保留最新的会话
|
|
93
|
-
this.abortCurrentRequest();
|
|
94
|
-
(0, log_1.logInfo)(`会话正在处理中,中断并等待: ${finalSessionId}`);
|
|
95
|
-
// 等待旧会话处理完成(最多等待10秒)
|
|
96
|
-
if (this.currentProcessingPromise) {
|
|
97
|
-
const waitTimeoutSecond = 10;
|
|
98
|
-
(0, log_1.logInfo)(`等待旧会话结束...`);
|
|
99
|
-
try {
|
|
100
|
-
await Promise.race([
|
|
101
|
-
this.currentProcessingPromise,
|
|
102
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error('等待超时')), 1000 * waitTimeoutSecond))
|
|
103
|
-
]);
|
|
104
|
-
(0, log_1.logInfo)(`旧会话已结束`);
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
(0, log_1.logWarn)(`等待旧会话结束时出错: ${error instanceof Error ? error.message : String(error)}`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
// 被更新的 createSession 调用覆盖(快速连续新建场景),放弃当前创建
|
|
111
|
-
if (this.pendingSession !== finalSessionId) {
|
|
112
|
-
(0, log_1.logInfo)(`会话创建被覆盖,放弃: ${finalSessionId}`);
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
// 创建新会话,清空所有待处理状态
|
|
117
|
-
this.abortCurrentRequest();
|
|
118
|
-
stateManager.clearPendingUserInputs(); // 清空输入队列,因为这些输入属于旧会话
|
|
119
|
-
this.pendingSession = null;
|
|
120
|
-
// 关闭所有后台进程
|
|
121
|
-
(0, TaskManager_1.getTaskManager)().dispose();
|
|
122
|
-
// 清空所有状态
|
|
123
|
-
stateManager.clearAllState();
|
|
124
|
-
// 初始化新会话
|
|
125
|
-
await this.initialize(finalSessionId);
|
|
126
|
-
// 清空非持久化的定时任务,持久化任务保留
|
|
127
|
-
(0, CronManager_1.getCronManager)().clearNonDurableTasks();
|
|
52
|
+
async createSession(opts = {}) {
|
|
53
|
+
// 初始化系统配置与模型检查
|
|
54
|
+
await this.initialize();
|
|
55
|
+
// 会话级配置:Agent 模式
|
|
128
56
|
const coreConfig = (0, ConfManager_1.getConfManager)().getCoreConfig();
|
|
57
|
+
this.runtime.agentMode = opts.agentMode || coreConfig?.agentMode || 'Agent';
|
|
58
|
+
// 构建会话级系统提示快照:整个会话不再变化(env/gitStatus 取会话创建时的快照)
|
|
59
|
+
this.runtime.setSystemPromptContent(await (0, genSystemPrompt_1.formatSystemPrompt)());
|
|
60
|
+
const mainAgentState = this.runtime.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
129
61
|
const workingDir = coreConfig?.workingDir;
|
|
130
|
-
|
|
131
|
-
const historyData = await (0, history_1.loadHistory)(
|
|
132
|
-
(0, log_1.logInfo)(`会话CoreConfig: ${JSON.stringify(coreConfig, null, 2)}`);
|
|
62
|
+
const historyId = opts.sessionId;
|
|
63
|
+
const historyData = await (0, history_1.loadHistory)(historyId, workingDir);
|
|
133
64
|
// 将加载的消息历史、todos 和 readFileTimestamps 设置到主代理状态
|
|
134
65
|
// 初始化时跳过自动保存,避免把刚读取的数据重复写回文件
|
|
135
66
|
mainAgentState.setMessageHistory(historyData.messages, true);
|
|
136
67
|
mainAgentState.setTodos(historyData.todos);
|
|
137
68
|
if (historyData.todoTasks && historyData.todoTasks.length > 0) {
|
|
138
|
-
|
|
139
|
-
stateManager.restoreTodoTasks(historyData.todoTasks);
|
|
69
|
+
this.runtime.restoreTodoTasks(historyData.todoTasks);
|
|
140
70
|
}
|
|
141
71
|
else if (historyData.todos && historyData.todos.length > 0) {
|
|
142
|
-
|
|
143
|
-
stateManager.restoreTodoTasksFromLegacy(historyData.todos);
|
|
72
|
+
this.runtime.restoreTodoTasksFromLegacy(historyData.todos);
|
|
144
73
|
}
|
|
145
74
|
if (historyData.readFileTimestamps) {
|
|
146
75
|
mainAgentState.setReadFileTimestamps(historyData.readFileTimestamps);
|
|
147
76
|
}
|
|
148
|
-
// 使用全局配置获取工作路径
|
|
149
77
|
const projectConfig = (0, ConfManager_1.getConfManager)().getProjectConfig();
|
|
150
78
|
const projectInputHistory = projectConfig?.history || [];
|
|
151
|
-
// 获取tokens
|
|
152
79
|
const usage = (0, tokens_1.getTokens)(mainAgentState.getMessageHistory());
|
|
153
80
|
const sessionData = {
|
|
154
81
|
pid: process.pid,
|
|
155
82
|
workingDir: coreConfig?.workingDir,
|
|
156
|
-
sessionId:
|
|
157
|
-
historyLoaded: !!
|
|
83
|
+
sessionId: this.sessionId,
|
|
84
|
+
historyLoaded: !!historyId,
|
|
158
85
|
projectInputHistory: projectInputHistory,
|
|
159
86
|
usage: usage,
|
|
160
87
|
todos: mainAgentState.getTodos(),
|
|
161
88
|
readFileTimestamps: historyData.readFileTimestamps || {}
|
|
162
89
|
};
|
|
163
|
-
(0, log_1.logInfo)(`新会话创建完成,sessionId: ${
|
|
164
|
-
|
|
165
|
-
|
|
90
|
+
(0, log_1.logInfo)(`新会话创建完成,sessionId: ${this.sessionId}`);
|
|
91
|
+
// 延迟一拍发送 session:ready:调用方需先拿到 createSession 返回的 SemaSession
|
|
92
|
+
// 并在其上注册监听器,再收到首个事件
|
|
93
|
+
setImmediate(() => {
|
|
94
|
+
this.emit('session:ready', sessionData);
|
|
95
|
+
mainAgentState.updateState('idle');
|
|
96
|
+
});
|
|
166
97
|
}
|
|
167
98
|
/**
|
|
168
99
|
* 处理用户输入
|
|
169
100
|
* 如果当前正在处理中,将输入加入队列等待
|
|
170
101
|
*/
|
|
171
102
|
processUserInput(input, originalInput, silent) {
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
const inputId = crypto.randomUUID().replace(/-/g, '').substring(0, 8);
|
|
103
|
+
const mainAgentState = this.runtime.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
104
|
+
const inputId = (0, session_1.generateShortId)();
|
|
175
105
|
const trimmedInput = input.trim();
|
|
176
106
|
// quickchat 旁路:不影响状态和队列,异步处理后直接返回
|
|
177
107
|
if (trimmedInput === '/quickchat' || trimmedInput.startsWith('/quickchat ')) {
|
|
178
|
-
const question = trimmedInput.startsWith('/quickchat ') ? trimmedInput.slice(
|
|
108
|
+
const question = trimmedInput.startsWith('/quickchat ') ? trimmedInput.slice('/quickchat '.length).trim() : '';
|
|
179
109
|
(0, ConfManager_1.getConfManager)().saveUserInputToHistory(originalInput || trimmedInput);
|
|
180
110
|
if (question) {
|
|
181
|
-
(0, quickchat_1.handlequickchat)(question).catch(err => (0, log_1.logWarn)(`[quickchat] 未捕获异常: ${err instanceof Error ? err.message : String(err)}`));
|
|
111
|
+
(0, quickchat_1.handlequickchat)(question, this.sessionId).catch(err => (0, log_1.logWarn)(`[quickchat] 未捕获异常: ${err instanceof Error ? err.message : String(err)}`));
|
|
182
112
|
}
|
|
183
113
|
else {
|
|
184
114
|
this.emit('quickchat:response', { question: '', content: '' });
|
|
@@ -187,8 +117,8 @@ class SemaEngine {
|
|
|
187
117
|
}
|
|
188
118
|
if (mainAgentState.getCurrentState() === 'processing') {
|
|
189
119
|
const type = trimmedInput.startsWith('/') ? 'command' : 'inject';
|
|
190
|
-
|
|
191
|
-
(0, log_1.logInfo)(`输入已入队(${type}),队列长度: ${
|
|
120
|
+
this.runtime.addPendingUserInput({ inputId, input: trimmedInput, originalInput, silent, type });
|
|
121
|
+
(0, log_1.logInfo)(`输入已入队(${type}),队列长度: ${this.runtime.getPendingUserInputsLength()}`);
|
|
192
122
|
if (!silent) {
|
|
193
123
|
this.emit('input:received', {
|
|
194
124
|
inputId,
|
|
@@ -196,7 +126,7 @@ class SemaEngine {
|
|
|
196
126
|
originalInput,
|
|
197
127
|
queued: true,
|
|
198
128
|
inject: type === 'inject',
|
|
199
|
-
queueLength:
|
|
129
|
+
queueLength: this.runtime.getPendingUserInputsLength(),
|
|
200
130
|
});
|
|
201
131
|
}
|
|
202
132
|
return;
|
|
@@ -217,21 +147,19 @@ class SemaEngine {
|
|
|
217
147
|
* 启动一次查询(构建上下文并调用 processQuery)
|
|
218
148
|
*/
|
|
219
149
|
startQuery(inputs) {
|
|
220
|
-
const
|
|
221
|
-
const mainAgentState = stateManager.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
150
|
+
const mainAgentState = this.runtime.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
222
151
|
mainAgentState.updateState('processing');
|
|
223
152
|
(0, log_1.logInfo)(`用户输入(${inputs.length}条): ${inputs.map(i => i.input).join(' | ')}`);
|
|
224
153
|
// 创建新的 AbortController 用于此次处理
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const agentMode = coreConfig?.agentMode || 'Agent';
|
|
229
|
-
// 获取工具集
|
|
154
|
+
this.runtime.currentAbortController = new AbortController();
|
|
155
|
+
const agentMode = this.runtime.agentMode;
|
|
156
|
+
// 获取工具集(按核心级 useTools 黑名单过滤)
|
|
230
157
|
const tools = (0, tools_1.getAvailableTools)();
|
|
231
158
|
// 构建主代理上下文
|
|
232
159
|
const agentContext = {
|
|
160
|
+
sessionId: this.sessionId,
|
|
233
161
|
agentId: StateManager_1.MAIN_AGENT_ID,
|
|
234
|
-
abortController:
|
|
162
|
+
abortController: this.runtime.currentAbortController,
|
|
235
163
|
tools,
|
|
236
164
|
model: 'main',
|
|
237
165
|
};
|
|
@@ -239,14 +167,12 @@ class SemaEngine {
|
|
|
239
167
|
this.currentProcessingPromise = this.processQuery(inputs, agentContext, agentMode)
|
|
240
168
|
.catch(error => {
|
|
241
169
|
(0, log_1.logWarn)(`processQuery 未捕获异常: ${error instanceof Error ? error.message : String(error)}`);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
stateManager.currentAbortController = null;
|
|
170
|
+
if (this.runtime.currentAbortController === agentContext.abortController) {
|
|
171
|
+
this.runtime.currentAbortController = null;
|
|
245
172
|
}
|
|
246
173
|
mainAgentState.updateState('idle');
|
|
247
174
|
})
|
|
248
175
|
.finally(() => {
|
|
249
|
-
// 清空 Promise 引用
|
|
250
176
|
this.currentProcessingPromise = null;
|
|
251
177
|
});
|
|
252
178
|
}
|
|
@@ -254,9 +180,7 @@ class SemaEngine {
|
|
|
254
180
|
* 处理查询逻辑
|
|
255
181
|
*/
|
|
256
182
|
async processQuery(inputs, agentContext, agentMode) {
|
|
257
|
-
|
|
258
|
-
const stateManager = (0, StateManager_1.getStateManager)();
|
|
259
|
-
const mainAgentState = stateManager.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
183
|
+
const mainAgentState = this.runtime.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
260
184
|
// 为每条输入发送独立的 input:processing 事件(静默输入跳过)
|
|
261
185
|
for (const item of inputs) {
|
|
262
186
|
if (!item.silent) {
|
|
@@ -274,12 +198,11 @@ class SemaEngine {
|
|
|
274
198
|
const allBlocks = [];
|
|
275
199
|
let combinedProcessedText = '';
|
|
276
200
|
for (const item of inputs) {
|
|
277
|
-
// abort 早期检查:避免会话切换后继续执行无用操作
|
|
278
201
|
if (agentContext.abortController.signal.aborted) {
|
|
279
202
|
(0, log_1.logInfo)('processQuery: abort detected during handleCommand loop, skipping remaining');
|
|
280
203
|
return;
|
|
281
204
|
}
|
|
282
|
-
const commandResult = await (0, runCommand_1.handleCommand)(item.input);
|
|
205
|
+
const commandResult = await (0, runCommand_1.handleCommand)(item.input, this.sessionId);
|
|
283
206
|
if (commandResult === null) {
|
|
284
207
|
// 系统命令已处理(如 /compact, /clear),跳过
|
|
285
208
|
continue;
|
|
@@ -287,23 +210,20 @@ class SemaEngine {
|
|
|
287
210
|
combinedProcessedText += (combinedProcessedText ? '\n' : '') + commandResult.processedText;
|
|
288
211
|
allBlocks.push(...commandResult.blocks);
|
|
289
212
|
}
|
|
290
|
-
// 如果所有输入都是系统命令(返回 null),直接结束
|
|
291
213
|
if (allBlocks.length === 0) {
|
|
292
214
|
return;
|
|
293
215
|
}
|
|
294
|
-
// abort 早期检查
|
|
295
216
|
if (agentContext.abortController.signal.aborted) {
|
|
296
217
|
(0, log_1.logInfo)('processQuery: abort detected after handleCommand, skipping remaining');
|
|
297
218
|
return;
|
|
298
219
|
}
|
|
299
|
-
//
|
|
300
|
-
// 跳过条件:全部输入均为 silent(来自 cron / 后台任务通知等系统注入),不应改变会话话题
|
|
220
|
+
// 后台异步执行话题检测,不阻塞主流程
|
|
301
221
|
const allSilent = inputs.every(i => i.silent);
|
|
302
222
|
const allOriginalTexts = inputs.map(i => i.originalInput || i.input).join('\n');
|
|
303
223
|
if (!allSilent && !(0, ConfManager_1.getConfManager)().getCoreConfig()?.disableTopicDetection) {
|
|
304
|
-
(0, topic_1.detectTopicInBackground)(allOriginalTexts,
|
|
224
|
+
(0, topic_1.detectTopicInBackground)(allOriginalTexts, this.runtime.currentAbortController, (result) => this.emit('topic:update', result));
|
|
305
225
|
}
|
|
306
|
-
//
|
|
226
|
+
// 处理文件引用以获取补充信息
|
|
307
227
|
const fileReferencesResult = await (0, fileReference_1.processFileReferences)(combinedProcessedText, agentContext);
|
|
308
228
|
(0, log_1.logInfo)(`返回文件引用信息: ${JSON.stringify(fileReferencesResult.supplementaryInfo, null, 2)}`);
|
|
309
229
|
if (fileReferencesResult.supplementaryInfo.length > 0) {
|
|
@@ -311,25 +231,24 @@ class SemaEngine {
|
|
|
311
231
|
references: fileReferencesResult.supplementaryInfo
|
|
312
232
|
});
|
|
313
233
|
}
|
|
314
|
-
// abort 早期检查
|
|
315
234
|
if (agentContext.abortController.signal.aborted) {
|
|
316
235
|
(0, log_1.logInfo)('processQuery: abort detected after processFileReferences, skipping remaining');
|
|
317
236
|
return;
|
|
318
237
|
}
|
|
319
|
-
// 1
|
|
238
|
+
// 1、系统提示:复用会话级快照(整会话不变);缺失时兜底构建一次
|
|
320
239
|
const hasSkillTool = agentContext.tools.some(tool => tool.name === tool_1.TOOL_NAME_SKILL);
|
|
321
|
-
|
|
240
|
+
let systemPromptContent = this.runtime.getSystemPromptContent();
|
|
241
|
+
if (!systemPromptContent) {
|
|
242
|
+
systemPromptContent = await (0, genSystemPrompt_1.formatSystemPrompt)();
|
|
243
|
+
this.runtime.setSystemPromptContent(systemPromptContent);
|
|
244
|
+
}
|
|
322
245
|
// 2、构建用户消息内容
|
|
323
|
-
// 2.1 获取消息历史
|
|
324
246
|
const messageHistory = mainAgentState.getMessageHistory();
|
|
325
|
-
|
|
326
|
-
// 构建reminder信息 文件引用 每次输入均添加,首次查询添加 todos\rules,Plan 模式添加 Plan 信息
|
|
327
|
-
const additionalReminders = (0, message_1.buildAdditionalReminders)(fileReferencesResult.systemReminders, messageHistory, agentMode, hasSkillTool);
|
|
247
|
+
const additionalReminders = (0, message_1.buildAdditionalReminders)(fileReferencesResult.systemReminders, messageHistory, agentMode, this.sessionId, hasSkillTool);
|
|
328
248
|
const userMessage = (0, message_1.buildUserMsg)([
|
|
329
249
|
...additionalReminders,
|
|
330
250
|
...allBlocks
|
|
331
251
|
]);
|
|
332
|
-
// 2.3 完整消息
|
|
333
252
|
const messages = [...messageHistory, userMessage];
|
|
334
253
|
// 调用 query 函数
|
|
335
254
|
for await (const _message of (0, Conversation_1.ReAct)(messages, systemPromptContent, agentContext)) {
|
|
@@ -340,29 +259,20 @@ class SemaEngine {
|
|
|
340
259
|
if ((0, errors_1.isInterruptedException)(error)) {
|
|
341
260
|
(0, log_1.logDebug)('用户中断操作');
|
|
342
261
|
}
|
|
343
|
-
// API 错误已在 emitSessionError 中记录,这里不重复记录
|
|
344
262
|
}
|
|
345
263
|
finally {
|
|
346
|
-
// 延迟清空 AbortController
|
|
347
|
-
const currentAbortController =
|
|
264
|
+
// 延迟清空 AbortController,确保所有中断逻辑执行完毕
|
|
265
|
+
const currentAbortController = this.runtime.currentAbortController;
|
|
348
266
|
if (currentAbortController === agentContext.abortController) {
|
|
349
|
-
// 使用 setTimeout 0 确保当前执行栈完成后再清空
|
|
350
267
|
setTimeout(() => {
|
|
351
|
-
if (
|
|
352
|
-
|
|
268
|
+
if (this.runtime.currentAbortController === currentAbortController) {
|
|
269
|
+
this.runtime.currentAbortController = null;
|
|
353
270
|
}
|
|
354
271
|
}, 0);
|
|
355
272
|
}
|
|
356
|
-
//
|
|
357
|
-
|
|
358
|
-
if (this.pendingSession) {
|
|
359
|
-
stateManager.clearPendingUserInputs();
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
// 处理同一会话中的待处理输入队列
|
|
363
|
-
const remaining = stateManager.consumeAllPendingInputs();
|
|
273
|
+
// 处理待处理输入队列
|
|
274
|
+
const remaining = this.runtime.consumeAllPendingInputs();
|
|
364
275
|
if (remaining.length > 0) {
|
|
365
|
-
// 转换为 takeNextBatch 所需格式
|
|
366
276
|
const pending = remaining.map(item => ({
|
|
367
277
|
inputId: item.inputId,
|
|
368
278
|
input: item.input,
|
|
@@ -374,7 +284,7 @@ class SemaEngine {
|
|
|
374
284
|
if (pending.length > 0) {
|
|
375
285
|
for (const item of pending) {
|
|
376
286
|
const type = item.input.startsWith('/') ? 'command' : 'inject';
|
|
377
|
-
|
|
287
|
+
this.runtime.addPendingUserInput({ ...item, type });
|
|
378
288
|
}
|
|
379
289
|
}
|
|
380
290
|
(0, log_1.logInfo)(`处理队列中 ${batch.length} 条待处理输入`);
|
|
@@ -387,73 +297,62 @@ class SemaEngine {
|
|
|
387
297
|
}
|
|
388
298
|
/**
|
|
389
299
|
* 中止当前正在进行的请求(仅处理 AbortController)
|
|
390
|
-
* 不更新状态,用于内部调用
|
|
391
300
|
*/
|
|
392
301
|
abortCurrentRequest() {
|
|
393
|
-
const
|
|
394
|
-
const abortController = stateManager.currentAbortController;
|
|
302
|
+
const abortController = this.runtime.currentAbortController;
|
|
395
303
|
if (abortController && !abortController.signal.aborted) {
|
|
396
304
|
(0, log_1.logInfo)('通过 AbortController 发送中断信号');
|
|
397
305
|
abortController.abort();
|
|
398
306
|
}
|
|
399
|
-
|
|
307
|
+
this.runtime.currentAbortController = null;
|
|
400
308
|
}
|
|
401
309
|
/**
|
|
402
310
|
* 中断当前会话
|
|
403
|
-
* 仅中断当前正在执行的请求,队列中的待处理输入不受影响
|
|
404
|
-
* 由 processQuery 的 finally 决定是否继续消费队列或设为 idle
|
|
405
311
|
*/
|
|
406
312
|
interruptSession() {
|
|
407
313
|
this.abortCurrentRequest();
|
|
408
|
-
// 不直接设 idle,由 processQuery 的 finally 决定
|
|
409
|
-
// 若当前未在 processing(如已经 idle),则无需额外操作
|
|
410
314
|
}
|
|
411
315
|
/**
|
|
412
|
-
* 更新 Agent
|
|
316
|
+
* 更新 Agent 模式(会话级)
|
|
413
317
|
*/
|
|
414
318
|
updateAgentMode(mode) {
|
|
415
|
-
|
|
416
|
-
const currentMode = (0, ConfManager_1.getConfManager)().getCoreConfig()?.agentMode || 'Agent';
|
|
417
|
-
if (currentMode === mode) {
|
|
319
|
+
if (this.runtime.agentMode === mode) {
|
|
418
320
|
return;
|
|
419
321
|
}
|
|
420
|
-
|
|
421
|
-
(0,
|
|
422
|
-
// 切换到 Plan 模式时,重置 Plan 模式信息发送状态
|
|
322
|
+
this.runtime.agentMode = mode;
|
|
323
|
+
(0, log_1.logInfo)(`[${this.sessionId}] Agent 模式已更新: ${mode}`);
|
|
423
324
|
if (mode === 'Plan') {
|
|
424
|
-
|
|
325
|
+
this.runtime.resetPlanModeInfoSent();
|
|
425
326
|
}
|
|
426
|
-
// 切换到 Design 模式时,重置 Design 模式信息发送状态
|
|
427
|
-
// 新会话由前端在切换 UI 时通过 createSession() 自行触发
|
|
428
327
|
if (mode === 'Design') {
|
|
429
|
-
|
|
328
|
+
this.runtime.resetDesignModeInfoSent();
|
|
430
329
|
}
|
|
431
330
|
}
|
|
432
|
-
|
|
433
|
-
|
|
331
|
+
/**
|
|
332
|
+
* 更新自动编辑状态
|
|
333
|
+
*/
|
|
334
|
+
updateAutoEdit(enable) {
|
|
335
|
+
this.runtime.updateAutoEdit(enable);
|
|
336
|
+
}
|
|
337
|
+
// 初始化系统配置与模型检查
|
|
338
|
+
async initialize() {
|
|
434
339
|
const coreConfig = (0, ConfManager_1.getConfManager)().getCoreConfig();
|
|
435
|
-
// 1、设置日志级别
|
|
436
340
|
(0, log_1.setLogLevel)(coreConfig?.logLevel || 'info');
|
|
437
|
-
// 2、设置sessionId(如果为空则生成一个)
|
|
438
|
-
const finalSessionId = sessionId || (0, session_1.generateSessionId)();
|
|
439
|
-
const stateManager = (0, StateManager_1.getStateManager)();
|
|
440
|
-
stateManager.setSessionId(finalSessionId);
|
|
441
|
-
// 3、从配置文件加载模型配置 ~/.sema.conf
|
|
442
341
|
try {
|
|
443
342
|
const modelManager = (0, ModelManager_1.getModelManager)();
|
|
444
343
|
const modelProfile = modelManager.getModel('main');
|
|
445
|
-
// 检查是否有可用模型
|
|
446
344
|
if (!modelProfile) {
|
|
447
|
-
//
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
345
|
+
// 延迟一拍:等调用方在返回的 SemaSession 上注册监听器
|
|
346
|
+
setImmediate(() => {
|
|
347
|
+
this.emit('config:no_models', {
|
|
348
|
+
message: '未配置任何模型,请先添加模型配置',
|
|
349
|
+
suggestion: ''
|
|
350
|
+
});
|
|
451
351
|
});
|
|
452
352
|
}
|
|
453
353
|
}
|
|
454
354
|
catch (error) {
|
|
455
355
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
456
|
-
// 发送模型配置错误事件
|
|
457
356
|
this.emit('session:error', {
|
|
458
357
|
type: 'model_error',
|
|
459
358
|
error: {
|
|
@@ -466,20 +365,31 @@ class SemaEngine {
|
|
|
466
365
|
}
|
|
467
366
|
}
|
|
468
367
|
/**
|
|
469
|
-
*
|
|
368
|
+
* 等待当前处理结束(最多 timeoutMs 毫秒)
|
|
369
|
+
*/
|
|
370
|
+
async waitForIdle(timeoutMs = 10000) {
|
|
371
|
+
if (!this.currentProcessingPromise)
|
|
372
|
+
return;
|
|
373
|
+
try {
|
|
374
|
+
await Promise.race([
|
|
375
|
+
this.currentProcessingPromise,
|
|
376
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('等待超时')), timeoutMs)),
|
|
377
|
+
]);
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
(0, log_1.logWarn)(`等待会话处理结束时出错: ${error instanceof Error ? error.message : String(error)}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* 清理本会话资源(会话级,不触碰全局单例)
|
|
470
385
|
*/
|
|
471
386
|
dispose() {
|
|
472
|
-
(0, log_1.logInfo)(
|
|
473
|
-
// 1. 中止当前正在进行的请求并清空队列
|
|
387
|
+
(0, log_1.logInfo)(`清理 SemaEngine 资源: ${this.sessionId}`);
|
|
474
388
|
this.abortCurrentRequest();
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
stateManager.clearAllState();
|
|
480
|
-
// 3. 移除所有事件监听器
|
|
481
|
-
this.eventBus.removeAllListeners();
|
|
482
|
-
(0, log_1.logInfo)('SemaEngine 资源清理完成');
|
|
389
|
+
this.runtime.clearPendingUserInputs();
|
|
390
|
+
// 移除本会话在 Task/Cron 管理器上的通知回调
|
|
391
|
+
(0, TaskManager_1.getTaskManager)().removeNotifyCallback(this.sessionId);
|
|
392
|
+
(0, CronManager_1.getCronManager)().removeNotifyCallback(this.sessionId);
|
|
483
393
|
}
|
|
484
394
|
}
|
|
485
395
|
exports.SemaEngine = SemaEngine;
|