sema-core 2.0.0 → 2.0.2
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 +25 -16
- package/dist/core/SemaEngine.d.ts.map +1 -1
- package/dist/core/SemaEngine.js +118 -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 +16 -9
- 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 +211 -20
- package/dist/manager/PermissionManager.js.map +1 -1
- package/dist/manager/StateManager.d.ts +74 -134
- package/dist/manager/StateManager.d.ts.map +1 -1
- package/dist/manager/StateManager.js +164 -209
- 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/permission.d.ts +3 -0
- package/dist/prompt/permission.d.ts.map +1 -0
- package/dist/prompt/permission.js +58 -0
- package/dist/prompt/permission.js.map +1 -0
- 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 +16 -2
- package/dist/services/api/queryLLM.d.ts.map +1 -1
- package/dist/services/api/queryLLM.js +19 -18
- 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 +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/session.d.ts +20 -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/commands.d.ts +4 -1
- package/dist/util/commands.d.ts.map +1 -1
- package/dist/util/commands.js +126 -9
- package/dist/util/commands.js.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/dist/util/topic.d.ts +2 -2
- package/dist/util/topic.d.ts.map +1 -1
- package/dist/util/topic.js +4 -3
- package/dist/util/topic.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { AgentMode } from '../types';
|
|
1
|
+
import { SessionEventBus } from '../events/EventSystem';
|
|
2
|
+
import type { AgentMode, PermissionLevel } 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
|
+
updatePermissionLevel(level: PermissionLevel): 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,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3D,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;IAyDnE;;;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;IAwJ1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAIxB;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAetC;;OAEG;IACH,qBAAqB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;YAKrC,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,105 @@ 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
|
+
// 会话级配置:权限自由度档位
|
|
59
|
+
this.runtime.setPermissionLevel(opts.permissionLevel || 'Ask');
|
|
60
|
+
// 构建会话级系统提示快照:整个会话不再变化(env/gitStatus 取会话创建时的快照)
|
|
61
|
+
this.runtime.setSystemPromptContent(await (0, genSystemPrompt_1.formatSystemPrompt)());
|
|
62
|
+
const mainAgentState = this.runtime.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
129
63
|
const workingDir = coreConfig?.workingDir;
|
|
130
|
-
|
|
131
|
-
const historyData = await (0, history_1.loadHistory)(
|
|
132
|
-
(0, log_1.logInfo)(`会话CoreConfig: ${JSON.stringify(coreConfig, null, 2)}`);
|
|
64
|
+
const historyId = opts.sessionId;
|
|
65
|
+
const historyData = await (0, history_1.loadHistory)(historyId, workingDir);
|
|
133
66
|
// 将加载的消息历史、todos 和 readFileTimestamps 设置到主代理状态
|
|
134
67
|
// 初始化时跳过自动保存,避免把刚读取的数据重复写回文件
|
|
135
68
|
mainAgentState.setMessageHistory(historyData.messages, true);
|
|
136
69
|
mainAgentState.setTodos(historyData.todos);
|
|
137
70
|
if (historyData.todoTasks && historyData.todoTasks.length > 0) {
|
|
138
|
-
|
|
139
|
-
stateManager.restoreTodoTasks(historyData.todoTasks);
|
|
71
|
+
this.runtime.restoreTodoTasks(historyData.todoTasks);
|
|
140
72
|
}
|
|
141
73
|
else if (historyData.todos && historyData.todos.length > 0) {
|
|
142
|
-
|
|
143
|
-
stateManager.restoreTodoTasksFromLegacy(historyData.todos);
|
|
74
|
+
this.runtime.restoreTodoTasksFromLegacy(historyData.todos);
|
|
144
75
|
}
|
|
145
76
|
if (historyData.readFileTimestamps) {
|
|
146
77
|
mainAgentState.setReadFileTimestamps(historyData.readFileTimestamps);
|
|
147
78
|
}
|
|
148
|
-
// 使用全局配置获取工作路径
|
|
149
79
|
const projectConfig = (0, ConfManager_1.getConfManager)().getProjectConfig();
|
|
150
80
|
const projectInputHistory = projectConfig?.history || [];
|
|
151
|
-
// 获取tokens
|
|
152
81
|
const usage = (0, tokens_1.getTokens)(mainAgentState.getMessageHistory());
|
|
153
82
|
const sessionData = {
|
|
154
83
|
pid: process.pid,
|
|
155
84
|
workingDir: coreConfig?.workingDir,
|
|
156
|
-
sessionId:
|
|
157
|
-
historyLoaded: !!
|
|
85
|
+
sessionId: this.sessionId,
|
|
86
|
+
historyLoaded: !!historyId,
|
|
158
87
|
projectInputHistory: projectInputHistory,
|
|
159
88
|
usage: usage,
|
|
160
89
|
todos: mainAgentState.getTodos(),
|
|
161
90
|
readFileTimestamps: historyData.readFileTimestamps || {}
|
|
162
91
|
};
|
|
163
|
-
(0, log_1.logInfo)(`新会话创建完成,sessionId: ${
|
|
164
|
-
|
|
165
|
-
|
|
92
|
+
(0, log_1.logInfo)(`新会话创建完成,sessionId: ${this.sessionId}`);
|
|
93
|
+
// 延迟一拍发送 session:ready:调用方需先拿到 createSession 返回的 SemaSession
|
|
94
|
+
// 并在其上注册监听器,再收到首个事件
|
|
95
|
+
setImmediate(() => {
|
|
96
|
+
this.emit('session:ready', sessionData);
|
|
97
|
+
mainAgentState.updateState('idle');
|
|
98
|
+
});
|
|
166
99
|
}
|
|
167
100
|
/**
|
|
168
101
|
* 处理用户输入
|
|
169
102
|
* 如果当前正在处理中,将输入加入队列等待
|
|
170
103
|
*/
|
|
171
104
|
processUserInput(input, originalInput, silent) {
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
const inputId = crypto.randomUUID().replace(/-/g, '').substring(0, 8);
|
|
105
|
+
const mainAgentState = this.runtime.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
106
|
+
const inputId = (0, session_1.generateShortId)();
|
|
175
107
|
const trimmedInput = input.trim();
|
|
176
108
|
// quickchat 旁路:不影响状态和队列,异步处理后直接返回
|
|
177
109
|
if (trimmedInput === '/quickchat' || trimmedInput.startsWith('/quickchat ')) {
|
|
178
|
-
const question = trimmedInput.startsWith('/quickchat ') ? trimmedInput.slice(
|
|
110
|
+
const question = trimmedInput.startsWith('/quickchat ') ? trimmedInput.slice('/quickchat '.length).trim() : '';
|
|
179
111
|
(0, ConfManager_1.getConfManager)().saveUserInputToHistory(originalInput || trimmedInput);
|
|
180
112
|
if (question) {
|
|
181
|
-
(0, quickchat_1.handlequickchat)(question).catch(err => (0, log_1.logWarn)(`[quickchat] 未捕获异常: ${err instanceof Error ? err.message : String(err)}`));
|
|
113
|
+
(0, quickchat_1.handlequickchat)(question, this.sessionId).catch(err => (0, log_1.logWarn)(`[quickchat] 未捕获异常: ${err instanceof Error ? err.message : String(err)}`));
|
|
182
114
|
}
|
|
183
115
|
else {
|
|
184
116
|
this.emit('quickchat:response', { question: '', content: '' });
|
|
@@ -187,8 +119,8 @@ class SemaEngine {
|
|
|
187
119
|
}
|
|
188
120
|
if (mainAgentState.getCurrentState() === 'processing') {
|
|
189
121
|
const type = trimmedInput.startsWith('/') ? 'command' : 'inject';
|
|
190
|
-
|
|
191
|
-
(0, log_1.logInfo)(`输入已入队(${type}),队列长度: ${
|
|
122
|
+
this.runtime.addPendingUserInput({ inputId, input: trimmedInput, originalInput, silent, type });
|
|
123
|
+
(0, log_1.logInfo)(`输入已入队(${type}),队列长度: ${this.runtime.getPendingUserInputsLength()}`);
|
|
192
124
|
if (!silent) {
|
|
193
125
|
this.emit('input:received', {
|
|
194
126
|
inputId,
|
|
@@ -196,7 +128,7 @@ class SemaEngine {
|
|
|
196
128
|
originalInput,
|
|
197
129
|
queued: true,
|
|
198
130
|
inject: type === 'inject',
|
|
199
|
-
queueLength:
|
|
131
|
+
queueLength: this.runtime.getPendingUserInputsLength(),
|
|
200
132
|
});
|
|
201
133
|
}
|
|
202
134
|
return;
|
|
@@ -217,21 +149,19 @@ class SemaEngine {
|
|
|
217
149
|
* 启动一次查询(构建上下文并调用 processQuery)
|
|
218
150
|
*/
|
|
219
151
|
startQuery(inputs) {
|
|
220
|
-
const
|
|
221
|
-
const mainAgentState = stateManager.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
152
|
+
const mainAgentState = this.runtime.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
222
153
|
mainAgentState.updateState('processing');
|
|
223
154
|
(0, log_1.logInfo)(`用户输入(${inputs.length}条): ${inputs.map(i => i.input).join(' | ')}`);
|
|
224
155
|
// 创建新的 AbortController 用于此次处理
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const agentMode = coreConfig?.agentMode || 'Agent';
|
|
229
|
-
// 获取工具集
|
|
156
|
+
this.runtime.currentAbortController = new AbortController();
|
|
157
|
+
const agentMode = this.runtime.agentMode;
|
|
158
|
+
// 获取工具集(按核心级 useTools 黑名单过滤)
|
|
230
159
|
const tools = (0, tools_1.getAvailableTools)();
|
|
231
160
|
// 构建主代理上下文
|
|
232
161
|
const agentContext = {
|
|
162
|
+
sessionId: this.sessionId,
|
|
233
163
|
agentId: StateManager_1.MAIN_AGENT_ID,
|
|
234
|
-
abortController:
|
|
164
|
+
abortController: this.runtime.currentAbortController,
|
|
235
165
|
tools,
|
|
236
166
|
model: 'main',
|
|
237
167
|
};
|
|
@@ -239,14 +169,12 @@ class SemaEngine {
|
|
|
239
169
|
this.currentProcessingPromise = this.processQuery(inputs, agentContext, agentMode)
|
|
240
170
|
.catch(error => {
|
|
241
171
|
(0, log_1.logWarn)(`processQuery 未捕获异常: ${error instanceof Error ? error.message : String(error)}`);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
stateManager.currentAbortController = null;
|
|
172
|
+
if (this.runtime.currentAbortController === agentContext.abortController) {
|
|
173
|
+
this.runtime.currentAbortController = null;
|
|
245
174
|
}
|
|
246
175
|
mainAgentState.updateState('idle');
|
|
247
176
|
})
|
|
248
177
|
.finally(() => {
|
|
249
|
-
// 清空 Promise 引用
|
|
250
178
|
this.currentProcessingPromise = null;
|
|
251
179
|
});
|
|
252
180
|
}
|
|
@@ -254,9 +182,7 @@ class SemaEngine {
|
|
|
254
182
|
* 处理查询逻辑
|
|
255
183
|
*/
|
|
256
184
|
async processQuery(inputs, agentContext, agentMode) {
|
|
257
|
-
|
|
258
|
-
const stateManager = (0, StateManager_1.getStateManager)();
|
|
259
|
-
const mainAgentState = stateManager.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
185
|
+
const mainAgentState = this.runtime.forAgent(StateManager_1.MAIN_AGENT_ID);
|
|
260
186
|
// 为每条输入发送独立的 input:processing 事件(静默输入跳过)
|
|
261
187
|
for (const item of inputs) {
|
|
262
188
|
if (!item.silent) {
|
|
@@ -274,12 +200,11 @@ class SemaEngine {
|
|
|
274
200
|
const allBlocks = [];
|
|
275
201
|
let combinedProcessedText = '';
|
|
276
202
|
for (const item of inputs) {
|
|
277
|
-
// abort 早期检查:避免会话切换后继续执行无用操作
|
|
278
203
|
if (agentContext.abortController.signal.aborted) {
|
|
279
204
|
(0, log_1.logInfo)('processQuery: abort detected during handleCommand loop, skipping remaining');
|
|
280
205
|
return;
|
|
281
206
|
}
|
|
282
|
-
const commandResult = await (0, runCommand_1.handleCommand)(item.input);
|
|
207
|
+
const commandResult = await (0, runCommand_1.handleCommand)(item.input, this.sessionId);
|
|
283
208
|
if (commandResult === null) {
|
|
284
209
|
// 系统命令已处理(如 /compact, /clear),跳过
|
|
285
210
|
continue;
|
|
@@ -287,23 +212,20 @@ class SemaEngine {
|
|
|
287
212
|
combinedProcessedText += (combinedProcessedText ? '\n' : '') + commandResult.processedText;
|
|
288
213
|
allBlocks.push(...commandResult.blocks);
|
|
289
214
|
}
|
|
290
|
-
// 如果所有输入都是系统命令(返回 null),直接结束
|
|
291
215
|
if (allBlocks.length === 0) {
|
|
292
216
|
return;
|
|
293
217
|
}
|
|
294
|
-
// abort 早期检查
|
|
295
218
|
if (agentContext.abortController.signal.aborted) {
|
|
296
219
|
(0, log_1.logInfo)('processQuery: abort detected after handleCommand, skipping remaining');
|
|
297
220
|
return;
|
|
298
221
|
}
|
|
299
|
-
//
|
|
300
|
-
// 跳过条件:全部输入均为 silent(来自 cron / 后台任务通知等系统注入),不应改变会话话题
|
|
222
|
+
// 后台异步执行话题检测,不阻塞主流程
|
|
301
223
|
const allSilent = inputs.every(i => i.silent);
|
|
302
224
|
const allOriginalTexts = inputs.map(i => i.originalInput || i.input).join('\n');
|
|
303
225
|
if (!allSilent && !(0, ConfManager_1.getConfManager)().getCoreConfig()?.disableTopicDetection) {
|
|
304
|
-
(0, topic_1.detectTopicInBackground)(allOriginalTexts,
|
|
226
|
+
(0, topic_1.detectTopicInBackground)(allOriginalTexts, this.runtime.currentAbortController, (result) => this.emit('topic:update', result), this.sessionId);
|
|
305
227
|
}
|
|
306
|
-
//
|
|
228
|
+
// 处理文件引用以获取补充信息
|
|
307
229
|
const fileReferencesResult = await (0, fileReference_1.processFileReferences)(combinedProcessedText, agentContext);
|
|
308
230
|
(0, log_1.logInfo)(`返回文件引用信息: ${JSON.stringify(fileReferencesResult.supplementaryInfo, null, 2)}`);
|
|
309
231
|
if (fileReferencesResult.supplementaryInfo.length > 0) {
|
|
@@ -311,25 +233,24 @@ class SemaEngine {
|
|
|
311
233
|
references: fileReferencesResult.supplementaryInfo
|
|
312
234
|
});
|
|
313
235
|
}
|
|
314
|
-
// abort 早期检查
|
|
315
236
|
if (agentContext.abortController.signal.aborted) {
|
|
316
237
|
(0, log_1.logInfo)('processQuery: abort detected after processFileReferences, skipping remaining');
|
|
317
238
|
return;
|
|
318
239
|
}
|
|
319
|
-
// 1
|
|
240
|
+
// 1、系统提示:复用会话级快照(整会话不变);缺失时兜底构建一次
|
|
320
241
|
const hasSkillTool = agentContext.tools.some(tool => tool.name === tool_1.TOOL_NAME_SKILL);
|
|
321
|
-
|
|
242
|
+
let systemPromptContent = this.runtime.getSystemPromptContent();
|
|
243
|
+
if (!systemPromptContent) {
|
|
244
|
+
systemPromptContent = await (0, genSystemPrompt_1.formatSystemPrompt)();
|
|
245
|
+
this.runtime.setSystemPromptContent(systemPromptContent);
|
|
246
|
+
}
|
|
322
247
|
// 2、构建用户消息内容
|
|
323
|
-
// 2.1 获取消息历史
|
|
324
248
|
const messageHistory = mainAgentState.getMessageHistory();
|
|
325
|
-
|
|
326
|
-
// 构建reminder信息 文件引用 每次输入均添加,首次查询添加 todos\rules,Plan 模式添加 Plan 信息
|
|
327
|
-
const additionalReminders = (0, message_1.buildAdditionalReminders)(fileReferencesResult.systemReminders, messageHistory, agentMode, hasSkillTool);
|
|
249
|
+
const additionalReminders = (0, message_1.buildAdditionalReminders)(fileReferencesResult.systemReminders, messageHistory, agentMode, this.sessionId, hasSkillTool);
|
|
328
250
|
const userMessage = (0, message_1.buildUserMsg)([
|
|
329
251
|
...additionalReminders,
|
|
330
252
|
...allBlocks
|
|
331
253
|
]);
|
|
332
|
-
// 2.3 完整消息
|
|
333
254
|
const messages = [...messageHistory, userMessage];
|
|
334
255
|
// 调用 query 函数
|
|
335
256
|
for await (const _message of (0, Conversation_1.ReAct)(messages, systemPromptContent, agentContext)) {
|
|
@@ -340,29 +261,20 @@ class SemaEngine {
|
|
|
340
261
|
if ((0, errors_1.isInterruptedException)(error)) {
|
|
341
262
|
(0, log_1.logDebug)('用户中断操作');
|
|
342
263
|
}
|
|
343
|
-
// API 错误已在 emitSessionError 中记录,这里不重复记录
|
|
344
264
|
}
|
|
345
265
|
finally {
|
|
346
|
-
// 延迟清空 AbortController
|
|
347
|
-
const currentAbortController =
|
|
266
|
+
// 延迟清空 AbortController,确保所有中断逻辑执行完毕
|
|
267
|
+
const currentAbortController = this.runtime.currentAbortController;
|
|
348
268
|
if (currentAbortController === agentContext.abortController) {
|
|
349
|
-
// 使用 setTimeout 0 确保当前执行栈完成后再清空
|
|
350
269
|
setTimeout(() => {
|
|
351
|
-
if (
|
|
352
|
-
|
|
270
|
+
if (this.runtime.currentAbortController === currentAbortController) {
|
|
271
|
+
this.runtime.currentAbortController = null;
|
|
353
272
|
}
|
|
354
273
|
}, 0);
|
|
355
274
|
}
|
|
356
|
-
//
|
|
357
|
-
|
|
358
|
-
if (this.pendingSession) {
|
|
359
|
-
stateManager.clearPendingUserInputs();
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
// 处理同一会话中的待处理输入队列
|
|
363
|
-
const remaining = stateManager.consumeAllPendingInputs();
|
|
275
|
+
// 处理待处理输入队列
|
|
276
|
+
const remaining = this.runtime.consumeAllPendingInputs();
|
|
364
277
|
if (remaining.length > 0) {
|
|
365
|
-
// 转换为 takeNextBatch 所需格式
|
|
366
278
|
const pending = remaining.map(item => ({
|
|
367
279
|
inputId: item.inputId,
|
|
368
280
|
input: item.input,
|
|
@@ -374,7 +286,7 @@ class SemaEngine {
|
|
|
374
286
|
if (pending.length > 0) {
|
|
375
287
|
for (const item of pending) {
|
|
376
288
|
const type = item.input.startsWith('/') ? 'command' : 'inject';
|
|
377
|
-
|
|
289
|
+
this.runtime.addPendingUserInput({ ...item, type });
|
|
378
290
|
}
|
|
379
291
|
}
|
|
380
292
|
(0, log_1.logInfo)(`处理队列中 ${batch.length} 条待处理输入`);
|
|
@@ -387,73 +299,62 @@ class SemaEngine {
|
|
|
387
299
|
}
|
|
388
300
|
/**
|
|
389
301
|
* 中止当前正在进行的请求(仅处理 AbortController)
|
|
390
|
-
* 不更新状态,用于内部调用
|
|
391
302
|
*/
|
|
392
303
|
abortCurrentRequest() {
|
|
393
|
-
const
|
|
394
|
-
const abortController = stateManager.currentAbortController;
|
|
304
|
+
const abortController = this.runtime.currentAbortController;
|
|
395
305
|
if (abortController && !abortController.signal.aborted) {
|
|
396
306
|
(0, log_1.logInfo)('通过 AbortController 发送中断信号');
|
|
397
307
|
abortController.abort();
|
|
398
308
|
}
|
|
399
|
-
|
|
309
|
+
this.runtime.currentAbortController = null;
|
|
400
310
|
}
|
|
401
311
|
/**
|
|
402
312
|
* 中断当前会话
|
|
403
|
-
* 仅中断当前正在执行的请求,队列中的待处理输入不受影响
|
|
404
|
-
* 由 processQuery 的 finally 决定是否继续消费队列或设为 idle
|
|
405
313
|
*/
|
|
406
314
|
interruptSession() {
|
|
407
315
|
this.abortCurrentRequest();
|
|
408
|
-
// 不直接设 idle,由 processQuery 的 finally 决定
|
|
409
|
-
// 若当前未在 processing(如已经 idle),则无需额外操作
|
|
410
316
|
}
|
|
411
317
|
/**
|
|
412
|
-
* 更新 Agent
|
|
318
|
+
* 更新 Agent 模式(会话级)
|
|
413
319
|
*/
|
|
414
320
|
updateAgentMode(mode) {
|
|
415
|
-
|
|
416
|
-
const currentMode = (0, ConfManager_1.getConfManager)().getCoreConfig()?.agentMode || 'Agent';
|
|
417
|
-
if (currentMode === mode) {
|
|
321
|
+
if (this.runtime.agentMode === mode) {
|
|
418
322
|
return;
|
|
419
323
|
}
|
|
420
|
-
|
|
421
|
-
(0,
|
|
422
|
-
// 切换到 Plan 模式时,重置 Plan 模式信息发送状态
|
|
324
|
+
this.runtime.agentMode = mode;
|
|
325
|
+
(0, log_1.logInfo)(`[${this.sessionId}] Agent 模式已更新: ${mode}`);
|
|
423
326
|
if (mode === 'Plan') {
|
|
424
|
-
|
|
327
|
+
this.runtime.resetPlanModeInfoSent();
|
|
425
328
|
}
|
|
426
|
-
// 切换到 Design 模式时,重置 Design 模式信息发送状态
|
|
427
|
-
// 新会话由前端在切换 UI 时通过 createSession() 自行触发
|
|
428
329
|
if (mode === 'Design') {
|
|
429
|
-
|
|
330
|
+
this.runtime.resetDesignModeInfoSent();
|
|
430
331
|
}
|
|
431
332
|
}
|
|
432
|
-
|
|
433
|
-
|
|
333
|
+
/**
|
|
334
|
+
* 更新权限自由度档位(会话级)
|
|
335
|
+
*/
|
|
336
|
+
updatePermissionLevel(level) {
|
|
337
|
+
this.runtime.setPermissionLevel(level);
|
|
338
|
+
}
|
|
339
|
+
// 初始化系统配置与模型检查
|
|
340
|
+
async initialize() {
|
|
434
341
|
const coreConfig = (0, ConfManager_1.getConfManager)().getCoreConfig();
|
|
435
|
-
// 1、设置日志级别
|
|
436
342
|
(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
343
|
try {
|
|
443
344
|
const modelManager = (0, ModelManager_1.getModelManager)();
|
|
444
345
|
const modelProfile = modelManager.getModel('main');
|
|
445
|
-
// 检查是否有可用模型
|
|
446
346
|
if (!modelProfile) {
|
|
447
|
-
//
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
347
|
+
// 延迟一拍:等调用方在返回的 SemaSession 上注册监听器
|
|
348
|
+
setImmediate(() => {
|
|
349
|
+
this.emit('config:no_models', {
|
|
350
|
+
message: '未配置任何模型,请先添加模型配置',
|
|
351
|
+
suggestion: ''
|
|
352
|
+
});
|
|
451
353
|
});
|
|
452
354
|
}
|
|
453
355
|
}
|
|
454
356
|
catch (error) {
|
|
455
357
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
456
|
-
// 发送模型配置错误事件
|
|
457
358
|
this.emit('session:error', {
|
|
458
359
|
type: 'model_error',
|
|
459
360
|
error: {
|
|
@@ -466,20 +367,31 @@ class SemaEngine {
|
|
|
466
367
|
}
|
|
467
368
|
}
|
|
468
369
|
/**
|
|
469
|
-
*
|
|
370
|
+
* 等待当前处理结束(最多 timeoutMs 毫秒)
|
|
371
|
+
*/
|
|
372
|
+
async waitForIdle(timeoutMs = 10000) {
|
|
373
|
+
if (!this.currentProcessingPromise)
|
|
374
|
+
return;
|
|
375
|
+
try {
|
|
376
|
+
await Promise.race([
|
|
377
|
+
this.currentProcessingPromise,
|
|
378
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('等待超时')), timeoutMs)),
|
|
379
|
+
]);
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
(0, log_1.logWarn)(`等待会话处理结束时出错: ${error instanceof Error ? error.message : String(error)}`);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* 清理本会话资源(会话级,不触碰全局单例)
|
|
470
387
|
*/
|
|
471
388
|
dispose() {
|
|
472
|
-
(0, log_1.logInfo)(
|
|
473
|
-
// 1. 中止当前正在进行的请求并清空队列
|
|
389
|
+
(0, log_1.logInfo)(`清理 SemaEngine 资源: ${this.sessionId}`);
|
|
474
390
|
this.abortCurrentRequest();
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
stateManager.clearAllState();
|
|
480
|
-
// 3. 移除所有事件监听器
|
|
481
|
-
this.eventBus.removeAllListeners();
|
|
482
|
-
(0, log_1.logInfo)('SemaEngine 资源清理完成');
|
|
391
|
+
this.runtime.clearPendingUserInputs();
|
|
392
|
+
// 移除本会话在 Task/Cron 管理器上的通知回调
|
|
393
|
+
(0, TaskManager_1.getTaskManager)().removeNotifyCallback(this.sessionId);
|
|
394
|
+
(0, CronManager_1.getCronManager)().removeNotifyCallback(this.sessionId);
|
|
483
395
|
}
|
|
484
396
|
}
|
|
485
397
|
exports.SemaEngine = SemaEngine;
|