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.
@@ -887,7 +887,7 @@ if (typeof window !== "undefined") {
887
887
  window.LocalStorageUtil = LocalStorageUtil;
888
888
  window.StorageUtil = StorageUtil;
889
889
  }
890
- const console$o = SDKLogger.createModuleConsole("PersonalPageStore");
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$o.warn(`PersonalPageStore: listener for '${event}' threw:`, e);
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$o.warn("PersonalPageStore: mountedFolder path requires at least username/workspace");
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$o.warn("PersonalPageStore: mountedFolder object requires username and workspace");
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$o.warn("PersonalPageStore: mountedFolder must be a path string, object, or null");
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$o.log(`[PersonalPageStore] Updated search path: ${normalizedPrefix} -> ${normalizedBaseUrl} (readonly=${isReadonly})`);
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$o.log(`[PersonalPageStore] Added search path: ${normalizedPrefix} -> ${normalizedBaseUrl} (readonly=${isReadonly})`);
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$o.log(`[PersonalPageStore] SearchPath found: ${effectiveName} -> ${fileUrl}`);
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$o.log(`[PersonalPageStore] SearchPath not found: ${effectiveName}`);
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$o.log(`PersonalPageStore: Override username set to: ${this.overrideUsername ?? "current user"}`);
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$o.log("personalPageStore: No token set, using anonymous mode");
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$n = SDKLogger.createModuleConsole("Speech");
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$n.warn(`Invalid fallbackMode "${mode}", expected one of: ${valid.join(", ")}`);
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$n.warn("当前浏览器不支持 OfflineAudioContext,返回原始采样率音频");
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$n.error("停止音频播放时发生错误:", error);
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$n.error("Error playing YouDao audio:", err));
5041
+ if (p) p.catch((err) => console$o.error("Error playing YouDao audio:", err));
5042
5042
  }));
5043
5043
  } catch (e) {
5044
- console$n.error("Error with YouDao API:", e);
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$n.log("录音开始"),
5062
- onStop: () => console$n.log("录音停止"),
5063
- onError: (e) => console$n.error("录音错误:", e),
5064
- onResult: (r) => console$n.log("识别结果:", r),
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$m = SDKLogger.createModuleConsole("MqttManager");
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$m.error("Failed to load MQTT config from storage:", e);
5370
+ console$n.error("Failed to load MQTT config from storage:", e);
5371
5371
  }
5372
5372
  }
5373
5373
  if (!effectiveConfig) {
5374
- console$m.error("MQTT connect: No config provided and no stored config");
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$m.error("Failed to load MQTT library:", e);
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$m.log("Connecting to MQTT with options:", connectOptions);
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$m.error("MQTT Error:", err);
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$m.log(`MQTT Reconnecting... (${this.retryCount}/${this.maxRetries})`);
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$m.error("MQTT Connection Exception:", e);
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$m.log("MQTT Connected");
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$m.log("MQTT Closed");
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$m.log(`message ${msgStr}
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$m.log(`Subscribed to ${topic}`);
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$l = SDKLogger.createModuleConsole("AgentTool");
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$l.log(`[CopilotTools] runAsyncAgentTask session='${session.name ?? "root"}' target='${resolvedAgentName}' callbackMode=${callbackMode ?? "delay"} task=${this.summarizeDebugValue(task)}`);
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$l.log(`[CopilotTools] runAsyncAgentTask ${label} expanded via sandbox: ${this.summarizeDebugValue(expanded)}`);
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$l.warn(`[CopilotTools] runAsyncAgentTask: ${label} template expansion failed. Error: ${e.message}`);
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$l.error(`[CopilotTools] ${targetLabel}.sendMessage failed:`, e);
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$l.error(`[CopilotTools] ${targetLabel}.sendMessage failed:`, e2);
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$k = SDKLogger.createModuleConsole("PersonalPageTool");
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$k.log(`[PersonalPageTool] Loading data from file '${filePageName}', key '${storageKey}'`);
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$k.error("[PersonalPageTool] Load failed:", e);
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$k.log(`[PersonalPageTool] Saving data to file '${filePageName}', key '${storageKey}'`, data);
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$k.error("[PersonalPageTool] Save failed:", e);
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$j = SDKLogger.createModuleConsole("ExecuteTool");
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$j;
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$i = SDKLogger.createModuleConsole("AIChat");
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$i.warn("Failed to get token from localStorage:", e);
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$i.log("[AIChat] _restartSignal detected, aborting tool loop");
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$i.error("Tool call execution failed:", error);
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$i.log("[AIChat] _restartSignal detected, aborting chat recursion");
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$h = SDKLogger.createModuleConsole("ChildSessionMixin");
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$h.log(`[ChildSessionMixin] Child agent '${name}' created`);
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$h.log(`[ChildSessionMixin] Merged task into queue for child '${name}'`);
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$h.log(`[ChildSessionMixin] Child '${name}' completed task ${taskObj.id}; pendingChildResults=${this._pendingChildResults.length}; result=${_summarize(result)}`);
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$h.error(`[ChildSessionMixin] Child '${name}' task ${taskObj.id} failed:`, e);
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$h.warn(`[ChildSessionMixin] Child '${name}' failure queued; taskId=${taskObj.id}; pendingChildResults=${this._pendingChildResults.length}; result=${_summarize(errorResult)}`);
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$h.warn("[ChildSessionMixin] onChildStream callback error:", e);
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$h.log(
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$h.log(
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$h.warn("[ChildSessionMixin] _triggerImmediateCallback not overridden — child results will accumulate until next send.");
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$h.log(`[ChildSessionMixin] Debounce callback set: ${seconds}s pendingChildResults=${this._pendingChildResults.length}`);
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$g = SDKLogger.createModuleConsole("ImageUtils");
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$g.log(
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$g.warn(
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$g.log(`[ImageUtils] File already exists at ${cdnUrl}, skipping upload`);
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$g.log(`[ImageUtils] Uploaded to ${cdnUrl} (${(blob.size / 1024).toFixed(1)} KB)`);
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 isWeChat = detectWxEnvironment().isWeChat;
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: 60
11925
+ channel
11357
11926
  });
11358
- if (response && response.token) {
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._finish(response);
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._finish(data);
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._finish(response);
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.sdk.setToken(response.token);
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; z-index: 99999;
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
- width: 100vw;
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: 100vh;
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._cleanupChildSessions();
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
- Object.assign(RTCChatSession.prototype, childSessionMethods);
21153
- RTCChatSession.prototype._triggerImmediateCallback = async function() {
21154
- if (this._isSending) {
21155
- await new Promise((resolve) => {
21156
- const check = () => {
21157
- if (!this._isSending) resolve();
21158
- else setTimeout(check, 50);
21159
- };
21160
- setTimeout(check, 50);
21161
- });
21162
- }
21163
- if (this._pendingChildResults.length === 0) return;
21164
- try {
21165
- await this.send(null, this._lastSendOptions);
21166
- } catch (e) {
21167
- console$9.error("[RTCChatSession] Immediate callback send failed:", e);
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._cleanupChildSessions();
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
- Object.assign(LocalRTCSession.prototype, childSessionMethods);
24437
- LocalRTCSession.prototype._triggerImmediateCallback = async function() {
24438
- if (this._pendingChildResults.length === 0) return;
24439
- const results = this._consumePendingChildResults();
24440
- const parts = results.map((cr) => {
24441
- const resultText = typeof cr.result === "string" ? cr.result : JSON.stringify(cr.result);
24442
- return `[Agent ${cr.agentName}] Task: ${cr.taskSummary}
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
- const summary = parts.join("\n\n");
24446
- this.sendText(summary);
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