keepwork-sdk 1.0.0 → 1.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-npm/keepwork-sdk.js +823 -122
- package/dist-npm/keepwork-sdk.js.map +1 -1
- package/dist-npm/types/src/ai-chat/AIChat.d.ts +0 -1
- package/dist-npm/types/src/ai-chat/AIChat.d.ts.map +1 -1
- package/dist-npm/types/src/ai-chat/AIChat.session.d.ts +14 -0
- package/dist-npm/types/src/ai-chat/AIChat.session.d.ts.map +1 -1
- package/dist-npm/types/src/core/keepworkSDK.core.d.ts.map +1 -1
- package/dist-npm/types/src/core/keepworkSDK.d.ts +80 -0
- package/dist-npm/types/src/core/keepworkSDK.d.ts.map +1 -1
- package/dist-npm/types/src/rtc/AIChatRTC.d.ts.map +1 -1
- package/dist-npm/types/src/rtc/AIChatRTC.session.d.ts +13 -0
- package/dist-npm/types/src/rtc/AIChatRTC.session.d.ts.map +1 -1
- package/dist-npm/types/src/rtc/AIChatRTCLocal.core.d.ts.map +1 -1
- package/dist-npm/types/src/rtc/AIChatRTCLocal.d.ts +0 -1
- package/dist-npm/types/src/rtc/AIChatRTCLocal.d.ts.map +1 -1
- package/dist-npm/types/src/rtc/AIChatRTCLocal.session.d.ts +10 -0
- package/dist-npm/types/src/rtc/AIChatRTCLocal.session.d.ts.map +1 -1
- package/dist-npm/types/src/ui/LocalAPIKeySettings.d.ts.map +1 -1
- package/dist-npm/types/src/ui/LoginWindow.d.ts +23 -0
- package/dist-npm/types/src/ui/LoginWindow.d.ts.map +1 -1
- package/package.json +10 -3
- /package/{README.md → readme.md} +0 -0
package/dist-npm/keepwork-sdk.js
CHANGED
|
@@ -887,7 +887,7 @@ if (typeof window !== "undefined") {
|
|
|
887
887
|
window.LocalStorageUtil = LocalStorageUtil;
|
|
888
888
|
window.StorageUtil = StorageUtil;
|
|
889
889
|
}
|
|
890
|
-
const console$
|
|
890
|
+
const console$p = SDKLogger.createModuleConsole("PersonalPageStore");
|
|
891
891
|
class PersonalPageStoreBase {
|
|
892
892
|
constructor(sdk) {
|
|
893
893
|
// ──────────────────── 字段 ────────────────────
|
|
@@ -970,7 +970,7 @@ class PersonalPageStoreBase {
|
|
|
970
970
|
try {
|
|
971
971
|
handler(...args);
|
|
972
972
|
} catch (e) {
|
|
973
|
-
console$
|
|
973
|
+
console$p.warn(`PersonalPageStore: listener for '${event}' threw:`, e);
|
|
974
974
|
}
|
|
975
975
|
}
|
|
976
976
|
}
|
|
@@ -1087,7 +1087,7 @@ class PersonalPageStoreBase {
|
|
|
1087
1087
|
if (typeof mountedFolder === "string") {
|
|
1088
1088
|
const parts = mountedFolder.replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
|
|
1089
1089
|
if (parts.length < 2) {
|
|
1090
|
-
console$
|
|
1090
|
+
console$p.warn("PersonalPageStore: mountedFolder path requires at least username/workspace");
|
|
1091
1091
|
return null;
|
|
1092
1092
|
}
|
|
1093
1093
|
const username = parts[0];
|
|
@@ -1098,7 +1098,7 @@ class PersonalPageStoreBase {
|
|
|
1098
1098
|
if (typeof mountedFolder === "object" && mountedFolder !== null) {
|
|
1099
1099
|
const m = mountedFolder;
|
|
1100
1100
|
if (!m["username"] || !m["workspace"]) {
|
|
1101
|
-
console$
|
|
1101
|
+
console$p.warn("PersonalPageStore: mountedFolder object requires username and workspace");
|
|
1102
1102
|
return null;
|
|
1103
1103
|
}
|
|
1104
1104
|
return {
|
|
@@ -1107,7 +1107,7 @@ class PersonalPageStoreBase {
|
|
|
1107
1107
|
remoteStorePath: m["remoteStorePath"] ?? this.remoteStorePath
|
|
1108
1108
|
};
|
|
1109
1109
|
}
|
|
1110
|
-
console$
|
|
1110
|
+
console$p.warn("PersonalPageStore: mountedFolder must be a path string, object, or null");
|
|
1111
1111
|
return null;
|
|
1112
1112
|
}
|
|
1113
1113
|
// ──────────────────── SearchPath ────────────────────
|
|
@@ -1127,10 +1127,10 @@ class PersonalPageStoreBase {
|
|
|
1127
1127
|
if (existing) {
|
|
1128
1128
|
existing.baseUrl = normalizedBaseUrl;
|
|
1129
1129
|
existing.isReadonly = isReadonly;
|
|
1130
|
-
console$
|
|
1130
|
+
console$p.log(`[PersonalPageStore] Updated search path: ${normalizedPrefix} -> ${normalizedBaseUrl} (readonly=${isReadonly})`);
|
|
1131
1131
|
} else {
|
|
1132
1132
|
this._searchPaths.push({ prefix: normalizedPrefix, baseUrl: normalizedBaseUrl, isReadonly });
|
|
1133
|
-
console$
|
|
1133
|
+
console$p.log(`[PersonalPageStore] Added search path: ${normalizedPrefix} -> ${normalizedBaseUrl} (readonly=${isReadonly})`);
|
|
1134
1134
|
}
|
|
1135
1135
|
}
|
|
1136
1136
|
/**
|
|
@@ -1184,7 +1184,7 @@ class PersonalPageStoreBase {
|
|
|
1184
1184
|
if (!resp.ok) continue;
|
|
1185
1185
|
const text = await resp.text();
|
|
1186
1186
|
if (text != null) {
|
|
1187
|
-
console$
|
|
1187
|
+
console$p.log(`[PersonalPageStore] SearchPath found: ${effectiveName} -> ${fileUrl}`);
|
|
1188
1188
|
const pageKey = this._toInternalPageKey(pageName);
|
|
1189
1189
|
this.personalPageData[pageKey] = this.personalPageData[pageKey] ?? {};
|
|
1190
1190
|
this.setValueByPath(this.personalPageData[pageKey], "content", text);
|
|
@@ -1193,7 +1193,7 @@ class PersonalPageStoreBase {
|
|
|
1193
1193
|
} catch {
|
|
1194
1194
|
}
|
|
1195
1195
|
}
|
|
1196
|
-
console$
|
|
1196
|
+
console$p.log(`[PersonalPageStore] SearchPath not found: ${effectiveName}`);
|
|
1197
1197
|
this._searchPathNotFound.add(effectiveName);
|
|
1198
1198
|
return null;
|
|
1199
1199
|
}
|
|
@@ -1457,7 +1457,7 @@ class PersonalPageStoreBase {
|
|
|
1457
1457
|
const newUsername = username || null;
|
|
1458
1458
|
if (this.overrideUsername !== newUsername) this.reset();
|
|
1459
1459
|
this.overrideUsername = newUsername;
|
|
1460
|
-
console$
|
|
1460
|
+
console$p.log(`PersonalPageStore: Override username set to: ${this.overrideUsername ?? "current user"}`);
|
|
1461
1461
|
}
|
|
1462
1462
|
/**
|
|
1463
1463
|
* 获取当前使用的用户名(override 或当前登录用户)。
|
|
@@ -1503,7 +1503,7 @@ class PersonalPageStoreBase {
|
|
|
1503
1503
|
if (this.userProfileLoaded) return;
|
|
1504
1504
|
try {
|
|
1505
1505
|
if (!this.sdk.token) {
|
|
1506
|
-
console$
|
|
1506
|
+
console$p.log("personalPageStore: No token set, using anonymous mode");
|
|
1507
1507
|
return;
|
|
1508
1508
|
}
|
|
1509
1509
|
await ((_b2 = (_a2 = this.sdk).getUserProfile) == null ? void 0 : _b2.call(_a2, { useCache: true }));
|
|
@@ -4579,7 +4579,7 @@ class AudioEngine {
|
|
|
4579
4579
|
};
|
|
4580
4580
|
}
|
|
4581
4581
|
}
|
|
4582
|
-
const console$
|
|
4582
|
+
const console$o = SDKLogger.createModuleConsole("Speech");
|
|
4583
4583
|
let _md5 = null;
|
|
4584
4584
|
async function getMd5() {
|
|
4585
4585
|
if (_md5) return _md5;
|
|
@@ -4651,7 +4651,7 @@ class Speech {
|
|
|
4651
4651
|
if (valid.includes(mode)) {
|
|
4652
4652
|
this.fallbackMode = mode;
|
|
4653
4653
|
} else {
|
|
4654
|
-
console$
|
|
4654
|
+
console$o.warn(`Invalid fallbackMode "${mode}", expected one of: ${valid.join(", ")}`);
|
|
4655
4655
|
}
|
|
4656
4656
|
}
|
|
4657
4657
|
/** 获取共享 AudioEngine 实例(优先 sdk.audioEngine,否则 AudioEngine.getShared())。 */
|
|
@@ -4684,7 +4684,7 @@ class Speech {
|
|
|
4684
4684
|
}
|
|
4685
4685
|
const OfflineCtx = typeof window !== "undefined" ? window.OfflineAudioContext || window.webkitOfflineAudioContext : null;
|
|
4686
4686
|
if (!OfflineCtx) {
|
|
4687
|
-
console$
|
|
4687
|
+
console$o.warn("当前浏览器不支持 OfflineAudioContext,返回原始采样率音频");
|
|
4688
4688
|
return audioBuffer;
|
|
4689
4689
|
}
|
|
4690
4690
|
const frameCount = Math.max(1, Math.ceil(audioBuffer.duration * nextSampleRate));
|
|
@@ -5013,7 +5013,7 @@ class Speech {
|
|
|
5013
5013
|
}
|
|
5014
5014
|
});
|
|
5015
5015
|
} catch (error) {
|
|
5016
|
-
console$
|
|
5016
|
+
console$o.error("停止音频播放时发生错误:", error);
|
|
5017
5017
|
}
|
|
5018
5018
|
}
|
|
5019
5019
|
/** 停止所有音频(stopAllAudio 的别名)。 */
|
|
@@ -5038,10 +5038,10 @@ class Speech {
|
|
|
5038
5038
|
audio.src = audioUrl;
|
|
5039
5039
|
void ((_b2 = (_a2 = this.resumeSharedAudioEngine()) == null ? void 0 : _a2.finally) == null ? void 0 : _b2.call(_a2, () => {
|
|
5040
5040
|
const p = audio.play();
|
|
5041
|
-
if (p) p.catch((err) => console$
|
|
5041
|
+
if (p) p.catch((err) => console$o.error("Error playing YouDao audio:", err));
|
|
5042
5042
|
}));
|
|
5043
5043
|
} catch (e) {
|
|
5044
|
-
console$
|
|
5044
|
+
console$o.error("Error with YouDao API:", e);
|
|
5045
5045
|
}
|
|
5046
5046
|
}
|
|
5047
5047
|
// ──────────────────── 语音转文字(STT)────────────────────
|
|
@@ -5058,10 +5058,10 @@ class Speech {
|
|
|
5058
5058
|
maxDuration: 60,
|
|
5059
5059
|
sampleRate: 16e3,
|
|
5060
5060
|
format: "wav",
|
|
5061
|
-
onStart: () => console$
|
|
5062
|
-
onStop: () => console$
|
|
5063
|
-
onError: (e) => console$
|
|
5064
|
-
onResult: (r) => console$
|
|
5061
|
+
onStart: () => console$o.log("录音开始"),
|
|
5062
|
+
onStop: () => console$o.log("录音停止"),
|
|
5063
|
+
onError: (e) => console$o.error("录音错误:", e),
|
|
5064
|
+
onResult: (r) => console$o.log("识别结果:", r),
|
|
5065
5065
|
...options
|
|
5066
5066
|
};
|
|
5067
5067
|
if (!((_a2 = navigator.mediaDevices) == null ? void 0 : _a2.getUserMedia)) throw new Error("当前浏览器不支持录音功能,请使用现代浏览器并确保在HTTPS环境下访问");
|
|
@@ -5295,7 +5295,7 @@ class Speech {
|
|
|
5295
5295
|
});
|
|
5296
5296
|
}
|
|
5297
5297
|
}
|
|
5298
|
-
const console$
|
|
5298
|
+
const console$n = SDKLogger.createModuleConsole("MqttManager");
|
|
5299
5299
|
class MqttManager {
|
|
5300
5300
|
constructor() {
|
|
5301
5301
|
__publicField(this, "client", null);
|
|
@@ -5367,11 +5367,11 @@ class MqttManager {
|
|
|
5367
5367
|
}
|
|
5368
5368
|
}
|
|
5369
5369
|
} catch (e) {
|
|
5370
|
-
console$
|
|
5370
|
+
console$n.error("Failed to load MQTT config from storage:", e);
|
|
5371
5371
|
}
|
|
5372
5372
|
}
|
|
5373
5373
|
if (!effectiveConfig) {
|
|
5374
|
-
console$
|
|
5374
|
+
console$n.error("MQTT connect: No config provided and no stored config");
|
|
5375
5375
|
this.status = "error";
|
|
5376
5376
|
this.emit("statusChange", this.status);
|
|
5377
5377
|
return;
|
|
@@ -5379,7 +5379,7 @@ class MqttManager {
|
|
|
5379
5379
|
try {
|
|
5380
5380
|
await this.LoadMQTT();
|
|
5381
5381
|
} catch (e) {
|
|
5382
|
-
console$
|
|
5382
|
+
console$n.error("Failed to load MQTT library:", e);
|
|
5383
5383
|
this.status = "error";
|
|
5384
5384
|
this.emit("statusChange", this.status);
|
|
5385
5385
|
return;
|
|
@@ -5403,7 +5403,7 @@ class MqttManager {
|
|
|
5403
5403
|
reconnectPeriod: 5e3,
|
|
5404
5404
|
connectTimeout: 30 * 1e3
|
|
5405
5405
|
};
|
|
5406
|
-
console$
|
|
5406
|
+
console$n.log("Connecting to MQTT with options:", connectOptions);
|
|
5407
5407
|
try {
|
|
5408
5408
|
this.client = mqtt.connect(connectOptions);
|
|
5409
5409
|
this.client.on("connect", () => {
|
|
@@ -5411,7 +5411,7 @@ class MqttManager {
|
|
|
5411
5411
|
topics == null ? void 0 : topics.forEach((topic) => this.subscribe(topic));
|
|
5412
5412
|
});
|
|
5413
5413
|
this.client.on("error", (err) => {
|
|
5414
|
-
console$
|
|
5414
|
+
console$n.error("MQTT Error:", err);
|
|
5415
5415
|
this.status = "error";
|
|
5416
5416
|
this.emit("statusChange", this.status);
|
|
5417
5417
|
this.emit("error", err);
|
|
@@ -5425,7 +5425,7 @@ class MqttManager {
|
|
|
5425
5425
|
this.client.on("reconnect", () => {
|
|
5426
5426
|
var _a3;
|
|
5427
5427
|
this.retryCount++;
|
|
5428
|
-
console$
|
|
5428
|
+
console$n.log(`MQTT Reconnecting... (${this.retryCount}/${this.maxRetries})`);
|
|
5429
5429
|
if (this.retryCount > this.maxRetries) {
|
|
5430
5430
|
(_a3 = this.client) == null ? void 0 : _a3.end();
|
|
5431
5431
|
this.status = "error";
|
|
@@ -5434,21 +5434,21 @@ class MqttManager {
|
|
|
5434
5434
|
}
|
|
5435
5435
|
});
|
|
5436
5436
|
} catch (e) {
|
|
5437
|
-
console$
|
|
5437
|
+
console$n.error("MQTT Connection Exception:", e);
|
|
5438
5438
|
this.status = "error";
|
|
5439
5439
|
this.emit("statusChange", this.status);
|
|
5440
5440
|
}
|
|
5441
5441
|
}
|
|
5442
5442
|
/** @private 连接成功回调。 */
|
|
5443
5443
|
OnConnect() {
|
|
5444
|
-
console$
|
|
5444
|
+
console$n.log("MQTT Connected");
|
|
5445
5445
|
this.status = "connected";
|
|
5446
5446
|
this.retryCount = 0;
|
|
5447
5447
|
this.emit("statusChange", this.status);
|
|
5448
5448
|
}
|
|
5449
5449
|
/** @private 连接关闭回调。 */
|
|
5450
5450
|
OnClose() {
|
|
5451
|
-
console$
|
|
5451
|
+
console$n.log("MQTT Closed");
|
|
5452
5452
|
if (this.status !== "disconnected") {
|
|
5453
5453
|
this.status = "disconnected";
|
|
5454
5454
|
this.emit("statusChange", this.status);
|
|
@@ -5459,7 +5459,7 @@ class MqttManager {
|
|
|
5459
5459
|
*/
|
|
5460
5460
|
OnMessage(topic, message) {
|
|
5461
5461
|
const msgStr = String(message);
|
|
5462
|
-
console$
|
|
5462
|
+
console$n.log(`message ${msgStr}
|
|
5463
5463
|
On topic: ${topic}`);
|
|
5464
5464
|
localStorage.setItem(`mqtt_msg_${topic}`, msgStr);
|
|
5465
5465
|
this.emit("message", { topic, message: msgStr });
|
|
@@ -5486,7 +5486,7 @@ On topic: ${topic}`);
|
|
|
5486
5486
|
var _a2;
|
|
5487
5487
|
if ((_a2 = this.client) == null ? void 0 : _a2.connected) {
|
|
5488
5488
|
this.client.subscribe(topic, (err) => {
|
|
5489
|
-
if (!err) console$
|
|
5489
|
+
if (!err) console$n.log(`Subscribed to ${topic}`);
|
|
5490
5490
|
});
|
|
5491
5491
|
}
|
|
5492
5492
|
}
|
|
@@ -6282,7 +6282,7 @@ class SandboxToolEnv {
|
|
|
6282
6282
|
});
|
|
6283
6283
|
}
|
|
6284
6284
|
}
|
|
6285
|
-
const console$
|
|
6285
|
+
const console$m = SDKLogger.createModuleConsole("AgentTool");
|
|
6286
6286
|
class AgentTool {
|
|
6287
6287
|
constructor(sdk) {
|
|
6288
6288
|
__publicField(this, "sdk");
|
|
@@ -6322,7 +6322,7 @@ class AgentTool {
|
|
|
6322
6322
|
} = args;
|
|
6323
6323
|
if (!task) return "Failed: 'task' is a required parameter.";
|
|
6324
6324
|
const resolvedAgentName = agentName || this.currentAgentName(session);
|
|
6325
|
-
console$
|
|
6325
|
+
console$m.log(`[CopilotTools] runAsyncAgentTask session='${session.name ?? "root"}' target='${resolvedAgentName}' callbackMode=${callbackMode ?? "delay"} task=${this.summarizeDebugValue(task)}`);
|
|
6326
6326
|
const expandedTask = await this.expandTemplate(session, task, "task");
|
|
6327
6327
|
const expandedSystemPrompt = await this.expandTemplate(session, systemPrompt, "systemPrompt");
|
|
6328
6328
|
const router = (_a2 = this.sdk) == null ? void 0 : _a2.agentRouter;
|
|
@@ -6447,11 +6447,11 @@ class AgentTool {
|
|
|
6447
6447
|
if (!value.includes("${") && !/^\s*\/\S+/.test(value)) return value;
|
|
6448
6448
|
try {
|
|
6449
6449
|
const expanded = await session.sandbox.processTemplate(value);
|
|
6450
|
-
console$
|
|
6450
|
+
console$m.log(`[CopilotTools] runAsyncAgentTask ${label} expanded via sandbox: ${this.summarizeDebugValue(expanded)}`);
|
|
6451
6451
|
return expanded;
|
|
6452
6452
|
} catch (e) {
|
|
6453
6453
|
if (e && e["isRestartAgentSignal"]) throw e;
|
|
6454
|
-
console$
|
|
6454
|
+
console$m.warn(`[CopilotTools] runAsyncAgentTask: ${label} template expansion failed. Error: ${e.message}`);
|
|
6455
6455
|
return value;
|
|
6456
6456
|
}
|
|
6457
6457
|
}
|
|
@@ -6493,7 +6493,7 @@ ${resultText}`;
|
|
|
6493
6493
|
try {
|
|
6494
6494
|
await ((_a3 = target == null ? void 0 : target["sendMessage"]) == null ? void 0 : _a3.call(target, payload));
|
|
6495
6495
|
} catch (e) {
|
|
6496
|
-
console$
|
|
6496
|
+
console$m.error(`[CopilotTools] ${targetLabel}.sendMessage failed:`, e);
|
|
6497
6497
|
}
|
|
6498
6498
|
}).catch(async (e) => {
|
|
6499
6499
|
var _a3;
|
|
@@ -6501,7 +6501,7 @@ ${resultText}`;
|
|
|
6501
6501
|
try {
|
|
6502
6502
|
await ((_a3 = target == null ? void 0 : target["sendMessage"]) == null ? void 0 : _a3.call(target, payload));
|
|
6503
6503
|
} catch (e2) {
|
|
6504
|
-
console$
|
|
6504
|
+
console$m.error(`[CopilotTools] ${targetLabel}.sendMessage failed:`, e2);
|
|
6505
6505
|
}
|
|
6506
6506
|
});
|
|
6507
6507
|
return `Task submitted to agent '${agentName}'. The agent is working in a brand-new background session. Results will be delivered as a message via ${targetLabel} when complete.`;
|
|
@@ -6587,7 +6587,7 @@ __publicField(AgentTool, "definitions", [
|
|
|
6587
6587
|
}
|
|
6588
6588
|
}
|
|
6589
6589
|
]);
|
|
6590
|
-
const console$
|
|
6590
|
+
const console$l = SDKLogger.createModuleConsole("PersonalPageTool");
|
|
6591
6591
|
class PersonalPageTool {
|
|
6592
6592
|
constructor(sdk) {
|
|
6593
6593
|
__publicField(this, "sdk");
|
|
@@ -6630,19 +6630,19 @@ class PersonalPageTool {
|
|
|
6630
6630
|
}
|
|
6631
6631
|
if (name === "personal_page_load") {
|
|
6632
6632
|
try {
|
|
6633
|
-
console$
|
|
6633
|
+
console$l.log(`[PersonalPageTool] Loading data from file '${filePageName}', key '${storageKey}'`);
|
|
6634
6634
|
if (!this.sdk.personalPageStore) throw new Error("SDK PersonalPageStore not available");
|
|
6635
6635
|
const data = storageKey ? await this.sdk.personalPageStore.loadPageData(filePageName, storageKey) : await this.sdk.personalPageStore.loadPageData(filePageName);
|
|
6636
6636
|
return JSON.stringify(data);
|
|
6637
6637
|
} catch (e) {
|
|
6638
|
-
console$
|
|
6638
|
+
console$l.error("[PersonalPageTool] Load failed:", e);
|
|
6639
6639
|
return `Failed to load data: ${e.message}`;
|
|
6640
6640
|
}
|
|
6641
6641
|
}
|
|
6642
6642
|
if (name === "personal_page_save") {
|
|
6643
6643
|
const { data, bForceFlush } = args;
|
|
6644
6644
|
try {
|
|
6645
|
-
console$
|
|
6645
|
+
console$l.log(`[PersonalPageTool] Saving data to file '${filePageName}', key '${storageKey}'`, data);
|
|
6646
6646
|
if (!this.sdk.personalPageStore) throw new Error("SDK PersonalPageStore not available");
|
|
6647
6647
|
await this.sdk.personalPageStore.savePageData(
|
|
6648
6648
|
filePageName,
|
|
@@ -6652,7 +6652,7 @@ class PersonalPageTool {
|
|
|
6652
6652
|
);
|
|
6653
6653
|
return "Data saved successfully.";
|
|
6654
6654
|
} catch (e) {
|
|
6655
|
-
console$
|
|
6655
|
+
console$l.error("[PersonalPageTool] Save failed:", e);
|
|
6656
6656
|
return `Failed to save data: ${e.message}`;
|
|
6657
6657
|
}
|
|
6658
6658
|
}
|
|
@@ -6712,7 +6712,7 @@ __publicField(PersonalPageTool, "definitions", [
|
|
|
6712
6712
|
}
|
|
6713
6713
|
}
|
|
6714
6714
|
]);
|
|
6715
|
-
const console$
|
|
6715
|
+
const console$k = SDKLogger.createModuleConsole("ExecuteTool");
|
|
6716
6716
|
const AsyncFunction = Object.getPrototypeOf(async function() {
|
|
6717
6717
|
}).constructor;
|
|
6718
6718
|
class ExecuteTool {
|
|
@@ -6762,7 +6762,7 @@ class ExecuteTool {
|
|
|
6762
6762
|
async runAppCmd(code, config = {}) {
|
|
6763
6763
|
const logs = [];
|
|
6764
6764
|
try {
|
|
6765
|
-
const originalConsole = console$
|
|
6765
|
+
const originalConsole = console$k;
|
|
6766
6766
|
const wrappedConsole = Object.create(originalConsole);
|
|
6767
6767
|
const consoleMethods = ["log", "info", "warn", "error", "debug"];
|
|
6768
6768
|
for (const level of consoleMethods) {
|
|
@@ -7901,7 +7901,7 @@ __publicField(AppTools, "definitions", [
|
|
|
7901
7901
|
}
|
|
7902
7902
|
}
|
|
7903
7903
|
]);
|
|
7904
|
-
const console$
|
|
7904
|
+
const console$j = SDKLogger.createModuleConsole("AIChat");
|
|
7905
7905
|
class AIChat {
|
|
7906
7906
|
constructor(sdk) {
|
|
7907
7907
|
__publicField(this, "sdk");
|
|
@@ -7993,7 +7993,7 @@ class AIChat {
|
|
|
7993
7993
|
try {
|
|
7994
7994
|
token = window.localStorage.getItem("token");
|
|
7995
7995
|
} catch (e) {
|
|
7996
|
-
console$
|
|
7996
|
+
console$j.warn("Failed to get token from localStorage:", e);
|
|
7997
7997
|
}
|
|
7998
7998
|
}
|
|
7999
7999
|
if (token) headers["authorization"] = `Bearer ${token}`;
|
|
@@ -8107,7 +8107,7 @@ class AIChat {
|
|
|
8107
8107
|
const session = options._session;
|
|
8108
8108
|
for (const toolCall of toolCalls) {
|
|
8109
8109
|
if (session == null ? void 0 : session._restartSignal) {
|
|
8110
|
-
console$
|
|
8110
|
+
console$j.log("[AIChat] _restartSignal detected, aborting tool loop");
|
|
8111
8111
|
break;
|
|
8112
8112
|
}
|
|
8113
8113
|
const fnName = (_d = toolCall.function) == null ? void 0 : _d.name;
|
|
@@ -8120,14 +8120,14 @@ class AIChat {
|
|
|
8120
8120
|
if (session) session["_restartSignal"] = error;
|
|
8121
8121
|
throw error;
|
|
8122
8122
|
}
|
|
8123
|
-
console$
|
|
8123
|
+
console$j.error("Tool call execution failed:", error);
|
|
8124
8124
|
const errorResult = { error: error.message ?? "Tool execution failed" };
|
|
8125
8125
|
toolResults.push({ tool_call_id: toolCall.id, result: errorResult });
|
|
8126
8126
|
(_f = options.onToolResult) == null ? void 0 : _f.call(options, { name: fnName, toolCallId: toolCall.id, result: errorResult });
|
|
8127
8127
|
}
|
|
8128
8128
|
}
|
|
8129
8129
|
if (session == null ? void 0 : session._restartSignal) {
|
|
8130
|
-
console$
|
|
8130
|
+
console$j.log("[AIChat] _restartSignal detected, aborting chat recursion");
|
|
8131
8131
|
return assistantContent ?? "";
|
|
8132
8132
|
}
|
|
8133
8133
|
for (const toolResult of toolResults) {
|
|
@@ -8204,7 +8204,7 @@ class AIChat {
|
|
|
8204
8204
|
throw new Error("createSession not yet initialized — ensure AIChat.session.ts is imported");
|
|
8205
8205
|
}
|
|
8206
8206
|
}
|
|
8207
|
-
const console$
|
|
8207
|
+
const console$i = SDKLogger.createModuleConsole("ChildSessionMixin");
|
|
8208
8208
|
function _generateUUID() {
|
|
8209
8209
|
if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID();
|
|
8210
8210
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
@@ -8275,7 +8275,7 @@ const childSessionMethods = {
|
|
|
8275
8275
|
if (this.sandbox) childSession["sandbox"] = this.sandbox;
|
|
8276
8276
|
const entry = { session: childSession, queue: [], isRunning: false };
|
|
8277
8277
|
this._childSessions[name] = entry;
|
|
8278
|
-
console$
|
|
8278
|
+
console$i.log(`[ChildSessionMixin] Child agent '${name}' created`);
|
|
8279
8279
|
return entry;
|
|
8280
8280
|
},
|
|
8281
8281
|
/**
|
|
@@ -8302,7 +8302,7 @@ const childSessionMethods = {
|
|
|
8302
8302
|
2. ${task}`;
|
|
8303
8303
|
if (tools) last.tools = [.../* @__PURE__ */ new Set([...last.tools, ...tools])];
|
|
8304
8304
|
last.maxIterations = Math.max(last.maxIterations, maxIterations);
|
|
8305
|
-
console$
|
|
8305
|
+
console$i.log(`[ChildSessionMixin] Merged task into queue for child '${name}'`);
|
|
8306
8306
|
return last.promise;
|
|
8307
8307
|
}
|
|
8308
8308
|
let resolve;
|
|
@@ -8377,15 +8377,15 @@ const childSessionMethods = {
|
|
|
8377
8377
|
const result = typeof response === "string" ? response : (response == null ? void 0 : response["result"]) ?? "";
|
|
8378
8378
|
const taskSummary = taskObj.description ?? (taskObj.task.length > 80 ? taskObj.task.slice(0, 80) + "..." : taskObj.task);
|
|
8379
8379
|
this._pendingChildResults.push({ agentName: name, taskId: taskObj.id, taskSummary, result });
|
|
8380
|
-
console$
|
|
8380
|
+
console$i.log(`[ChildSessionMixin] Child '${name}' completed task ${taskObj.id}; pendingChildResults=${this._pendingChildResults.length}; result=${_summarize(result)}`);
|
|
8381
8381
|
(_h = self._handleChildCallback) == null ? void 0 : _h.call(self, taskObj.callbackMode, taskObj.debounceSeconds);
|
|
8382
8382
|
taskObj.resolve(result);
|
|
8383
8383
|
} catch (e) {
|
|
8384
|
-
console$
|
|
8384
|
+
console$i.error(`[ChildSessionMixin] Child '${name}' task ${taskObj.id} failed:`, e);
|
|
8385
8385
|
const errorResult = { error: e.message ?? "Child agent task failed" };
|
|
8386
8386
|
const taskSummary = taskObj.description ?? (taskObj.task.length > 80 ? taskObj.task.slice(0, 80) + "..." : taskObj.task);
|
|
8387
8387
|
this._pendingChildResults.push({ agentName: name, taskId: taskObj.id, taskSummary, result: errorResult });
|
|
8388
|
-
console$
|
|
8388
|
+
console$i.warn(`[ChildSessionMixin] Child '${name}' failure queued; taskId=${taskObj.id}; pendingChildResults=${this._pendingChildResults.length}; result=${_summarize(errorResult)}`);
|
|
8389
8389
|
(_i = self._handleChildCallback) == null ? void 0 : _i.call(self, taskObj.callbackMode, taskObj.debounceSeconds);
|
|
8390
8390
|
taskObj.reject(e);
|
|
8391
8391
|
}
|
|
@@ -8415,7 +8415,7 @@ const childSessionMethods = {
|
|
|
8415
8415
|
try {
|
|
8416
8416
|
this.onChildStream(event);
|
|
8417
8417
|
} catch (e) {
|
|
8418
|
-
console$
|
|
8418
|
+
console$i.warn("[ChildSessionMixin] onChildStream callback error:", e);
|
|
8419
8419
|
}
|
|
8420
8420
|
}
|
|
8421
8421
|
},
|
|
@@ -8435,7 +8435,7 @@ const childSessionMethods = {
|
|
|
8435
8435
|
const results = this._pendingChildResults;
|
|
8436
8436
|
this._pendingChildResults = [];
|
|
8437
8437
|
if (results.length > 0) {
|
|
8438
|
-
console$
|
|
8438
|
+
console$i.log(
|
|
8439
8439
|
`[ChildSessionMixin] _consumePendingChildResults session='${this.name ?? "root"}' consumed ${results.length} result(s): ` + results.map((item) => `${item.agentName}:${item.taskId}:${_summarize(item.result, 80)}`).join(" | ")
|
|
8440
8440
|
);
|
|
8441
8441
|
}
|
|
@@ -8452,7 +8452,7 @@ const childSessionMethods = {
|
|
|
8452
8452
|
*/
|
|
8453
8453
|
_handleChildCallback(mode, debounceSeconds) {
|
|
8454
8454
|
var _a2, _b2;
|
|
8455
|
-
console$
|
|
8455
|
+
console$i.log(
|
|
8456
8456
|
`[ChildSessionMixin] _handleChildCallback session='${this.name ?? "root"}' mode=${mode ?? "delay"} debounceSeconds=${debounceSeconds ?? 5} pendingChildResults=${this._pendingChildResults.length}`
|
|
8457
8457
|
);
|
|
8458
8458
|
const selfCb = this;
|
|
@@ -8468,7 +8468,7 @@ const childSessionMethods = {
|
|
|
8468
8468
|
* @private
|
|
8469
8469
|
*/
|
|
8470
8470
|
async _triggerImmediateCallback() {
|
|
8471
|
-
console$
|
|
8471
|
+
console$i.warn("[ChildSessionMixin] _triggerImmediateCallback not overridden — child results will accumulate until next send.");
|
|
8472
8472
|
},
|
|
8473
8473
|
/**
|
|
8474
8474
|
* 延迟执行 `_triggerImmediateCallback`(用于 debounce 模式)。
|
|
@@ -8481,7 +8481,7 @@ const childSessionMethods = {
|
|
|
8481
8481
|
await this._triggerImmediateCallback();
|
|
8482
8482
|
}, seconds * 1e3);
|
|
8483
8483
|
this._debounceTimers.push(timerId);
|
|
8484
|
-
console$
|
|
8484
|
+
console$i.log(`[ChildSessionMixin] Debounce callback set: ${seconds}s pendingChildResults=${this._pendingChildResults.length}`);
|
|
8485
8485
|
},
|
|
8486
8486
|
/**
|
|
8487
8487
|
* 取消所有待处理的 debounce 定时器。
|
|
@@ -8535,7 +8535,7 @@ const childSessionMethods = {
|
|
|
8535
8535
|
this._pendingChildResults = [];
|
|
8536
8536
|
}
|
|
8537
8537
|
};
|
|
8538
|
-
const console$
|
|
8538
|
+
const console$h = SDKLogger.createModuleConsole("ImageUtils");
|
|
8539
8539
|
const DEFAULT_MAX_BYTES = 32 * 1024;
|
|
8540
8540
|
function base64ByteSize(base64) {
|
|
8541
8541
|
const len = base64.length;
|
|
@@ -8578,7 +8578,7 @@ async function compressBase64Image(inputBase64, options = {}) {
|
|
|
8578
8578
|
for (const quality of QUALITY_STEPS) {
|
|
8579
8579
|
const result = canvasToBase64(img, width, height, quality);
|
|
8580
8580
|
if (result.byteSize <= maxBytes) {
|
|
8581
|
-
console$
|
|
8581
|
+
console$h.log(
|
|
8582
8582
|
`[ImageUtils] Compressed image: ${width}x${height} q=${quality} → ${(result.byteSize / 1024).toFixed(1)} KB`
|
|
8583
8583
|
);
|
|
8584
8584
|
return result.base64;
|
|
@@ -8588,11 +8588,34 @@ async function compressBase64Image(inputBase64, options = {}) {
|
|
|
8588
8588
|
height = Math.max(1, Math.floor(height / 2));
|
|
8589
8589
|
}
|
|
8590
8590
|
const final = canvasToBase64(img, width, height, 0.2);
|
|
8591
|
-
console$
|
|
8591
|
+
console$h.warn(
|
|
8592
8592
|
`[ImageUtils] Could not compress below ${maxBytes} bytes; final size ${final.byteSize}`
|
|
8593
8593
|
);
|
|
8594
8594
|
return final.base64;
|
|
8595
8595
|
}
|
|
8596
|
+
async function compressDataURI(dataURI, options = {}) {
|
|
8597
|
+
const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
8598
|
+
const { mimeType, base64 } = splitDataURI(dataURI);
|
|
8599
|
+
if (base64ByteSize(base64) <= maxBytes) return dataURI;
|
|
8600
|
+
const compressed = await compressBase64Image(base64, { maxBytes, mimeType });
|
|
8601
|
+
return `data:image/jpeg;base64,${compressed}`;
|
|
8602
|
+
}
|
|
8603
|
+
async function compressContentImages(contentArray, options = {}) {
|
|
8604
|
+
if (!Array.isArray(contentArray)) return contentArray;
|
|
8605
|
+
const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
8606
|
+
return Promise.all(
|
|
8607
|
+
contentArray.map(async (item) => {
|
|
8608
|
+
var _a2;
|
|
8609
|
+
if (item.type !== "image_url") return item;
|
|
8610
|
+
const url = (_a2 = item.image_url) == null ? void 0 : _a2.url;
|
|
8611
|
+
if (!url || !url.startsWith("data:")) return item;
|
|
8612
|
+
const { base64 } = splitDataURI(url);
|
|
8613
|
+
if (base64ByteSize(base64) <= maxBytes) return item;
|
|
8614
|
+
const compressedURI = await compressDataURI(url, { maxBytes });
|
|
8615
|
+
return { ...item, image_url: { ...item.image_url, url: compressedURI } };
|
|
8616
|
+
})
|
|
8617
|
+
);
|
|
8618
|
+
}
|
|
8596
8619
|
async function uploadTempVisionImage(base64OrDataURI, options = {}) {
|
|
8597
8620
|
var _a2, _b2;
|
|
8598
8621
|
const { sdk, fileName = "image.jpg", maxBytes } = options;
|
|
@@ -8635,7 +8658,7 @@ async function uploadTempVisionImage(base64OrDataURI, options = {}) {
|
|
|
8635
8658
|
try {
|
|
8636
8659
|
const headResp = await fetch(cdnUrl, { method: "HEAD" });
|
|
8637
8660
|
if (headResp.ok) {
|
|
8638
|
-
console$
|
|
8661
|
+
console$h.log(`[ImageUtils] File already exists at ${cdnUrl}, skipping upload`);
|
|
8639
8662
|
return cdnUrl;
|
|
8640
8663
|
}
|
|
8641
8664
|
} catch {
|
|
@@ -8663,7 +8686,7 @@ async function uploadTempVisionImage(base64OrDataURI, options = {}) {
|
|
|
8663
8686
|
if (!uploadResp.ok) {
|
|
8664
8687
|
throw new Error(`[ImageUtils] Qiniu upload failed: HTTP ${uploadResp.status}`);
|
|
8665
8688
|
}
|
|
8666
|
-
console$
|
|
8689
|
+
console$h.log(`[ImageUtils] Uploaded to ${cdnUrl} (${(blob.size / 1024).toFixed(1)} KB)`);
|
|
8667
8690
|
return cdnUrl;
|
|
8668
8691
|
}
|
|
8669
8692
|
let _cachedMd5 = null;
|
|
@@ -8683,6 +8706,542 @@ async function _getMd5() {
|
|
|
8683
8706
|
}
|
|
8684
8707
|
return _cachedMd5;
|
|
8685
8708
|
}
|
|
8709
|
+
const console$g = SDKLogger.createModuleConsole("AIChat");
|
|
8710
|
+
class ChatSession {
|
|
8711
|
+
constructor(aiChat, options = {}) {
|
|
8712
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8713
|
+
__publicField(this, "aiChat");
|
|
8714
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8715
|
+
__publicField(this, "messages", []);
|
|
8716
|
+
__publicField(this, "chatId");
|
|
8717
|
+
__publicField(this, "modId");
|
|
8718
|
+
__publicField(this, "skipHistory");
|
|
8719
|
+
__publicField(this, "historyId");
|
|
8720
|
+
__publicField(this, "historyRows", null);
|
|
8721
|
+
__publicField(this, "model");
|
|
8722
|
+
__publicField(this, "apiCacheKey");
|
|
8723
|
+
__publicField(this, "historyLength");
|
|
8724
|
+
__publicField(this, "options");
|
|
8725
|
+
__publicField(this, "sandbox");
|
|
8726
|
+
__publicField(this, "_workspaceExplicitlySet");
|
|
8727
|
+
__publicField(this, "workspace");
|
|
8728
|
+
__publicField(this, "mountFolder");
|
|
8729
|
+
__publicField(this, "_pendingContexts", []);
|
|
8730
|
+
__publicField(this, "_restartedWithPromptFile", false);
|
|
8731
|
+
__publicField(this, "_savedMessages");
|
|
8732
|
+
__publicField(this, "_restartSignal");
|
|
8733
|
+
__publicField(this, "_registeredAsAgent", false);
|
|
8734
|
+
__publicField(this, "_defaultSettings");
|
|
8735
|
+
// ChildSessionHost fields (injected by initChildSessionState)
|
|
8736
|
+
__publicField(this, "name");
|
|
8737
|
+
__publicField(this, "parentSession");
|
|
8738
|
+
__publicField(this, "_childSessions");
|
|
8739
|
+
__publicField(this, "_pendingChildResults");
|
|
8740
|
+
__publicField(this, "_debounceTimers");
|
|
8741
|
+
__publicField(this, "_isSending");
|
|
8742
|
+
__publicField(this, "_lastSendOptions");
|
|
8743
|
+
__publicField(this, "_maxChildSessions");
|
|
8744
|
+
__publicField(this, "_depth");
|
|
8745
|
+
__publicField(this, "_maxDepth");
|
|
8746
|
+
__publicField(this, "onChildStream");
|
|
8747
|
+
var _a2, _b2;
|
|
8748
|
+
const normalizedOptions = { ...options };
|
|
8749
|
+
if (normalizedOptions.systemPrompt === void 0 && normalizedOptions.system_prompt !== void 0) {
|
|
8750
|
+
normalizedOptions.systemPrompt = normalizedOptions.system_prompt;
|
|
8751
|
+
}
|
|
8752
|
+
this.aiChat = aiChat;
|
|
8753
|
+
this.messages = [];
|
|
8754
|
+
this.chatId = normalizedOptions.chatId ?? AIChat.generateUUID();
|
|
8755
|
+
let persistedId = normalizedOptions.persistedId;
|
|
8756
|
+
if (!normalizedOptions.modId && !persistedId) {
|
|
8757
|
+
persistedId = Math.floor(1e3 + Math.random() * 9e3).toString();
|
|
8758
|
+
}
|
|
8759
|
+
this.modId = normalizedOptions.modId ?? aiChat._generateModId(persistedId) ?? null;
|
|
8760
|
+
this.skipHistory = !!normalizedOptions.skipHistory;
|
|
8761
|
+
this.historyId = void 0;
|
|
8762
|
+
this.historyRows = null;
|
|
8763
|
+
this.model = normalizedOptions.model ?? "keepwork-flash";
|
|
8764
|
+
this.apiCacheKey = normalizedOptions.apiCacheKey ?? null;
|
|
8765
|
+
this.historyLength = (normalizedOptions.historyLength ?? 0) > 0 ? normalizedOptions.historyLength : 0;
|
|
8766
|
+
this.options = normalizedOptions;
|
|
8767
|
+
if (normalizedOptions.systemPrompt) {
|
|
8768
|
+
this.messages.push({ role: "system", content: normalizedOptions.systemPrompt });
|
|
8769
|
+
}
|
|
8770
|
+
this._workspaceExplicitlySet = normalizedOptions.workspace !== void 0;
|
|
8771
|
+
this.workspace = normalizedOptions.workspace ?? null;
|
|
8772
|
+
this.mountFolder = normalizedOptions.mountFolder ?? null;
|
|
8773
|
+
this._pendingContexts = [];
|
|
8774
|
+
this.sandbox = new SandboxToolEnv(aiChat.sdk, {
|
|
8775
|
+
workspace: this.workspace ?? "",
|
|
8776
|
+
mountFolder: this.mountFolder,
|
|
8777
|
+
enabledCategories: normalizedOptions.enabledCategories ?? ["fileOps", "execute"],
|
|
8778
|
+
toolProxy: normalizedOptions.toolProxy ?? void 0,
|
|
8779
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8780
|
+
session: this
|
|
8781
|
+
});
|
|
8782
|
+
Object.defineProperty(this, "sdk", { get: () => this.aiChat.sdk, configurable: true });
|
|
8783
|
+
initChildSessionState(this, normalizedOptions);
|
|
8784
|
+
this._defaultSettings = {
|
|
8785
|
+
model: this.model,
|
|
8786
|
+
historyLength: this.historyLength,
|
|
8787
|
+
workspace: this.workspace,
|
|
8788
|
+
mountFolder: this.mountFolder,
|
|
8789
|
+
systemPrompt: normalizedOptions.systemPrompt ?? null,
|
|
8790
|
+
enabledCategories: normalizedOptions.enabledCategories ?? ["fileOps", "execute"]
|
|
8791
|
+
};
|
|
8792
|
+
this._registeredAsAgent = false;
|
|
8793
|
+
if (this.name && !this.parentSession) {
|
|
8794
|
+
const router = (_a2 = aiChat.sdk) == null ? void 0 : _a2["agentRouter"];
|
|
8795
|
+
if (router) {
|
|
8796
|
+
this._registeredAsAgent = ((_b2 = router.register) == null ? void 0 : _b2.call(router, this.name, this)) ?? false;
|
|
8797
|
+
if (!this._registeredAsAgent) {
|
|
8798
|
+
console$g.warn(`[ChatSession] Failed to register agent '${this.name}' — name may already be taken.`);
|
|
8799
|
+
}
|
|
8800
|
+
}
|
|
8801
|
+
}
|
|
8802
|
+
}
|
|
8803
|
+
// ──────────────────── 消息 API ────────────────────
|
|
8804
|
+
/** sdk 访问器(指向 aiChat.sdk) */
|
|
8805
|
+
get sdk() {
|
|
8806
|
+
return this.aiChat.sdk;
|
|
8807
|
+
}
|
|
8808
|
+
/**
|
|
8809
|
+
* 入队后台上下文(将在下一次 send() 时注入到用户消息前)。
|
|
8810
|
+
* 多次调用会累积;下次 send() 时统一冲刷。
|
|
8811
|
+
* @param text - 要注入的上下文文本
|
|
8812
|
+
*/
|
|
8813
|
+
sendContext(text) {
|
|
8814
|
+
if (!text) return;
|
|
8815
|
+
this._pendingContexts.push(String(text));
|
|
8816
|
+
}
|
|
8817
|
+
/**
|
|
8818
|
+
* 取消注册 AgentRouter 中的 agent 名称。
|
|
8819
|
+
* 当此 session 不再处理该 agent 任务时调用。
|
|
8820
|
+
*/
|
|
8821
|
+
unregisterAgent() {
|
|
8822
|
+
var _a2, _b2;
|
|
8823
|
+
if (this._registeredAsAgent && this.name) {
|
|
8824
|
+
const router = (_a2 = this.aiChat.sdk) == null ? void 0 : _a2["agentRouter"];
|
|
8825
|
+
(_b2 = router == null ? void 0 : router.unregister) == null ? void 0 : _b2.call(router, this.name);
|
|
8826
|
+
this._registeredAsAgent = false;
|
|
8827
|
+
}
|
|
8828
|
+
}
|
|
8829
|
+
/**
|
|
8830
|
+
* 直接通过 sandbox 执行工具(AgentRouter.toolCallOnly 路径使用)。
|
|
8831
|
+
*/
|
|
8832
|
+
executeTool(fnName, fnArgs) {
|
|
8833
|
+
return this.sandbox.execute(fnName, fnArgs, { _proxied: true });
|
|
8834
|
+
}
|
|
8835
|
+
/**
|
|
8836
|
+
* 设置文件操作工作空间。
|
|
8837
|
+
* 同步更新 `this.workspace` 和 `this.sandbox.workspace`。
|
|
8838
|
+
* @param wsName - 工作空间名,null/'' 表示清除
|
|
8839
|
+
*/
|
|
8840
|
+
setWorkspace(wsName) {
|
|
8841
|
+
const nextWorkspace = wsName || null;
|
|
8842
|
+
const nextSandboxWorkspace = nextWorkspace ?? "";
|
|
8843
|
+
if (this.workspace === nextWorkspace && (!this.sandbox || this.sandbox.workspace === nextSandboxWorkspace)) return;
|
|
8844
|
+
this._workspaceExplicitlySet = true;
|
|
8845
|
+
this.workspace = nextWorkspace;
|
|
8846
|
+
if (this.sandbox) this.sandbox.workspace = nextSandboxWorkspace;
|
|
8847
|
+
console$g.log(`[ChatSession] Workspace set to: ${this.workspace ?? "(none)"}`);
|
|
8848
|
+
}
|
|
8849
|
+
/**
|
|
8850
|
+
* 设置只读回退层的 mountFolder 配置。
|
|
8851
|
+
* @param mountFolderConfig - 挂载文件夹路径/对象,或 null 清除
|
|
8852
|
+
*/
|
|
8853
|
+
setMountFolder(mountFolderConfig) {
|
|
8854
|
+
this.mountFolder = mountFolderConfig ?? null;
|
|
8855
|
+
if (this.sandbox) this.sandbox.mountFolder = this.mountFolder;
|
|
8856
|
+
console$g.log(`[ChatSession] MountFolder set to: ${this.mountFolder ?? "(none)"}`);
|
|
8857
|
+
}
|
|
8858
|
+
/** 设置 API 缓存 Key(传递给 aiGenerators.chat)。 */
|
|
8859
|
+
setAPICacheKey(key) {
|
|
8860
|
+
this.apiCacheKey = key;
|
|
8861
|
+
}
|
|
8862
|
+
/**
|
|
8863
|
+
* 向会话历史追加用户消息(自动冲刷 _pendingContexts 并注入到消息前)。
|
|
8864
|
+
* @param content - 消息内容(字符串或多模态数组)
|
|
8865
|
+
*/
|
|
8866
|
+
addUserMessage(content) {
|
|
8867
|
+
const contextPrefix = this._flushPendingContexts();
|
|
8868
|
+
let resolvedContent = content;
|
|
8869
|
+
if (contextPrefix && typeof resolvedContent === "string") {
|
|
8870
|
+
resolvedContent = contextPrefix + "\n" + resolvedContent;
|
|
8871
|
+
} else if (contextPrefix && Array.isArray(resolvedContent)) {
|
|
8872
|
+
resolvedContent = [{ type: "text", text: contextPrefix }, ...resolvedContent];
|
|
8873
|
+
}
|
|
8874
|
+
const message = { role: "user", content: resolvedContent, _ts: Date.now() };
|
|
8875
|
+
this.messages.push(message);
|
|
8876
|
+
return message;
|
|
8877
|
+
}
|
|
8878
|
+
/**
|
|
8879
|
+
* 冲刷并返回所有待注入的上下文(包裹在 context_begin…context_end 块中)。
|
|
8880
|
+
* 若无待处理上下文则返回空字符串。
|
|
8881
|
+
* @private
|
|
8882
|
+
*/
|
|
8883
|
+
_flushPendingContexts() {
|
|
8884
|
+
var _a2;
|
|
8885
|
+
if (!((_a2 = this._pendingContexts) == null ? void 0 : _a2.length)) return "";
|
|
8886
|
+
const contexts = this._pendingContexts.splice(0);
|
|
8887
|
+
return "(context_begin)\n" + contexts.join("\n") + "\n(context_end)";
|
|
8888
|
+
}
|
|
8889
|
+
/**
|
|
8890
|
+
* 向会话历史追加助手消息。
|
|
8891
|
+
* @param content - 助手文本内容
|
|
8892
|
+
* @param gptChatId - 可选的 GPT Chat ID(用于历史关联)
|
|
8893
|
+
*/
|
|
8894
|
+
addAssistantMessage(content, gptChatId) {
|
|
8895
|
+
const message = { role: "assistant", content, _ts: Date.now() };
|
|
8896
|
+
if (gptChatId) message.gptChatId = gptChatId;
|
|
8897
|
+
this.messages.push(message);
|
|
8898
|
+
}
|
|
8899
|
+
// ──────────────────── send() ────────────────────
|
|
8900
|
+
/**
|
|
8901
|
+
* 发送消息并更新会话历史(主发送入口)。
|
|
8902
|
+
*
|
|
8903
|
+
* 处理流程:
|
|
8904
|
+
* 1. 取消 debounce 定时器
|
|
8905
|
+
* 2. 若 runCode=true,通过 sandbox.processTemplate 展开 ${...} 表达式
|
|
8906
|
+
* 3. 注入待处理的子 agent 结果(tool call 形式)
|
|
8907
|
+
* 4. 冲刷 _pendingContexts
|
|
8908
|
+
* 5. 压缩 / 上传内联 base64 图片
|
|
8909
|
+
* 6. 添加用户消息,修剪历史
|
|
8910
|
+
* 7. 调用 aiChat.chat()
|
|
8911
|
+
* 8. 追加助手消息,持久化历史
|
|
8912
|
+
*
|
|
8913
|
+
* @param userMessage - 用户消息(字符串、多模态数组,或 null 仅消费子 agent 结果)
|
|
8914
|
+
* @param options - 发送选项(model / tools / enableTools / 流式回调等)
|
|
8915
|
+
*/
|
|
8916
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8917
|
+
async send(userMessage, options = {}) {
|
|
8918
|
+
var _a2, _b2, _c, _d;
|
|
8919
|
+
(_a2 = this._cancelDebounceTimers) == null ? void 0 : _a2.call(this);
|
|
8920
|
+
this._isSending = true;
|
|
8921
|
+
const summarizeDebugValue2 = (v) => {
|
|
8922
|
+
const s = typeof v === "string" ? v : JSON.stringify(v);
|
|
8923
|
+
return s.length > 180 ? s.slice(0, 180) + "..." : s;
|
|
8924
|
+
};
|
|
8925
|
+
console$g.log(`[ChatSession.send] start session='${this.name ?? "root"}' userMessage=${summarizeDebugValue2(userMessage)}`);
|
|
8926
|
+
try {
|
|
8927
|
+
let resolvedUserMessage = userMessage;
|
|
8928
|
+
const effectiveOptions = {
|
|
8929
|
+
...this.options,
|
|
8930
|
+
...options,
|
|
8931
|
+
apiCacheKey: this.apiCacheKey
|
|
8932
|
+
};
|
|
8933
|
+
if (this._workspaceExplicitlySet) effectiveOptions.workspace = this.workspace;
|
|
8934
|
+
const shouldProcessTemplate = effectiveOptions.runCode === true && typeof userMessage === "string";
|
|
8935
|
+
if (shouldProcessTemplate) {
|
|
8936
|
+
resolvedUserMessage = await this.sandbox.processTemplate(userMessage);
|
|
8937
|
+
console$g.log(`[ChatSession.send] runCode resolved userMessage=${summarizeDebugValue2(resolvedUserMessage)}`);
|
|
8938
|
+
}
|
|
8939
|
+
const childResults = ((_b2 = this._consumePendingChildResults) == null ? void 0 : _b2.call(this)) ?? [];
|
|
8940
|
+
if (childResults.length > 0) {
|
|
8941
|
+
console$g.log(`[ChatSession.send] injecting ${childResults.length} pending child result(s) into session='${this.name ?? "root"}'`);
|
|
8942
|
+
const toolCalls = childResults.map((cr) => ({
|
|
8943
|
+
id: cr.taskId,
|
|
8944
|
+
type: "function",
|
|
8945
|
+
function: { name: "async_agent_task", arguments: JSON.stringify({ agent: cr.agentName, task: cr.taskSummary }) }
|
|
8946
|
+
}));
|
|
8947
|
+
this.messages.push({ role: "assistant", content: null, tool_calls: toolCalls });
|
|
8948
|
+
for (const cr of childResults) {
|
|
8949
|
+
this.messages.push({
|
|
8950
|
+
role: "tool",
|
|
8951
|
+
tool_call_id: cr.taskId,
|
|
8952
|
+
content: typeof cr.result === "string" ? cr.result : JSON.stringify(cr.result)
|
|
8953
|
+
});
|
|
8954
|
+
}
|
|
8955
|
+
}
|
|
8956
|
+
const contextPrefix = this._flushPendingContexts();
|
|
8957
|
+
if (contextPrefix) {
|
|
8958
|
+
if (resolvedUserMessage == null) resolvedUserMessage = contextPrefix;
|
|
8959
|
+
else if (typeof resolvedUserMessage === "string") resolvedUserMessage = contextPrefix + "\n" + resolvedUserMessage;
|
|
8960
|
+
else if (Array.isArray(resolvedUserMessage)) resolvedUserMessage = [{ type: "text", text: contextPrefix }, ...resolvedUserMessage];
|
|
8961
|
+
}
|
|
8962
|
+
if (effectiveOptions.skipIfMessageTextEmpty === true && shouldProcessTemplate && typeof resolvedUserMessage === "string" && resolvedUserMessage.trim() === "" && childResults.length === 0) {
|
|
8963
|
+
console$g.log(`[ChatSession.send] skipped empty runCode result in session='${this.name ?? "root"}'`);
|
|
8964
|
+
return "";
|
|
8965
|
+
}
|
|
8966
|
+
if (Array.isArray(resolvedUserMessage)) {
|
|
8967
|
+
const imageConfig = effectiveOptions.imageConfig ?? {};
|
|
8968
|
+
const maxImageBytes = imageConfig.maxImageBytes ?? DEFAULT_MAX_BYTES;
|
|
8969
|
+
resolvedUserMessage = await compressContentImages(resolvedUserMessage, { maxBytes: maxImageBytes });
|
|
8970
|
+
if (imageConfig.autoConvertBase64ToURL !== false) {
|
|
8971
|
+
resolvedUserMessage = await this._uploadInlineImages(resolvedUserMessage);
|
|
8972
|
+
}
|
|
8973
|
+
}
|
|
8974
|
+
let userMessageEntry = null;
|
|
8975
|
+
if (resolvedUserMessage != null) {
|
|
8976
|
+
userMessageEntry = this.addUserMessage(resolvedUserMessage);
|
|
8977
|
+
if (typeof effectiveOptions.onUserMessage === "function") {
|
|
8978
|
+
try {
|
|
8979
|
+
effectiveOptions.onUserMessage(userMessageEntry);
|
|
8980
|
+
} catch (e) {
|
|
8981
|
+
console$g.warn("[ChatSession.send] onUserMessage callback failed:", e);
|
|
8982
|
+
}
|
|
8983
|
+
}
|
|
8984
|
+
}
|
|
8985
|
+
if (this._restartedWithPromptFile) this._restartedWithPromptFile = false;
|
|
8986
|
+
this._evictMessages();
|
|
8987
|
+
if (((_c = effectiveOptions.imageConfig) == null ? void 0 : _c.maxImageHistoryCount) != null) {
|
|
8988
|
+
this._evictExcessImages(effectiveOptions.imageConfig.maxImageHistoryCount);
|
|
8989
|
+
}
|
|
8990
|
+
this._lastSendOptions = effectiveOptions;
|
|
8991
|
+
console$g.log("[ChatSession.send] options:", effectiveOptions);
|
|
8992
|
+
let currentGptChatId;
|
|
8993
|
+
const response = await this.aiChat.chat({
|
|
8994
|
+
...effectiveOptions,
|
|
8995
|
+
_session: this,
|
|
8996
|
+
messages: this.messages,
|
|
8997
|
+
onComplete: (result, fullResponse) => {
|
|
8998
|
+
var _a3, _b3;
|
|
8999
|
+
const fr = fullResponse;
|
|
9000
|
+
if (fr == null ? void 0 : fr["headers"]) {
|
|
9001
|
+
currentGptChatId = (_a3 = fr["headers"]) == null ? void 0 : _a3["x-gpt-chat-id"];
|
|
9002
|
+
}
|
|
9003
|
+
(_b3 = effectiveOptions.onComplete) == null ? void 0 : _b3.call(effectiveOptions, result, fullResponse);
|
|
9004
|
+
}
|
|
9005
|
+
});
|
|
9006
|
+
const assistantContent = typeof response === "string" ? response : (response == null ? void 0 : response["result"]) ?? null;
|
|
9007
|
+
this.addAssistantMessage(assistantContent, currentGptChatId);
|
|
9008
|
+
try {
|
|
9009
|
+
const sdkRef = this.aiChat.sdk;
|
|
9010
|
+
if (!this.skipHistory && this.chatId && this.modId && ((_d = sdkRef == null ? void 0 : sdkRef.token) == null ? void 0 : _d.trim())) {
|
|
9011
|
+
const usedModel = options.model ?? this.model;
|
|
9012
|
+
if (this.historyId) {
|
|
9013
|
+
await this.aiChat.updateChatHistory(this.historyId, {
|
|
9014
|
+
id: this.historyId,
|
|
9015
|
+
chatId: this.chatId,
|
|
9016
|
+
modId: this.modId,
|
|
9017
|
+
model: usedModel,
|
|
9018
|
+
messages: this.messages
|
|
9019
|
+
});
|
|
9020
|
+
} else {
|
|
9021
|
+
await this.aiChat.upsertChatHistory({
|
|
9022
|
+
title: typeof resolvedUserMessage === "string" ? resolvedUserMessage.substring(0, 50) : "",
|
|
9023
|
+
chatId: this.chatId,
|
|
9024
|
+
modId: this.modId,
|
|
9025
|
+
model: usedModel,
|
|
9026
|
+
messages: this.messages
|
|
9027
|
+
});
|
|
9028
|
+
if (this.historyRows === null) this.historyRows = [];
|
|
9029
|
+
}
|
|
9030
|
+
try {
|
|
9031
|
+
const historyRes = await this.aiChat.getChatHistory(this.modId);
|
|
9032
|
+
if (historyRes == null ? void 0 : historyRes.rows) {
|
|
9033
|
+
this.historyRows = historyRes.rows;
|
|
9034
|
+
const history = historyRes.rows.find((h) => h.chatId === this.chatId);
|
|
9035
|
+
if (history) this.historyId = history.id;
|
|
9036
|
+
}
|
|
9037
|
+
} catch (e) {
|
|
9038
|
+
console$g.warn("Failed to fetch chat history", e);
|
|
9039
|
+
}
|
|
9040
|
+
}
|
|
9041
|
+
} catch (e) {
|
|
9042
|
+
console$g.error("Failed to save chat history", e);
|
|
9043
|
+
}
|
|
9044
|
+
return response;
|
|
9045
|
+
} finally {
|
|
9046
|
+
this._isSending = false;
|
|
9047
|
+
}
|
|
9048
|
+
}
|
|
9049
|
+
// ──────────────────── 图片处理 ────────────────────
|
|
9050
|
+
/**
|
|
9051
|
+
* 将多模态 content 数组中的内联 base64 图片上传到临时 CDN,
|
|
9052
|
+
* 并将 data-URI 替换为远程 URL。
|
|
9053
|
+
* @private
|
|
9054
|
+
*/
|
|
9055
|
+
async _uploadInlineImages(contentArray) {
|
|
9056
|
+
if (!Array.isArray(contentArray)) return contentArray;
|
|
9057
|
+
return Promise.all(
|
|
9058
|
+
contentArray.map(async (item) => {
|
|
9059
|
+
var _a2;
|
|
9060
|
+
if (item.type !== "image_url") return item;
|
|
9061
|
+
const url = (_a2 = item.image_url) == null ? void 0 : _a2.url;
|
|
9062
|
+
if (!url || !url.startsWith("data:")) return item;
|
|
9063
|
+
try {
|
|
9064
|
+
const cdnUrl = await uploadTempVisionImage(url, { sdk: this.aiChat.sdk });
|
|
9065
|
+
console$g.log("[ChatSession] Uploaded inline image to CDN:", cdnUrl);
|
|
9066
|
+
return { ...item, image_url: { ...item.image_url, url: cdnUrl } };
|
|
9067
|
+
} catch (e) {
|
|
9068
|
+
console$g.warn("[ChatSession] Failed to upload inline image, keeping data-URI:", e);
|
|
9069
|
+
return item;
|
|
9070
|
+
}
|
|
9071
|
+
})
|
|
9072
|
+
);
|
|
9073
|
+
}
|
|
9074
|
+
// ──────────────────── 消息修剪 ────────────────────
|
|
9075
|
+
/**
|
|
9076
|
+
* 按 historyLength 修剪旧消息轮次。
|
|
9077
|
+
* 保留所有前置 system 消息 + 最后 `historyLength` 轮对话。
|
|
9078
|
+
* @private
|
|
9079
|
+
*/
|
|
9080
|
+
_evictMessages() {
|
|
9081
|
+
const limit = this.historyLength;
|
|
9082
|
+
if (!limit || limit <= 0) return;
|
|
9083
|
+
let systemEnd = 0;
|
|
9084
|
+
while (systemEnd < this.messages.length && this.messages[systemEnd].role === "system") systemEnd++;
|
|
9085
|
+
const roundStarts = [];
|
|
9086
|
+
for (let i = systemEnd; i < this.messages.length; i++) {
|
|
9087
|
+
if (this.messages[i].role === "user") roundStarts.push(i);
|
|
9088
|
+
}
|
|
9089
|
+
if (roundStarts.length <= limit) return;
|
|
9090
|
+
const keepFrom = roundStarts[roundStarts.length - limit];
|
|
9091
|
+
const evicted = keepFrom - systemEnd;
|
|
9092
|
+
this.messages = [...this.messages.slice(0, systemEnd), ...this.messages.slice(keepFrom)];
|
|
9093
|
+
console$g.log(`[ChatSession] Evicted ${evicted} message(s), kept ${limit} round(s)`);
|
|
9094
|
+
}
|
|
9095
|
+
/**
|
|
9096
|
+
* 从历史中移除超出 maxCount 限制的旧图片,
|
|
9097
|
+
* 将被移除的 image_url 替换为 `(user_image)` 文本占位符。
|
|
9098
|
+
* @private
|
|
9099
|
+
*/
|
|
9100
|
+
_evictExcessImages(maxCount) {
|
|
9101
|
+
var _a2;
|
|
9102
|
+
if (maxCount < 0) return;
|
|
9103
|
+
const positions = [];
|
|
9104
|
+
for (let i = 0; i < this.messages.length; i++) {
|
|
9105
|
+
const msg = this.messages[i];
|
|
9106
|
+
if (msg.role !== "user" || !Array.isArray(msg.content)) continue;
|
|
9107
|
+
for (let j = 0; j < msg.content.length; j++) {
|
|
9108
|
+
if (((_a2 = msg.content[j]) == null ? void 0 : _a2["type"]) === "image_url") {
|
|
9109
|
+
positions.push({ msgIdx: i, partIdx: j });
|
|
9110
|
+
}
|
|
9111
|
+
}
|
|
9112
|
+
}
|
|
9113
|
+
if (positions.length <= maxCount) return;
|
|
9114
|
+
const toRemove = positions.slice(0, positions.length - maxCount);
|
|
9115
|
+
let removedCount = 0;
|
|
9116
|
+
for (const { msgIdx, partIdx } of toRemove) {
|
|
9117
|
+
const msg = this.messages[msgIdx];
|
|
9118
|
+
msg.content[partIdx] = { type: "text", text: "(user_image)" };
|
|
9119
|
+
removedCount++;
|
|
9120
|
+
}
|
|
9121
|
+
if (removedCount > 0) console$g.log(`[ChatSession] Evicted ${removedCount} image(s) from history, kept ${maxCount}`);
|
|
9122
|
+
}
|
|
9123
|
+
// ──────────────────── 历史管理 ────────────────────
|
|
9124
|
+
/** 清空对话历史(仅清空 messages 数组)。 */
|
|
9125
|
+
clear() {
|
|
9126
|
+
this.messages = [];
|
|
9127
|
+
}
|
|
9128
|
+
/** 获取当前对话历史的副本。 */
|
|
9129
|
+
getHistory() {
|
|
9130
|
+
return [...this.messages];
|
|
9131
|
+
}
|
|
9132
|
+
// ──────────────────── restartAgent ────────────────────
|
|
9133
|
+
/**
|
|
9134
|
+
* 重启 agent 会话(可选加载配置文件)。
|
|
9135
|
+
*
|
|
9136
|
+
* 行为:
|
|
9137
|
+
* - 无 promptFile:恢复所有设置到构造时的默认值
|
|
9138
|
+
* - 纯 Markdown(只有 system_prompt):仅更换系统提示,其他设置保持默认
|
|
9139
|
+
* - 完整配置:临时覆盖设置;下次无 promptFile 的重启会恢复全部默认值
|
|
9140
|
+
*
|
|
9141
|
+
* @param promptFile - 配置文件 URL 或路径(.json / .yml / .yaml / .md)
|
|
9142
|
+
* @param tools - 可选工具分类覆盖(空表示继承默认值)
|
|
9143
|
+
* @param _options - 高级选项(预留)
|
|
9144
|
+
* @returns `{ configSource }`
|
|
9145
|
+
*/
|
|
9146
|
+
async restartAgent(promptFile, tools, _options) {
|
|
9147
|
+
var _a2, _b2, _c, _d, _e, _f;
|
|
9148
|
+
console$g.log(`[ChatSession] restartAgent session='${this.name ?? "root"}' promptFile=${promptFile ?? "(none)"}`);
|
|
9149
|
+
const normalizedTools = Array.isArray(tools) ? tools.filter((t) => typeof t === "string" && t.trim()) : [];
|
|
9150
|
+
const cleanupFn = this["_cleanupChildSessions"];
|
|
9151
|
+
cleanupFn == null ? void 0 : cleanupFn.call(this);
|
|
9152
|
+
const defaults = this._defaultSettings;
|
|
9153
|
+
this.model = defaults.model ?? "keepwork-flash";
|
|
9154
|
+
this.historyLength = defaults.historyLength ?? 0;
|
|
9155
|
+
if (defaults.workspace !== void 0) this.setWorkspace(defaults.workspace);
|
|
9156
|
+
if (defaults.mountFolder !== void 0) this.setMountFolder(defaults.mountFolder);
|
|
9157
|
+
if (this.sandbox && defaults.enabledCategories) {
|
|
9158
|
+
(_b2 = (_a2 = this.sandbox).setEnabledCategories) == null ? void 0 : _b2.call(_a2, defaults.enabledCategories);
|
|
9159
|
+
}
|
|
9160
|
+
let loadedConfig = null;
|
|
9161
|
+
const hasPromptFile = !!(promptFile && typeof promptFile === "string" && promptFile.trim());
|
|
9162
|
+
if (hasPromptFile) {
|
|
9163
|
+
try {
|
|
9164
|
+
const AgentConfig2 = (await Promise.resolve().then(() => AgentConfig$1)).default;
|
|
9165
|
+
loadedConfig = await AgentConfig2.fetch(promptFile.trim());
|
|
9166
|
+
} catch (e) {
|
|
9167
|
+
console$g.warn(`[ChatSession] restartAgent failed to load '${promptFile}': ${e.message}`);
|
|
9168
|
+
}
|
|
9169
|
+
}
|
|
9170
|
+
const systemPrompt = loadedConfig ? loadedConfig["system_prompt"] ?? loadedConfig["systemPrompt"] ?? defaults.systemPrompt : defaults.systemPrompt;
|
|
9171
|
+
if (hasPromptFile && loadedConfig) {
|
|
9172
|
+
this._savedMessages = this.messages.filter((m) => m.role !== "system");
|
|
9173
|
+
console$g.log(`[ChatSession] restartAgent: saved ${this._savedMessages.length} history messages`);
|
|
9174
|
+
} else if (!hasPromptFile && this._savedMessages) {
|
|
9175
|
+
console$g.log(`[ChatSession] restartAgent: keeping ${this._savedMessages.length} saved history messages for summarizer`);
|
|
9176
|
+
}
|
|
9177
|
+
this.messages = [];
|
|
9178
|
+
if (systemPrompt) this.messages.push({ role: "system", content: systemPrompt });
|
|
9179
|
+
if (!hasPromptFile && this._savedMessages) this._savedMessages = null;
|
|
9180
|
+
if (loadedConfig) {
|
|
9181
|
+
if (loadedConfig["model"]) this.model = loadedConfig["model"];
|
|
9182
|
+
if (loadedConfig["historyLength"] !== void 0) this.historyLength = loadedConfig["historyLength"];
|
|
9183
|
+
if (loadedConfig["workspace"]) this.setWorkspace(loadedConfig["workspace"]);
|
|
9184
|
+
if (loadedConfig["mountFolder"]) this.setMountFolder(loadedConfig["mountFolder"]);
|
|
9185
|
+
if (loadedConfig["tools"] && this.sandbox) {
|
|
9186
|
+
const cats = loadedConfig["tools"];
|
|
9187
|
+
const enabledCategories = Object.keys(cats).filter((k) => {
|
|
9188
|
+
var _a3;
|
|
9189
|
+
return ((_a3 = cats[k]) == null ? void 0 : _a3.enabled) !== false;
|
|
9190
|
+
});
|
|
9191
|
+
if (enabledCategories.length > 0) {
|
|
9192
|
+
(_d = (_c = this.sandbox).setEnabledCategories) == null ? void 0 : _d.call(_c, enabledCategories);
|
|
9193
|
+
}
|
|
9194
|
+
}
|
|
9195
|
+
}
|
|
9196
|
+
if (this.sandbox && normalizedTools.length > 0) {
|
|
9197
|
+
(_f = (_e = this.sandbox).setEnabledCategories) == null ? void 0 : _f.call(_e, normalizedTools);
|
|
9198
|
+
}
|
|
9199
|
+
this._pendingContexts = [];
|
|
9200
|
+
this._restartedWithPromptFile = hasPromptFile && !!loadedConfig;
|
|
9201
|
+
if (this.sandbox) {
|
|
9202
|
+
this.sandbox._activePromptFile = promptFile ?? null;
|
|
9203
|
+
this.sandbox._templateSourceFile = promptFile ?? null;
|
|
9204
|
+
}
|
|
9205
|
+
return { configSource: loadedConfig ? promptFile ?? "unknown" : "default" };
|
|
9206
|
+
}
|
|
9207
|
+
// ChildSessionHost 必须实现的方法占位(由 mixin 注入)
|
|
9208
|
+
_triggerImmediateCallback() {
|
|
9209
|
+
return Promise.resolve();
|
|
9210
|
+
}
|
|
9211
|
+
}
|
|
9212
|
+
function installAIChatSessionFactory() {
|
|
9213
|
+
Object.assign(ChatSession.prototype, childSessionMethods);
|
|
9214
|
+
Object.assign(ChatSession.prototype, {
|
|
9215
|
+
async _triggerImmediateCallback() {
|
|
9216
|
+
console$g.log(
|
|
9217
|
+
`[ChatSession] _triggerImmediateCallback session='${this.name ?? "root"}' pendingChildResults=${this._pendingChildResults.length} isSending=${this._isSending}`
|
|
9218
|
+
);
|
|
9219
|
+
if (this._isSending) {
|
|
9220
|
+
await new Promise((resolve) => {
|
|
9221
|
+
const check = () => {
|
|
9222
|
+
if (!this._isSending) resolve();
|
|
9223
|
+
else setTimeout(check, 50);
|
|
9224
|
+
};
|
|
9225
|
+
setTimeout(check, 50);
|
|
9226
|
+
});
|
|
9227
|
+
}
|
|
9228
|
+
if (this._pendingChildResults.length === 0) return;
|
|
9229
|
+
console$g.log("[ChatSession] Immediate callback: sending child results to parent");
|
|
9230
|
+
try {
|
|
9231
|
+
await this.send(null, this._lastSendOptions);
|
|
9232
|
+
} catch (e) {
|
|
9233
|
+
console$g.error("[ChatSession] Immediate callback send failed:", e);
|
|
9234
|
+
}
|
|
9235
|
+
}
|
|
9236
|
+
});
|
|
9237
|
+
Object.assign(AIChat.prototype, {
|
|
9238
|
+
createSession(options = {}) {
|
|
9239
|
+
return new ChatSession(this, options);
|
|
9240
|
+
}
|
|
9241
|
+
});
|
|
9242
|
+
}
|
|
9243
|
+
installAIChatSessionFactory();
|
|
9244
|
+
installAIChatSessionFactory();
|
|
8686
9245
|
const console$f = SDKLogger.createModuleConsole("SummarizeTool");
|
|
8687
9246
|
const _SummarizeTool = class _SummarizeTool {
|
|
8688
9247
|
constructor() {
|
|
@@ -11138,7 +11697,9 @@ class LoginWindow {
|
|
|
11138
11697
|
const t = (k) => this._strings[k] || k;
|
|
11139
11698
|
const enableRegister = options.enableRegister !== false;
|
|
11140
11699
|
const enableWechat = options.enableWechat !== false;
|
|
11141
|
-
const
|
|
11700
|
+
const wxEnv = detectWxEnvironment();
|
|
11701
|
+
const isWeChat = wxEnv.isWeChat;
|
|
11702
|
+
const isWxMiniProgram = wxEnv.isMiniProgram;
|
|
11142
11703
|
const isMobile = isMobileDevice();
|
|
11143
11704
|
const showWechatQr = enableWechat && !isWeChat && !isMobile && typeof window !== "undefined";
|
|
11144
11705
|
const showWechatRedirect = enableWechat && isWeChat;
|
|
@@ -11153,6 +11714,13 @@ class LoginWindow {
|
|
|
11153
11714
|
this._machineCode = options.machineCode;
|
|
11154
11715
|
this._wechatOptions = this._normalizeWechatOptions(options);
|
|
11155
11716
|
this._wxAuthInstance = this.sdk.wxAuth || new WxAuth(this.sdk);
|
|
11717
|
+
if (typeof window !== "undefined" && isWxMiniProgram && !this.sdk.token) {
|
|
11718
|
+
const hasWechatCode = new URL(window.location.href).searchParams.get("code");
|
|
11719
|
+
if (!hasWechatCode) {
|
|
11720
|
+
this._wxAuthInstance.authorize({ autoRegister: true });
|
|
11721
|
+
return;
|
|
11722
|
+
}
|
|
11723
|
+
}
|
|
11156
11724
|
this._injectStyles();
|
|
11157
11725
|
const overlay = document.createElement("div");
|
|
11158
11726
|
overlay.className = "kw-login-overlay";
|
|
@@ -11349,16 +11917,14 @@ class LoginWindow {
|
|
|
11349
11917
|
}
|
|
11350
11918
|
regSubmit.textContent = t("registering");
|
|
11351
11919
|
try {
|
|
11920
|
+
const channel = options.channel != null ? Number(options.channel) : 60;
|
|
11352
11921
|
const response = await this.sdk.post("/users/register", {
|
|
11353
11922
|
username,
|
|
11354
11923
|
password,
|
|
11355
11924
|
platform: "WEB",
|
|
11356
|
-
channel
|
|
11925
|
+
channel
|
|
11357
11926
|
});
|
|
11358
|
-
|
|
11359
|
-
this.sdk.setToken(response.token);
|
|
11360
|
-
}
|
|
11361
|
-
this._finish(response);
|
|
11927
|
+
this._finishWithAuth(response);
|
|
11362
11928
|
} catch (err) {
|
|
11363
11929
|
regSubmit.disabled = false;
|
|
11364
11930
|
regSubmit.textContent = t("registerBtn");
|
|
@@ -11422,6 +11988,24 @@ class LoginWindow {
|
|
|
11422
11988
|
close() {
|
|
11423
11989
|
this._destroy();
|
|
11424
11990
|
}
|
|
11991
|
+
/**
|
|
11992
|
+
* 打开登录弹窗并直接进入「设置账号」视图,用于微信回调全局识别后、
|
|
11993
|
+
* 探测到未绑定账号(needBind)时完成绑定登录。
|
|
11994
|
+
*
|
|
11995
|
+
* show() 内部同步创建并挂载 overlay 后才返回 Promise,因此可在返回后立即
|
|
11996
|
+
* 切换到 oauth-setup 视图(用户只会看到设置账号界面,不会看到账号/密码登录界面)。
|
|
11997
|
+
*
|
|
11998
|
+
* @param data - codeToProbe 返回的 { ticket, suggestedUsername, provider, bindPath? }
|
|
11999
|
+
* @param options - 透传给 show() 的选项(title / lang 等)
|
|
12000
|
+
* @returns 与 show() 一致:绑定成功 resolve 登录结果,取消 reject
|
|
12001
|
+
*/
|
|
12002
|
+
showWechatBindSetup(data, options = {}) {
|
|
12003
|
+
const promise = this.show({ ...options, enableWechat: false, enableGoogle: false });
|
|
12004
|
+
if (this._overlay) {
|
|
12005
|
+
this._showOauthSetup(this._overlay, data, data.bindPath || OAUTH_BIND_PATH);
|
|
12006
|
+
}
|
|
12007
|
+
return promise;
|
|
12008
|
+
}
|
|
11425
12009
|
_renderWechatQrPanel(t) {
|
|
11426
12010
|
return `
|
|
11427
12011
|
<div class="kw-login-wechat-panel">
|
|
@@ -11602,11 +12186,8 @@ class LoginWindow {
|
|
|
11602
12186
|
if (this._machineCode) payload.machineCode = this._machineCode;
|
|
11603
12187
|
const response = await this.sdk.post(options.probePath, payload);
|
|
11604
12188
|
if (response && response.token) {
|
|
11605
|
-
this.sdk.setToken(response.token);
|
|
11606
|
-
setCookie("token", response.token, 14);
|
|
11607
|
-
setCookie("token", response.token, 14, { sameSite: "None", secure: true });
|
|
11608
12189
|
this._clearWechatQueryFromCurrentUrl();
|
|
11609
|
-
this.
|
|
12190
|
+
this._finishWithAuth(response);
|
|
11610
12191
|
return;
|
|
11611
12192
|
}
|
|
11612
12193
|
if (response && response.needBind && response.ticket) {
|
|
@@ -11680,7 +12261,8 @@ class LoginWindow {
|
|
|
11680
12261
|
const data = result && result.data;
|
|
11681
12262
|
if (result && result.success && data && data.token) {
|
|
11682
12263
|
this._clearWechatQueryFromCurrentUrl();
|
|
11683
|
-
this.
|
|
12264
|
+
this._finishWithAuth(data);
|
|
12265
|
+
this._reloadAfterOAuthLogin();
|
|
11684
12266
|
return;
|
|
11685
12267
|
}
|
|
11686
12268
|
if (result && result.success && data && data.needBind && data.ticket) {
|
|
@@ -11951,11 +12533,8 @@ class LoginWindow {
|
|
|
11951
12533
|
if (options.machineCode) payload.machineCode = options.machineCode;
|
|
11952
12534
|
const response = await this.sdk.post(options.probePath, payload);
|
|
11953
12535
|
if (response && response.token) {
|
|
11954
|
-
this.sdk.setToken(response.token);
|
|
11955
|
-
setCookie("token", response.token, 14);
|
|
11956
|
-
setCookie("token", response.token, 14, { sameSite: "None", secure: true });
|
|
11957
12536
|
this._clearGoogleQueryFromCurrentUrl();
|
|
11958
|
-
this.
|
|
12537
|
+
this._finishWithAuth(response);
|
|
11959
12538
|
return;
|
|
11960
12539
|
}
|
|
11961
12540
|
if (response && response.needBind && response.ticket) {
|
|
@@ -12199,10 +12778,7 @@ class LoginWindow {
|
|
|
12199
12778
|
if (this._machineCode) payload.machineCode = this._machineCode;
|
|
12200
12779
|
const response = await this.sdk.post(ctx.bindPath, payload);
|
|
12201
12780
|
if (response && response.token) {
|
|
12202
|
-
this.
|
|
12203
|
-
setCookie("token", response.token, 14);
|
|
12204
|
-
setCookie("token", response.token, 14, { sameSite: "None", secure: true });
|
|
12205
|
-
this._finish(response);
|
|
12781
|
+
this._finishWithAuth(response);
|
|
12206
12782
|
return;
|
|
12207
12783
|
}
|
|
12208
12784
|
if (submitBtn) {
|
|
@@ -12231,6 +12807,28 @@ class LoginWindow {
|
|
|
12231
12807
|
}
|
|
12232
12808
|
return pwd;
|
|
12233
12809
|
}
|
|
12810
|
+
/**
|
|
12811
|
+
* 登录/注册成功统一收尾:写 token + cookie,然后关窗口并 resolve。
|
|
12812
|
+
* 所有「直接持有 token 的路径」都走此方法,避免各处重复写 setToken + setCookie。
|
|
12813
|
+
* 若 response 不含 token(如账号登录走 sdk.login() 内部处理),退化为普通 _finish。
|
|
12814
|
+
*/
|
|
12815
|
+
_finishWithAuth(response) {
|
|
12816
|
+
if (response && response.token) {
|
|
12817
|
+
this.sdk.setToken(response.token);
|
|
12818
|
+
setCookie("token", response.token, 14);
|
|
12819
|
+
setCookie("token", response.token, 14, { sameSite: "None", secure: true });
|
|
12820
|
+
}
|
|
12821
|
+
this._finish(response);
|
|
12822
|
+
}
|
|
12823
|
+
/**
|
|
12824
|
+
* 整页跳转式 OAuth 登录(微信浏览器 / 小程序)成功后刷新页面,
|
|
12825
|
+
* 使宿主页面以登录态重新初始化。SSR 等无 window 环境下静默跳过。
|
|
12826
|
+
*/
|
|
12827
|
+
_reloadAfterOAuthLogin() {
|
|
12828
|
+
if (typeof window !== "undefined" && window.location && typeof window.location.reload === "function") {
|
|
12829
|
+
window.location.reload();
|
|
12830
|
+
}
|
|
12831
|
+
}
|
|
12234
12832
|
_finish(response) {
|
|
12235
12833
|
this._destroy();
|
|
12236
12834
|
if (this._resolve) {
|
|
@@ -14320,8 +14918,9 @@ class LocalAPIKeySettings {
|
|
|
14320
14918
|
this._injectStyles();
|
|
14321
14919
|
const overlay = document.createElement("div");
|
|
14322
14920
|
overlay.className = `lak-overlay${options.fullscreen ? " lak-overlay-fullscreen" : ""}`;
|
|
14921
|
+
overlay.style.cssText = "position:fixed;top:0;left:0;right:0;bottom:0;width:100vw;height:100vh;height:100dvh;z-index:2147483647;margin:0;";
|
|
14323
14922
|
overlay.innerHTML = this._buildHTML(options);
|
|
14324
|
-
document.body.appendChild(overlay);
|
|
14923
|
+
(document.body || document.documentElement).appendChild(overlay);
|
|
14325
14924
|
this._overlay = overlay;
|
|
14326
14925
|
this._populateFields();
|
|
14327
14926
|
this._renderActivePanel();
|
|
@@ -14914,7 +15513,13 @@ class LocalAPIKeySettings {
|
|
|
14914
15513
|
const style = document.createElement("style");
|
|
14915
15514
|
style.textContent = `
|
|
14916
15515
|
.lak-overlay {
|
|
14917
|
-
position: fixed; inset: 0;
|
|
15516
|
+
position: fixed; inset: 0;
|
|
15517
|
+
/* Explicit width/height in addition to inset:0 so the overlay always
|
|
15518
|
+
* fills the screen even when a transformed/filter/perspective ancestor
|
|
15519
|
+
* turns it into the fixed-positioning containing block (e.g. a scaled
|
|
15520
|
+
* app shell). vw/vh are resolved against the viewport regardless. */
|
|
15521
|
+
width: 100vw; height: 100vh; height: 100dvh;
|
|
15522
|
+
z-index: 2147483647;
|
|
14918
15523
|
background: rgba(0,0,0,0.55);
|
|
14919
15524
|
display: flex; align-items: center; justify-content: center;
|
|
14920
15525
|
opacity: 0; transition: opacity 0.2s;
|
|
@@ -14943,10 +15548,12 @@ class LocalAPIKeySettings {
|
|
|
14943
15548
|
}
|
|
14944
15549
|
|
|
14945
15550
|
.lak-overlay-fullscreen .lak-box {
|
|
14946
|
-
|
|
15551
|
+
/* Fill the overlay (which already spans the viewport) rather than
|
|
15552
|
+
* re-deriving from vw/dvh. This keeps the box correct even if the
|
|
15553
|
+
* overlay is clamped by an ancestor containing block. */
|
|
15554
|
+
width: 100%;
|
|
14947
15555
|
max-width: none;
|
|
14948
|
-
height:
|
|
14949
|
-
height: 100dvh;
|
|
15556
|
+
height: 100%;
|
|
14950
15557
|
max-height: none;
|
|
14951
15558
|
border-radius: 0;
|
|
14952
15559
|
box-shadow: none;
|
|
@@ -17812,6 +18419,57 @@ function applyCoreMixin(TargetClass) {
|
|
|
17812
18419
|
proto.showProfileWindow = async function(options = {}) {
|
|
17813
18420
|
return this.profileWindow.show(options);
|
|
17814
18421
|
};
|
|
18422
|
+
proto.handleWechatRedirectLogin = async function() {
|
|
18423
|
+
var _a2, _b2;
|
|
18424
|
+
if (typeof window === "undefined") return false;
|
|
18425
|
+
let url;
|
|
18426
|
+
try {
|
|
18427
|
+
url = new URL(window.location.href);
|
|
18428
|
+
} catch {
|
|
18429
|
+
return false;
|
|
18430
|
+
}
|
|
18431
|
+
const code = url.searchParams.get("code");
|
|
18432
|
+
const wxauth = url.searchParams.get("wxauth");
|
|
18433
|
+
if (!code || wxauth !== "1") return false;
|
|
18434
|
+
const guardKey = `kwWxRedirectLogin:${code}`;
|
|
18435
|
+
try {
|
|
18436
|
+
if (sessionStorage.getItem(guardKey)) return false;
|
|
18437
|
+
sessionStorage.setItem(guardKey, "1");
|
|
18438
|
+
} catch {
|
|
18439
|
+
}
|
|
18440
|
+
try {
|
|
18441
|
+
const result = await this.wxAuth.codeToProbe(code);
|
|
18442
|
+
const data = result && result.data;
|
|
18443
|
+
if (result && result.success && data && data.token) {
|
|
18444
|
+
this._clearWechatRedirectQuery();
|
|
18445
|
+
if (typeof window !== "undefined" && window.location && typeof window.location.reload === "function") {
|
|
18446
|
+
window.location.reload();
|
|
18447
|
+
}
|
|
18448
|
+
return true;
|
|
18449
|
+
}
|
|
18450
|
+
if (result && result.success && data && data.needBind && data.ticket) {
|
|
18451
|
+
this._clearWechatRedirectQuery();
|
|
18452
|
+
if (data.provider == null) data.provider = "wechat";
|
|
18453
|
+
(_b2 = (_a2 = this.loginWindow).showWechatBindSetup) == null ? void 0 : _b2.call(_a2, data);
|
|
18454
|
+
return true;
|
|
18455
|
+
}
|
|
18456
|
+
} catch (err) {
|
|
18457
|
+
console.warn("[KeepworkSDK] WeChat redirect login failed:", err);
|
|
18458
|
+
}
|
|
18459
|
+
return true;
|
|
18460
|
+
};
|
|
18461
|
+
proto._clearWechatRedirectQuery = function() {
|
|
18462
|
+
if (typeof window === "undefined" || !window.history || !window.history.replaceState) return;
|
|
18463
|
+
try {
|
|
18464
|
+
const url = new URL(window.location.href);
|
|
18465
|
+
if (!url.searchParams.has("code") && !url.searchParams.has("state") && !url.searchParams.has("wxauth")) return;
|
|
18466
|
+
url.searchParams.delete("code");
|
|
18467
|
+
url.searchParams.delete("state");
|
|
18468
|
+
url.searchParams.delete("wxauth");
|
|
18469
|
+
window.history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`);
|
|
18470
|
+
} catch {
|
|
18471
|
+
}
|
|
18472
|
+
};
|
|
17815
18473
|
proto.logout = async function() {
|
|
17816
18474
|
let response;
|
|
17817
18475
|
try {
|
|
@@ -19344,6 +20002,15 @@ const _KeepworkSDK = class _KeepworkSDK {
|
|
|
19344
20002
|
this._speechRTC = null;
|
|
19345
20003
|
this._loadAIChatPromise = null;
|
|
19346
20004
|
this._patchAIChat();
|
|
20005
|
+
if (typeof window !== "undefined") {
|
|
20006
|
+
Promise.resolve().then(
|
|
20007
|
+
() => {
|
|
20008
|
+
var _a2;
|
|
20009
|
+
return (_a2 = this.handleWechatRedirectLogin) == null ? void 0 : _a2.call(this);
|
|
20010
|
+
}
|
|
20011
|
+
).catch(() => {
|
|
20012
|
+
});
|
|
20013
|
+
}
|
|
19347
20014
|
}
|
|
19348
20015
|
// ──────────────────── AIChat / SpeechRTC 懒加载 getter/setter ────────────────────
|
|
19349
20016
|
// 实际方法(_patchAIChat / loadAIChat)由 keepworkSDK.core.ts mixin 注入
|
|
@@ -20190,7 +20857,20 @@ class RTCChatSession {
|
|
|
20190
20857
|
this.agentState = AGENT_STATE.UNKNOWN;
|
|
20191
20858
|
this._stateEventReceived = false;
|
|
20192
20859
|
this._autoPlayResumeRegistered = false;
|
|
20193
|
-
this.
|
|
20860
|
+
this._cleanupChildSessionsSafe();
|
|
20861
|
+
}
|
|
20862
|
+
_cleanupChildSessionsSafe() {
|
|
20863
|
+
const cleanup = this._cleanupChildSessions;
|
|
20864
|
+
if (typeof cleanup === "function") {
|
|
20865
|
+
cleanup.call(this);
|
|
20866
|
+
return;
|
|
20867
|
+
}
|
|
20868
|
+
for (const timer of this._debounceTimers || []) {
|
|
20869
|
+
clearTimeout(timer);
|
|
20870
|
+
}
|
|
20871
|
+
this._debounceTimers = [];
|
|
20872
|
+
this._childSessions = {};
|
|
20873
|
+
this._pendingChildResults = [];
|
|
20194
20874
|
}
|
|
20195
20875
|
_ensureSandbox() {
|
|
20196
20876
|
if (!this.sandbox) {
|
|
@@ -21149,24 +21829,28 @@ class RTCChatSession {
|
|
|
21149
21829
|
}
|
|
21150
21830
|
}
|
|
21151
21831
|
}
|
|
21152
|
-
|
|
21153
|
-
RTCChatSession.prototype
|
|
21154
|
-
|
|
21155
|
-
|
|
21156
|
-
|
|
21157
|
-
|
|
21158
|
-
|
|
21159
|
-
|
|
21160
|
-
|
|
21161
|
-
|
|
21162
|
-
|
|
21163
|
-
|
|
21164
|
-
|
|
21165
|
-
|
|
21166
|
-
|
|
21167
|
-
|
|
21168
|
-
|
|
21169
|
-
}
|
|
21832
|
+
function installRTCChatSessionMixin() {
|
|
21833
|
+
Object.assign(RTCChatSession.prototype, childSessionMethods);
|
|
21834
|
+
RTCChatSession.prototype._triggerImmediateCallback = async function() {
|
|
21835
|
+
if (this._isSending) {
|
|
21836
|
+
await new Promise((resolve) => {
|
|
21837
|
+
const check = () => {
|
|
21838
|
+
if (!this._isSending) resolve();
|
|
21839
|
+
else setTimeout(check, 50);
|
|
21840
|
+
};
|
|
21841
|
+
setTimeout(check, 50);
|
|
21842
|
+
});
|
|
21843
|
+
}
|
|
21844
|
+
if (this._pendingChildResults.length === 0) return;
|
|
21845
|
+
try {
|
|
21846
|
+
await this.send(null, this._lastSendOptions);
|
|
21847
|
+
} catch (e) {
|
|
21848
|
+
console$9.error("[RTCChatSession] Immediate callback send failed:", e);
|
|
21849
|
+
}
|
|
21850
|
+
};
|
|
21851
|
+
}
|
|
21852
|
+
installRTCChatSessionMixin();
|
|
21853
|
+
installRTCChatSessionMixin();
|
|
21170
21854
|
let AIChatRTC$1 = (_a = class {
|
|
21171
21855
|
/**
|
|
21172
21856
|
* @param {Object} sdk - KeepworkSDK instance (provides sdk.post, sdk.token, sdk.copilotTools)
|
|
@@ -23629,7 +24313,20 @@ class LocalRTCSession {
|
|
|
23629
24313
|
this._isSpeaking = false;
|
|
23630
24314
|
this._isLLMStreaming = false;
|
|
23631
24315
|
this._messages = [];
|
|
23632
|
-
this.
|
|
24316
|
+
this._cleanupChildSessionsSafe();
|
|
24317
|
+
}
|
|
24318
|
+
_cleanupChildSessionsSafe() {
|
|
24319
|
+
const cleanup = this._cleanupChildSessions;
|
|
24320
|
+
if (typeof cleanup === "function") {
|
|
24321
|
+
cleanup.call(this);
|
|
24322
|
+
return;
|
|
24323
|
+
}
|
|
24324
|
+
for (const timer of this._debounceTimers || []) {
|
|
24325
|
+
clearTimeout(timer);
|
|
24326
|
+
}
|
|
24327
|
+
this._debounceTimers = [];
|
|
24328
|
+
this._childSessions = {};
|
|
24329
|
+
this._pendingChildResults = [];
|
|
23633
24330
|
}
|
|
23634
24331
|
_mergeConfigSection(currentConfig = {}, nextConfig = {}) {
|
|
23635
24332
|
return {
|
|
@@ -24433,19 +25130,23 @@ class LocalRTCSession {
|
|
|
24433
25130
|
}
|
|
24434
25131
|
}
|
|
24435
25132
|
}
|
|
24436
|
-
|
|
24437
|
-
LocalRTCSession.prototype
|
|
24438
|
-
|
|
24439
|
-
|
|
24440
|
-
|
|
24441
|
-
const
|
|
24442
|
-
|
|
25133
|
+
function installLocalRTCSessionMixin() {
|
|
25134
|
+
Object.assign(LocalRTCSession.prototype, childSessionMethods);
|
|
25135
|
+
LocalRTCSession.prototype._triggerImmediateCallback = async function() {
|
|
25136
|
+
if (this._pendingChildResults.length === 0) return;
|
|
25137
|
+
const results = this._consumePendingChildResults();
|
|
25138
|
+
const parts = results.map((cr) => {
|
|
25139
|
+
const resultText = typeof cr.result === "string" ? cr.result : JSON.stringify(cr.result);
|
|
25140
|
+
return `[Agent ${cr.agentName}] Task: ${cr.taskSummary}
|
|
24443
25141
|
Result: ${resultText}`;
|
|
24444
|
-
|
|
24445
|
-
|
|
24446
|
-
|
|
24447
|
-
};
|
|
25142
|
+
});
|
|
25143
|
+
const summary = parts.join("\n\n");
|
|
25144
|
+
this.sendText(summary);
|
|
25145
|
+
};
|
|
25146
|
+
}
|
|
25147
|
+
installLocalRTCSessionMixin();
|
|
24448
25148
|
const console$6 = SDKLogger.createModuleConsole("AIChatRTCLocal");
|
|
25149
|
+
installLocalRTCSessionMixin();
|
|
24449
25150
|
let AIChatRTCLocal$1 = (_b = class {
|
|
24450
25151
|
/**
|
|
24451
25152
|
* @param {Object} sdk - KeepworkSDK instance
|