@cxyhhhhh/dsh-qqbot 0.1.0-dev.202608141838 → 0.1.0-dev.202608141907
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/model-resolver.d.ts +13 -7
- package/dist/model-resolver.d.ts.map +1 -1
- package/dist/model-resolver.js +67 -23
- package/dist/model-resolver.js.map +1 -1
- package/dist/session-manager.d.ts +10 -5
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +20 -38
- package/dist/session-manager.js.map +1 -1
- package/package.json +1 -1
package/dist/model-resolver.d.ts
CHANGED
|
@@ -14,33 +14,35 @@ export interface ModelEntry {
|
|
|
14
14
|
export declare class ModelResolver {
|
|
15
15
|
private readonly ctx;
|
|
16
16
|
private readonly config;
|
|
17
|
-
/** per-
|
|
17
|
+
/** per-peer 模型偏好(内存态) */
|
|
18
18
|
private overrides;
|
|
19
19
|
/** settings.yaml 缓存 */
|
|
20
20
|
private settingsCache;
|
|
21
|
+
/** 隔离偏好文件路径 */
|
|
22
|
+
private readonly prefsPath;
|
|
21
23
|
constructor(ctx: Context, config: ImQQBotConfig);
|
|
22
24
|
/**
|
|
23
25
|
* 获取指定 sessionKey 的有效模型路由
|
|
24
26
|
*
|
|
25
|
-
* 优先级:per-
|
|
27
|
+
* 优先级:per-peer 偏好 > config 显式指定 > settings.yaml > 宿主服务
|
|
26
28
|
*/
|
|
27
29
|
getEffectiveRoute(sessionKey: string): ModelRoute | undefined;
|
|
28
30
|
/**
|
|
29
|
-
* 设置 per-
|
|
31
|
+
* 设置 per-peer 模型偏好并持久化到隔离文件
|
|
30
32
|
*/
|
|
31
33
|
setOverride(sessionKey: string, route: ModelRoute): void;
|
|
32
34
|
/**
|
|
33
|
-
* 清除 per-
|
|
35
|
+
* 清除 per-peer 模型偏好并持久化
|
|
34
36
|
*/
|
|
35
37
|
clearOverride(sessionKey: string): void;
|
|
36
38
|
/**
|
|
37
|
-
* 是否存在指定 session
|
|
39
|
+
* 是否存在指定 session 的模型偏好
|
|
38
40
|
*/
|
|
39
41
|
hasOverride(sessionKey: string): boolean;
|
|
40
42
|
/**
|
|
41
|
-
* 解析默认模型路由(不含 per-
|
|
43
|
+
* 解析默认模型路由(不含 per-peer 偏好)
|
|
42
44
|
*
|
|
43
|
-
* 优先级:config 显式指定 > 宿主 agentDefaultModel
|
|
45
|
+
* 优先级:config 显式指定 > settings.yaml(只读) > 宿主 agentDefaultModel
|
|
44
46
|
*/
|
|
45
47
|
resolveDefault(): ModelRoute | undefined;
|
|
46
48
|
/**
|
|
@@ -51,6 +53,10 @@ export declare class ModelResolver {
|
|
|
51
53
|
* 列出可用 provider 名称
|
|
52
54
|
*/
|
|
53
55
|
listProviders(): string[];
|
|
56
|
+
/** 从隔离偏好文件加载 per-peer 偏好 */
|
|
57
|
+
private loadPrefs;
|
|
58
|
+
/** 将 per-peer 偏好写回隔离文件 */
|
|
59
|
+
private writePrefs;
|
|
54
60
|
private readFromHost;
|
|
55
61
|
private readDefaultFromSettings;
|
|
56
62
|
private readModelsFromSettings;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-resolver.d.ts","sourceRoot":"","sources":["../src/model-resolver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-resolver.d.ts","sourceRoot":"","sources":["../src/model-resolver.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,WAAW;AACX,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,aAAa;AACb,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAkBD,qBAAa,aAAa;IAStB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IATzB,yBAAyB;IACzB,OAAO,CAAC,SAAS,CAAiC;IAClD,uBAAuB;IACvB,OAAO,CAAC,aAAa,CAA6C;IAClE,eAAe;IACf,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwD;gBAG/D,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,aAAa;IAKxC;;;;OAIG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI7D;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAKxD;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAMvC;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAIxC;;;;OAIG;IACH,cAAc,IAAI,UAAU,GAAG,SAAS;IAcxC;;OAEG;IACH,UAAU,IAAI,UAAU,EAAE;IAI1B;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE;IA2BzB,4BAA4B;IAC5B,OAAO,CAAC,SAAS;IAmBjB,0BAA0B;IAC1B,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,sBAAsB;IAsB9B,OAAO,CAAC,YAAY;IAkBpB,sBAAsB;IACtB,OAAO,CAAC,UAAU;CAKnB"}
|
package/dist/model-resolver.js
CHANGED
|
@@ -2,76 +2,86 @@
|
|
|
2
2
|
* ModelResolver — 统一的模型发现与路由解析
|
|
3
3
|
*
|
|
4
4
|
* 职责:
|
|
5
|
-
* 1.
|
|
5
|
+
* 1. 解析当前生效的默认模型路由
|
|
6
6
|
* 2. 列出可用 providers 和模型
|
|
7
|
-
* 3. 管理 per-
|
|
7
|
+
* 3. 管理 per-peer 的模型偏好(隔离存储,不污染全局 settings.yaml)
|
|
8
|
+
*
|
|
9
|
+
* 优先级(从高到低):
|
|
10
|
+
* per-peer 偏好(~/.dsh-qqbot/model-prefs.json)
|
|
11
|
+
* > config 显式指定(cordis.yml 的 provider/model)
|
|
12
|
+
* > settings.yaml 的 agent-default-model(只读,作为默认兜底)
|
|
13
|
+
* > 宿主 agentDefaultModel 服务
|
|
8
14
|
*
|
|
9
15
|
* 从 SessionManager 中解耦,使其专注于 session 生命周期管理。
|
|
10
16
|
*/
|
|
11
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
12
|
-
import { resolve } from 'node:path';
|
|
17
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
18
|
+
import { resolve, dirname } from 'node:path';
|
|
13
19
|
import { homedir } from 'node:os';
|
|
14
20
|
import yaml from 'js-yaml';
|
|
15
21
|
export class ModelResolver {
|
|
16
22
|
ctx;
|
|
17
23
|
config;
|
|
18
|
-
/** per-
|
|
24
|
+
/** per-peer 模型偏好(内存态) */
|
|
19
25
|
overrides = new Map();
|
|
20
26
|
/** settings.yaml 缓存 */
|
|
21
27
|
settingsCache;
|
|
28
|
+
/** 隔离偏好文件路径 */
|
|
29
|
+
prefsPath = resolve(homedir(), '.dsh-qqbot', 'model-prefs.json');
|
|
22
30
|
constructor(ctx, config) {
|
|
23
31
|
this.ctx = ctx;
|
|
24
32
|
this.config = config;
|
|
33
|
+
this.loadPrefs();
|
|
25
34
|
}
|
|
26
35
|
/**
|
|
27
36
|
* 获取指定 sessionKey 的有效模型路由
|
|
28
37
|
*
|
|
29
|
-
* 优先级:per-
|
|
38
|
+
* 优先级:per-peer 偏好 > config 显式指定 > settings.yaml > 宿主服务
|
|
30
39
|
*/
|
|
31
40
|
getEffectiveRoute(sessionKey) {
|
|
32
41
|
return this.overrides.get(sessionKey) ?? this.resolveDefault();
|
|
33
42
|
}
|
|
34
43
|
/**
|
|
35
|
-
* 设置 per-
|
|
44
|
+
* 设置 per-peer 模型偏好并持久化到隔离文件
|
|
36
45
|
*/
|
|
37
46
|
setOverride(sessionKey, route) {
|
|
38
47
|
this.overrides.set(sessionKey, route);
|
|
48
|
+
this.writePrefs();
|
|
39
49
|
}
|
|
40
50
|
/**
|
|
41
|
-
* 清除 per-
|
|
51
|
+
* 清除 per-peer 模型偏好并持久化
|
|
42
52
|
*/
|
|
43
53
|
clearOverride(sessionKey) {
|
|
44
|
-
this.overrides.delete(sessionKey)
|
|
54
|
+
if (this.overrides.delete(sessionKey)) {
|
|
55
|
+
this.writePrefs();
|
|
56
|
+
}
|
|
45
57
|
}
|
|
46
58
|
/**
|
|
47
|
-
* 是否存在指定 session
|
|
59
|
+
* 是否存在指定 session 的模型偏好
|
|
48
60
|
*/
|
|
49
61
|
hasOverride(sessionKey) {
|
|
50
62
|
return this.overrides.has(sessionKey);
|
|
51
63
|
}
|
|
52
64
|
/**
|
|
53
|
-
* 解析默认模型路由(不含 per-
|
|
65
|
+
* 解析默认模型路由(不含 per-peer 偏好)
|
|
54
66
|
*
|
|
55
|
-
* 优先级:config 显式指定 > 宿主 agentDefaultModel
|
|
67
|
+
* 优先级:config 显式指定 > settings.yaml(只读) > 宿主 agentDefaultModel
|
|
56
68
|
*/
|
|
57
69
|
resolveDefault() {
|
|
58
70
|
// 1. config 中显式指定
|
|
59
71
|
if (this.config.provider && this.config.model) {
|
|
60
72
|
return { provider: this.config.provider, model: this.config.model };
|
|
61
73
|
}
|
|
62
|
-
// 2.
|
|
63
|
-
const
|
|
64
|
-
if (
|
|
65
|
-
return
|
|
66
|
-
// 3.
|
|
67
|
-
return this.
|
|
74
|
+
// 2. 从 settings.yaml 直接读取(只读,作为默认兜底)
|
|
75
|
+
const fromSettings = this.readDefaultFromSettings();
|
|
76
|
+
if (fromSettings)
|
|
77
|
+
return fromSettings;
|
|
78
|
+
// 3. 从宿主 agentDefaultModel 服务读取
|
|
79
|
+
return this.readFromHost();
|
|
68
80
|
}
|
|
69
81
|
/**
|
|
70
82
|
* 列出所有可用模型
|
|
71
83
|
*/
|
|
72
84
|
listModels() {
|
|
73
|
-
// 优先尝试宿主 → 兜底 settings.yaml
|
|
74
|
-
// 注:ctx.llm.listModels 是异步的,此处仅能同步返回 settings 数据
|
|
75
85
|
return this.readModelsFromSettings();
|
|
76
86
|
}
|
|
77
87
|
/**
|
|
@@ -99,6 +109,43 @@ export class ModelResolver {
|
|
|
99
109
|
const llmPiAi = settings?.['llm-pi-ai'];
|
|
100
110
|
return llmPiAi?.providers ? Object.keys(llmPiAi.providers) : [];
|
|
101
111
|
}
|
|
112
|
+
// ── 隔离偏好文件 ──
|
|
113
|
+
/** 从隔离偏好文件加载 per-peer 偏好 */
|
|
114
|
+
loadPrefs() {
|
|
115
|
+
try {
|
|
116
|
+
if (!existsSync(this.prefsPath))
|
|
117
|
+
return;
|
|
118
|
+
const content = readFileSync(this.prefsPath, 'utf8');
|
|
119
|
+
const data = JSON.parse(content);
|
|
120
|
+
if (data.overrides && typeof data.overrides === 'object') {
|
|
121
|
+
for (const [key, route] of Object.entries(data.overrides)) {
|
|
122
|
+
if (route.provider && route.model) {
|
|
123
|
+
this.overrides.set(key, { provider: route.provider, model: route.model });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
if (this.config.debug) {
|
|
130
|
+
console.log(`[im-qqbot] loadPrefs failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/** 将 per-peer 偏好写回隔离文件 */
|
|
135
|
+
writePrefs() {
|
|
136
|
+
try {
|
|
137
|
+
mkdirSync(dirname(this.prefsPath), { recursive: true });
|
|
138
|
+
const data = {
|
|
139
|
+
overrides: Object.fromEntries(this.overrides.entries()),
|
|
140
|
+
};
|
|
141
|
+
writeFileSync(this.prefsPath, JSON.stringify(data, null, 2), 'utf8');
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
if (this.config.debug) {
|
|
145
|
+
console.log(`[im-qqbot] writePrefs failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
102
149
|
// ── 私有方法 ──
|
|
103
150
|
readFromHost() {
|
|
104
151
|
try {
|
|
@@ -123,9 +170,6 @@ export class ModelResolver {
|
|
|
123
170
|
return undefined;
|
|
124
171
|
const defaultModel = settings['agent-default-model'];
|
|
125
172
|
if (defaultModel?.provider && defaultModel?.model) {
|
|
126
|
-
if (this.config.debug) {
|
|
127
|
-
console.log(`[im-qqbot] ModelResolver: from settings.yaml: ${defaultModel.provider}/${defaultModel.model}`);
|
|
128
|
-
}
|
|
129
173
|
return { provider: defaultModel.provider, model: defaultModel.model };
|
|
130
174
|
}
|
|
131
175
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../src/model-resolver.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../src/model-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -80,7 +80,12 @@ export declare class SessionManager {
|
|
|
80
80
|
*/
|
|
81
81
|
getEffectiveModel(scope: ChatScope, peerId: string): ModelRoute | undefined;
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
83
|
+
* 设置模型偏好并销毁旧 agent(下次消息进来以新 route 创建)
|
|
84
|
+
*
|
|
85
|
+
* route 持久化到隔离偏好文件 ~/.dsh-qqbot/model-prefs.json,
|
|
86
|
+
* 不影响全局 settings.yaml。模型在 agent 创建时固定,因此切换
|
|
87
|
+
* 需销毁旧 session,下次消息重建时以新 route 创建(对齐 dsh-TUI
|
|
88
|
+
* 的"重启生效"语义)。
|
|
84
89
|
*/
|
|
85
90
|
setModelOverride(scope: ChatScope, peerId: string, route: ModelRoute): Promise<void>;
|
|
86
91
|
/**
|
|
@@ -101,16 +106,16 @@ export declare class SessionManager {
|
|
|
101
106
|
private sessionKey;
|
|
102
107
|
/**
|
|
103
108
|
* 从 sessionKey 确定性生成 SessionId
|
|
109
|
+
*
|
|
110
|
+
* 将模型路由纳入派生,这样切换模型会得到不同的 SessionId,
|
|
111
|
+
* 强制创建全新 session(无旧的 live agent、无持久化 requestHeader),
|
|
112
|
+
* 从而让新模型真正生效。未指定路由时保持稳定(宿主默认)。
|
|
104
113
|
*/
|
|
105
114
|
private deriveSessionId;
|
|
106
115
|
/**
|
|
107
116
|
* 组合 preset:解析 preset id 并生成 setup hook
|
|
108
117
|
*/
|
|
109
118
|
private composePreset;
|
|
110
|
-
/**
|
|
111
|
-
* 合并多个 setup hook(按顺序执行)
|
|
112
|
-
*/
|
|
113
|
-
private combineSetups;
|
|
114
119
|
/** 获取或恢复或创建会话(get → resume → create) */
|
|
115
120
|
getOrCreate(scope: ChatScope, peerId: string, senderId: string, replyTarget: ReplyTarget): Promise<SessionRecord>;
|
|
116
121
|
/** 根据 sessionId 查找 record */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/session-manager.js
CHANGED
|
@@ -41,12 +41,17 @@ export class SessionManager {
|
|
|
41
41
|
return this.modelResolver.getEffectiveRoute(this.sessionKey(scope, peerId));
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
44
|
+
* 设置模型偏好并销毁旧 agent(下次消息进来以新 route 创建)
|
|
45
|
+
*
|
|
46
|
+
* route 持久化到隔离偏好文件 ~/.dsh-qqbot/model-prefs.json,
|
|
47
|
+
* 不影响全局 settings.yaml。模型在 agent 创建时固定,因此切换
|
|
48
|
+
* 需销毁旧 session,下次消息重建时以新 route 创建(对齐 dsh-TUI
|
|
49
|
+
* 的"重启生效"语义)。
|
|
45
50
|
*/
|
|
46
51
|
async setModelOverride(scope, peerId, route) {
|
|
47
52
|
const key = this.sessionKey(scope, peerId);
|
|
48
53
|
this.modelResolver.setOverride(key, route);
|
|
49
|
-
// 销毁旧 session
|
|
54
|
+
// 销毁旧 session(下次创建时读到新偏好)
|
|
50
55
|
const record = this.sessions.get(key);
|
|
51
56
|
if (record) {
|
|
52
57
|
this.sessions.delete(key);
|
|
@@ -82,9 +87,14 @@ export class SessionManager {
|
|
|
82
87
|
}
|
|
83
88
|
/**
|
|
84
89
|
* 从 sessionKey 确定性生成 SessionId
|
|
90
|
+
*
|
|
91
|
+
* 将模型路由纳入派生,这样切换模型会得到不同的 SessionId,
|
|
92
|
+
* 强制创建全新 session(无旧的 live agent、无持久化 requestHeader),
|
|
93
|
+
* 从而让新模型真正生效。未指定路由时保持稳定(宿主默认)。
|
|
85
94
|
*/
|
|
86
|
-
deriveSessionId(sessionKey) {
|
|
87
|
-
const
|
|
95
|
+
deriveSessionId(sessionKey, route) {
|
|
96
|
+
const input = route ? `${sessionKey}#${route.provider}/${route.model}` : sessionKey;
|
|
97
|
+
const hash = createHash('sha256').update(input).digest('hex');
|
|
88
98
|
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20, 32)}`;
|
|
89
99
|
}
|
|
90
100
|
/**
|
|
@@ -115,21 +125,6 @@ export class SessionManager {
|
|
|
115
125
|
return {};
|
|
116
126
|
}
|
|
117
127
|
}
|
|
118
|
-
/**
|
|
119
|
-
* 合并多个 setup hook(按顺序执行)
|
|
120
|
-
*/
|
|
121
|
-
combineSetups(...setups) {
|
|
122
|
-
const valid = setups.filter((s) => s !== undefined);
|
|
123
|
-
if (valid.length === 0)
|
|
124
|
-
return undefined;
|
|
125
|
-
if (valid.length === 1)
|
|
126
|
-
return valid[0];
|
|
127
|
-
return async (agentCtx) => {
|
|
128
|
-
for (const setup of valid) {
|
|
129
|
-
await setup(agentCtx);
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
128
|
/** 获取或恢复或创建会话(get → resume → create) */
|
|
134
129
|
async getOrCreate(scope, peerId, senderId, replyTarget) {
|
|
135
130
|
const key = this.sessionKey(scope, peerId);
|
|
@@ -139,20 +134,9 @@ export class SessionManager {
|
|
|
139
134
|
existing.lastActivity = Date.now();
|
|
140
135
|
return existing;
|
|
141
136
|
}
|
|
142
|
-
const sessionId = SessionId(this.deriveSessionId(key));
|
|
143
137
|
const route = this.modelResolver.getEffectiveRoute(key);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const modelSetup = route
|
|
147
|
-
? (agentCtx) => {
|
|
148
|
-
// 注册 agent/request waterfall 中间件,确保我们的 route 最终生效
|
|
149
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
150
|
-
agentCtx.on('agent/request', async (_payload, next) => {
|
|
151
|
-
const resolved = await next();
|
|
152
|
-
return { ...resolved, provider: route.provider, model: route.model };
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
: undefined;
|
|
138
|
+
const sessionId = SessionId(this.deriveSessionId(key, route));
|
|
139
|
+
console.log(`[im-qqbot] getOrCreate: key=${key} route=${route ? `${route.provider}/${route.model}` : 'host-default'} sessionId=${sessionId}`);
|
|
156
140
|
let agent;
|
|
157
141
|
let handle;
|
|
158
142
|
let agentPreset;
|
|
@@ -163,25 +147,23 @@ export class SessionManager {
|
|
|
163
147
|
console.log(`[im-qqbot] reusing live agent: key=${key}`);
|
|
164
148
|
}
|
|
165
149
|
else {
|
|
166
|
-
// 2. 尝试从持久化存储恢复(带 setup hook)
|
|
150
|
+
// 2. 尝试从持久化存储恢复(带 preset setup hook)
|
|
167
151
|
try {
|
|
168
152
|
const composed = await this.composePreset(this.config.preset);
|
|
169
153
|
agentPreset = composed.agentPreset;
|
|
170
|
-
const combinedSetup = this.combineSetups(composed.setup, modelSetup);
|
|
171
154
|
const resumed = await this.agents.resume({
|
|
172
155
|
resumeSessionId: sessionId,
|
|
173
156
|
...(route ? { agentOptions: route } : {}),
|
|
174
|
-
...(
|
|
157
|
+
...(composed.setup ? { setup: composed.setup } : {}),
|
|
175
158
|
});
|
|
176
159
|
agent = resumed.agent;
|
|
177
160
|
handle = resumed;
|
|
178
161
|
console.log(`[im-qqbot] resumed session: key=${key} preset=${agentPreset ?? 'none'}`);
|
|
179
162
|
}
|
|
180
163
|
catch {
|
|
181
|
-
// 3. 恢复失败,创建全新 session(带 setup hook)
|
|
164
|
+
// 3. 恢复失败,创建全新 session(带 preset setup hook)
|
|
182
165
|
const composed = await this.composePreset(this.config.preset);
|
|
183
166
|
agentPreset = composed.agentPreset;
|
|
184
|
-
const combinedSetup = this.combineSetups(composed.setup, modelSetup);
|
|
185
167
|
const created = await this.agents.create({
|
|
186
168
|
sessionId,
|
|
187
169
|
meta: {
|
|
@@ -189,7 +171,7 @@ export class SessionManager {
|
|
|
189
171
|
...(agentPreset ? { agentPreset } : {}),
|
|
190
172
|
},
|
|
191
173
|
...(route ? { agentOptions: route } : {}),
|
|
192
|
-
...(
|
|
174
|
+
...(composed.setup ? { setup: composed.setup } : {}),
|
|
193
175
|
});
|
|
194
176
|
agent = created.agent;
|
|
195
177
|
handle = created;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAIrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAmEpD,MAAM,OAAO,cAAc;IAMN;IACA;IACA;IACA;IARX,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC5C,SAAS,GAA0C,IAAI,CAAC;IAC/C,aAAa,CAAgB;IAE9C,YACmB,GAAY,EACZ,MAAwB,EACxB,MAAqB,EACrB,MAAc;QAHd,QAAG,GAAH,GAAG,CAAS;QACZ,WAAM,GAAN,MAAM,CAAkB;QACxB,WAAM,GAAN,MAAM,CAAe;QACrB,WAAM,GAAN,MAAM,CAAQ;QAE/B,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAEpD,IAAI,MAAM,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,gCAAgC;IAEhC;;OAEG;IACH,iBAAiB,CAAC,KAAgB,EAAE,MAAc;QAChD,OAAO,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAIrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAmEpD,MAAM,OAAO,cAAc;IAMN;IACA;IACA;IACA;IARX,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC5C,SAAS,GAA0C,IAAI,CAAC;IAC/C,aAAa,CAAgB;IAE9C,YACmB,GAAY,EACZ,MAAwB,EACxB,MAAqB,EACrB,MAAc;QAHd,QAAG,GAAH,GAAG,CAAS;QACZ,WAAM,GAAN,MAAM,CAAkB;QACxB,WAAM,GAAN,MAAM,CAAe;QACrB,WAAM,GAAN,MAAM,CAAQ;QAE/B,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAEpD,IAAI,MAAM,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,gCAAgC;IAEhC;;OAEG;IACH,iBAAiB,CAAC,KAAgB,EAAE,MAAc;QAChD,OAAO,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,gBAAgB,CAAC,KAAgB,EAAE,MAAc,EAAE,KAAiB;QACxE,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE3C,0BAA0B;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACtC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,qDAAqD,GAAG,MAAM,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7G,CAAC;IACH,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,KAAgB,EAAE,MAAc;QACjD,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;IAC5C,CAAC;IAED,uBAAuB;IAEvB;;OAEG;IACK,UAAU,CAAC,KAAgB,EAAE,MAAc;QACjD,OAAO,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;IACzD,CAAC;IAED;;;;;;OAMG;IACK,eAAe,CAAC,UAAkB,EAAE,KAAkB;QAC5D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;QACpF,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;IACtH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa,CAAC,QAAiB;QAC3C,IAAI,OAAqC,CAAC;QAC1C,IAAI,CAAC;YACH,OAAO,GAAI,IAAI,CAAC,GAA0C,CAAC,YAA4C,CAAC;QAC1G,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;QAED,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAExB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACjD,MAAM,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC;YAC/B,OAAO;gBACL,WAAW,EAAE,UAAU;gBACvB,KAAK,EAAE,KAAK,EAAE,QAAiB,EAAE,EAAE;oBACjC,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;gBAC5C,CAAC;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,oBAAoB,QAAQ,IAAI,WAAW,iBAAiB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,2BAA2B,CACxI,CAAC;YACF,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,WAAW,CACf,KAAgB,EAChB,MAAc,EACd,QAAgB,EAChB,WAAwB;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAExC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,WAAW,GAAG,WAAW,CAAC;YACnC,QAAQ,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACnC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACxD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,+BAA+B,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,cAAc,cAAc,SAAS,EAAE,CAAC,CAAC;QAE9I,IAAI,KAAe,CAAC;QACpB,IAAI,MAAkC,CAAC;QACvC,IAAI,WAA+B,CAAC;QAEpC,uBAAuB;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,GAAG,IAAI,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,sCAAsC,GAAG,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,qCAAqC;YACrC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC9D,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;gBACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;oBACvC,eAAe,EAAE,SAAS;oBAC1B,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACrD,CAAC,CAAC;gBACH,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;gBACtB,MAAM,GAAG,OAAO,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,mCAAmC,GAAG,WAAW,WAAW,IAAI,MAAM,EAAE,CAAC,CAAC;YACxF,CAAC;YAAC,MAAM,CAAC;gBACP,4CAA4C;gBAC5C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC9D,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;gBACnC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;oBACvC,SAAS;oBACT,IAAI,EAAE;wBACJ,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;wBACrC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACxC;oBACD,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACrD,CAAC,CAAC;gBACH,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;gBACtB,MAAM,GAAG,OAAO,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,uCAAuC,GAAG,WAAW,WAAW,IAAI,MAAM,EAAE,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAkB;YAC5B,UAAU,EAAE,GAAG;YACf,SAAS;YACT,KAAK;YACL,MAAM,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,EAAE;YACpD,WAAW;YACX,KAAK;YACL,MAAM;YACN,QAAQ;YACR,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;YACxB,WAAW;SACZ,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,6BAA6B;IAC7B,eAAe,CAAC,SAAiB;QAC/B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;gBAAE,OAAO,MAAM,CAAC;QACpD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,yBAAyB;IACzB,WAAW,CAAC,KAAe;QACzB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK;gBAAE,OAAO,MAAM,CAAC;QAC5C,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,gBAAgB;IAChB,KAAK,CAAC,MAAM,CAAC,KAAgB,EAAE,MAAc;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,eAAe;IACP,SAAS;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1C,IAAI,GAAG,GAAG,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC/D,OAAO,CAAC,GAAG,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAC;gBAC5D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC1B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBACtC,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,2CAA2C,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5E,CAAC;IAED,cAAc;IACd,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;CACF"}
|