@kafca/agentdock 0.1.46 → 0.1.48

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.
Files changed (103) hide show
  1. package/README.md +11 -0
  2. package/dist/renderer/assets/{Badge-BIesaDYG.js → Badge-C92lMj9Q.js} +1 -1
  3. package/dist/renderer/assets/{Chat-CpataoDh.js → Chat-DqoKCPwz.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-_Mdmltgv.js → ChatMarkdown-C4psQvmt.js} +1 -1
  5. package/dist/renderer/assets/{Config-Pe5-zKZk.js → Config-1uk8FQL7.js} +2 -2
  6. package/dist/renderer/assets/{CronList-BnaOSPT8.js → CronList-DnKCiYWC.js} +1 -1
  7. package/dist/renderer/assets/{Dashboard-D05l8GKE.js → Dashboard-rOAQcJA0.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-BDBavDll.js → EmptyState-bF6Sc61O.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-DvR798l_.js → KnowledgeDetail-C5-Dp95R.js} +2 -2
  10. package/dist/renderer/assets/{KnowledgeHome-r2ZuvU8-.js → KnowledgeHome-DGa1EWXD.js} +2 -2
  11. package/dist/renderer/assets/{Logs-BaljtmAV.js → Logs-CKKVW2k8.js} +1 -1
  12. package/dist/renderer/assets/{Modal-CXhD_OWR.js → Modal-DIc9HxD5.js} +3 -3
  13. package/dist/renderer/assets/{MonitorList-D7tyipbx.js → MonitorList-D2YOJRIX.js} +1 -1
  14. package/dist/renderer/assets/{Page-KUuFYgjg.js → Page-vZ-_l6Kn.js} +1 -1
  15. package/dist/renderer/assets/ProjectDetail-CqTa6kAh.js +11 -0
  16. package/dist/renderer/assets/{ProjectList-CbdHd5Ev.js → ProjectList-LgDQVVyZ.js} +1 -1
  17. package/dist/renderer/assets/{Select-Djc8BXMC.js → Select-BN2HMOmY.js} +1 -1
  18. package/dist/renderer/assets/SessionChat-Beco1N1T.js +1 -0
  19. package/dist/renderer/assets/{SessionList-DHgl1s1D.js → SessionList-3NkskCJJ.js} +1 -1
  20. package/dist/renderer/assets/ThreadChat-Ji8pOm5p.js +28 -0
  21. package/dist/renderer/assets/{Workspace-DTocqY-F.js → Workspace-yarrGItB.js} +1 -1
  22. package/dist/renderer/assets/{arrow-left-CXyya3hP.js → arrow-left-DNovvfPp.js} +1 -1
  23. package/dist/renderer/assets/{book-open-9n4Kxc7E.js → book-open-CarZFsXv.js} +1 -1
  24. package/dist/renderer/assets/{bot-C9HBk5XH.js → bot-g16rGMp6.js} +1 -1
  25. package/dist/renderer/assets/{check-CutSg9a5.js → check-DjFX73Zi.js} +1 -1
  26. package/dist/renderer/assets/{chevron-down-DrydR4i3.js → chevron-down-B02YlQS_.js} +1 -1
  27. package/dist/renderer/assets/{circle-BEjtahw6.js → circle-DPfWdG1F.js} +1 -1
  28. package/dist/renderer/assets/{desktop-DATgk_ka.js → desktop-DMkue1T6.js} +1 -1
  29. package/dist/renderer/assets/{funnel-BhqZpS4f.js → funnel-Dy1VL-D9.js} +1 -1
  30. package/dist/renderer/assets/{heart-Dp8Vs-7_.js → heart-YjvGwq5-.js} +1 -1
  31. package/dist/renderer/assets/{index-BKpv0P0s.js → index-CZN1STMc.js} +2 -2
  32. package/dist/renderer/assets/index-CjCuR6DI.css +11 -0
  33. package/dist/renderer/assets/{index-cI3pWBnN.js → index-mvjDN9uV.js} +9 -9
  34. package/dist/renderer/assets/{pencil-ywcJzeOo.js → pencil-qpMjLIFd.js} +1 -1
  35. package/dist/renderer/assets/{play-AtN492Cx.js → play-CPCcNQcH.js} +1 -1
  36. package/dist/renderer/assets/{plus-BEj14BBV.js → plus-B76JWGKd.js} +1 -1
  37. package/dist/renderer/assets/projects-C1nFINjh.js +1 -0
  38. package/dist/renderer/assets/{save-D6ov4CNv.js → save-DtvrD3W1.js} +1 -1
  39. package/dist/renderer/assets/{search-C3bvw7AR.js → search-Ddth-YHH.js} +1 -1
  40. package/dist/renderer/assets/{server-C1Uyedyx.js → server-D0zmghb3.js} +1 -1
  41. package/dist/renderer/assets/{session-utils-DpRwJ6Nh.js → session-utils-C9oe-21F.js} +1 -1
  42. package/dist/renderer/assets/{sessions-BWmAppwK.js → sessions-BXOnLLah.js} +1 -1
  43. package/dist/renderer/assets/{shield-check-CVx1mEs2.js → shield-check-Cv5d_blH.js} +1 -1
  44. package/dist/renderer/assets/{trash-2-o-heXOgs.js → trash-2-C2mimX2b.js} +1 -1
  45. package/dist/renderer/assets/{user-dPOzUqIc.js → user-BrLJ4elW.js} +1 -1
  46. package/dist/renderer/assets/{wifi-off-Fz5c3_x_.js → wifi-off-DvRJYLbG.js} +1 -1
  47. package/dist/renderer/index.html +2 -2
  48. package/dist-electron/packages/core-sdk/src/index.js +4 -0
  49. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +53 -7
  50. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +3 -0
  51. package/dist-electron/services/local-ai-core/src/acp/store/platform-store.js +13 -5
  52. package/dist-electron/services/local-ai-core/src/acp/store/schema.js +1 -0
  53. package/dist-electron/services/local-ai-core/src/acp/store/thread-store.js +3 -0
  54. package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +1 -1
  55. package/dist-electron/services/local-ai-core/src/agents/shared/launch-utils.js +22 -0
  56. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +132 -348
  57. package/dist-electron/services/local-ai-core/src/channel/shared/base-channel-gateway.js +306 -0
  58. package/dist-electron/services/local-ai-core/src/channel/shared/session-command-runtime.js +14 -3
  59. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +131 -382
  60. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +8 -1
  61. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +2 -1
  62. package/dist-electron/services/local-ai-core/src/runtime/channel-service.js +150 -0
  63. package/dist-electron/services/local-ai-core/src/runtime/env-utils.js +12 -0
  64. package/dist-electron/services/local-ai-core/src/runtime/external-service.js +234 -0
  65. package/dist-electron/services/local-ai-core/src/runtime/handlers/automation-handler.js +34 -0
  66. package/dist-electron/services/local-ai-core/src/runtime/handlers/capabilities-handler.js +12 -0
  67. package/dist-electron/services/local-ai-core/src/runtime/handlers/channel-handler.js +65 -0
  68. package/dist-electron/services/local-ai-core/src/runtime/handlers/external-handler.js +17 -0
  69. package/dist-electron/services/local-ai-core/src/runtime/handlers/knowledge-handler.js +65 -0
  70. package/dist-electron/services/local-ai-core/src/runtime/handlers/openai-handler.js +496 -0
  71. package/dist-electron/services/local-ai-core/src/runtime/handlers/provider-handler.js +24 -0
  72. package/dist-electron/services/local-ai-core/src/runtime/handlers/runtime-handler.js +68 -0
  73. package/dist-electron/services/local-ai-core/src/runtime/handlers/runtimes-handler.js +37 -0
  74. package/dist-electron/services/local-ai-core/src/runtime/handlers/scheduler-handler.js +34 -0
  75. package/dist-electron/services/local-ai-core/src/runtime/handlers/security-handler.js +49 -0
  76. package/dist-electron/services/local-ai-core/src/runtime/handlers/task-handler.js +27 -0
  77. package/dist-electron/services/local-ai-core/src/runtime/handlers/thread-handler.js +46 -0
  78. package/dist-electron/services/local-ai-core/src/runtime/handlers/workspace-handler.js +29 -0
  79. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +40 -592
  80. package/dist-electron/services/local-ai-core/src/runtime/server-helpers.js +96 -0
  81. package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +3 -0
  82. package/dist-electron/services/local-ai-core/src/runtime/server.js +107 -1084
  83. package/dist-electron/services/local-ai-core/src/runtime/standalone.js +13 -1
  84. package/dist-electron/services/local-ai-core/src/thread/thread-command-service.js +23 -2
  85. package/dist-electron/services/local-ai-core/src/thread/thread-slash-command-dispatcher.js +1 -0
  86. package/dist-electron/src/pages/Projects/project-provider-config.js +75 -0
  87. package/dist-electron/src/pages/Threads/thread-chat-model.js +2 -0
  88. package/dist-electron/tests/contracts/architecture-docs.test.js +1 -0
  89. package/dist-electron/tests/electron/agent-runtime-detector.test.js +18 -0
  90. package/dist-electron/tests/electron/knowledge-skill-script.test.js +15 -5
  91. package/dist-electron/tests/electron/lac-cli.test.js +591 -688
  92. package/dist-electron/tests/electron/plugin-kernel.test.js +47 -31
  93. package/dist-electron/tests/electron/project-provider-config.test.js +71 -0
  94. package/dist-electron/tests/electron/workspace-task-store.test.js +40 -11
  95. package/dist-electron/tests/integration/local-core-cors.test.js +22 -0
  96. package/dist-electron/tests/integration/local-core-refactor.test.js +177 -0
  97. package/dist-electron/tests/integration/local-core-routes.test.js +45 -0
  98. package/package.json +2 -2
  99. package/dist/renderer/assets/ProjectDetail-Ddq94-yu.js +0 -11
  100. package/dist/renderer/assets/SessionChat-DOy0iKQR.js +0 -1
  101. package/dist/renderer/assets/ThreadChat-I7dYibDc.js +0 -23
  102. package/dist/renderer/assets/index-CO4fGqmv.css +0 -11
  103. package/dist/renderer/assets/projects-Clar8lgb.js +0 -1
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-cI3pWBnN.js";/**
1
+ import{c as a}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-cI3pWBnN.js";/**
1
+ import{c as o}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-cI3pWBnN.js";/**
1
+ import{c as e}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -0,0 +1 @@
1
+ import{D as t}from"./index-mvjDN9uV.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-cI3pWBnN.js";/**
1
+ import{c as a}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-cI3pWBnN.js";/**
1
+ import{c}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-cI3pWBnN.js";/**
1
+ import{c as e}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-cI3pWBnN.js";/**
1
+ import{c as o}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{A as o}from"./index-cI3pWBnN.js";const i=s=>o.get(`/projects/${s}/sessions`),c=(s,e,t)=>o.get(`/projects/${s}/sessions/${e}`,{history_limit:String(t)}),r=(s,e,t)=>o.patch(`/projects/${s}/sessions/${e}`,t),a=(s,e)=>o.delete(`/projects/${s}/sessions/${e}`),p=(s,e)=>o.post(`/projects/${s}/sessions/switch`,e),$=(s,e)=>o.post(`/projects/${s}/send`,e);export{$ as a,a as d,c as g,i as l,r,p as s};
1
+ import{D as o}from"./index-mvjDN9uV.js";const i=s=>o.get(`/projects/${s}/sessions`),c=(s,e,t)=>o.get(`/projects/${s}/sessions/${e}`,{history_limit:String(t)}),r=(s,e,t)=>o.patch(`/projects/${s}/sessions/${e}`,t),a=(s,e)=>o.delete(`/projects/${s}/sessions/${e}`),p=(s,e)=>o.post(`/projects/${s}/sessions/switch`,e),$=(s,e)=>o.post(`/projects/${s}/send`,e);export{$ as a,a as d,c as g,i as l,r,p as s};
@@ -1,4 +1,4 @@
1
- import{c}from"./index-cI3pWBnN.js";/**
1
+ import{c}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-cI3pWBnN.js";/**
1
+ import{c as e}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c}from"./index-cI3pWBnN.js";/**
1
+ import{c}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-cI3pWBnN.js";/**
1
+ import{c as a}from"./index-mvjDN9uV.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="./favicon.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>AgentDock</title>
8
- <script type="module" crossorigin src="./assets/index-cI3pWBnN.js"></script>
9
- <link rel="stylesheet" crossorigin href="./assets/index-CO4fGqmv.css">
8
+ <script type="module" crossorigin src="./assets/index-mvjDN9uV.js"></script>
9
+ <link rel="stylesheet" crossorigin href="./assets/index-CjCuR6DI.css">
10
10
  </head>
11
11
  <body class="bg-[#f5f5f7] dark:bg-[#151516]">
12
12
  <div id="root"></div>
@@ -85,6 +85,7 @@ exports.createThread = createThread;
85
85
  exports.getThread = getThread;
86
86
  exports.renameThread = renameThread;
87
87
  exports.updateThreadKnowledgeBases = updateThreadKnowledgeBases;
88
+ exports.updateThreadMode = updateThreadMode;
88
89
  exports.deleteThread = deleteThread;
89
90
  exports.sendMessage = sendMessage;
90
91
  exports.sendAction = sendAction;
@@ -498,6 +499,9 @@ async function renameThread(threadId, title) {
498
499
  async function updateThreadKnowledgeBases(threadId, knowledgeBaseIds) {
499
500
  return coreRequest('PATCH', `/threads/${encodeURIComponent(threadId)}/knowledge-bases`, { knowledgeBaseIds });
500
501
  }
502
+ async function updateThreadMode(threadId, mode) {
503
+ return coreRequest('PATCH', `/threads/${encodeURIComponent(threadId)}/mode`, { mode });
504
+ }
501
505
  async function deleteThread(threadId) {
502
506
  return coreRequest('DELETE', `/threads/${encodeURIComponent(threadId)}`);
503
507
  }
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LocalCoreAcpSessionCoordinator = void 0;
4
4
  exports.buildAgentPath = buildAgentPath;
5
5
  const node_path_1 = require("node:path");
6
+ const node_fs_1 = require("node:fs");
6
7
  const node_os_1 = require("node:os");
7
8
  const scheduled_job_route_js_1 = require("../scheduler/scheduled-job-route.js");
9
+ const env_utils_js_1 = require("../runtime/env-utils.js");
8
10
  class LocalCoreAcpSessionCoordinator {
9
11
  options;
10
12
  sessions = new Map();
@@ -69,7 +71,7 @@ class LocalCoreAcpSessionCoordinator {
69
71
  threadId,
70
72
  bridgeSessionKey,
71
73
  config,
72
- runtimeEnv: this.buildAgentRuntimeEnv(threadId, String(baseEnv.PATH || ''), options.runtimeEnv, options.runId),
74
+ runtimeEnv: this.buildAgentRuntimeEnv(threadId, (0, env_utils_js_1.getPathEnv)(baseEnv), options.runtimeEnv, options.runId),
73
75
  });
74
76
  session.launchPermissionMode = permissionMode;
75
77
  session.launchConfigKey = configKey;
@@ -289,11 +291,14 @@ exports.LocalCoreAcpSessionCoordinator = LocalCoreAcpSessionCoordinator;
289
291
  function acpSessionCwd(config) {
290
292
  return config.sandbox?.enabled ? config.sandbox.workspaceMountPath : config.workDir;
291
293
  }
292
- function buildAgentPath(existingPath, cliBinDir) {
294
+ function buildAgentPath(existingPath, cliBinDir, options = {}) {
295
+ const platform = options.platform || process.platform;
296
+ const pathDelimiter = platform === 'win32' ? ';' : node_path_1.delimiter;
293
297
  const entries = [
294
298
  cliBinDir,
295
- ...userBinDirs(),
296
- ...String(existingPath || '').split(node_path_1.delimiter),
299
+ ...userBinDirs(platform),
300
+ ...windowsGitBashDirs(existingPath, platform, options.pathExists || node_fs_1.existsSync),
301
+ ...String(existingPath || '').split(pathDelimiter),
297
302
  ];
298
303
  const seen = new Set();
299
304
  return entries
@@ -305,12 +310,53 @@ function buildAgentPath(existingPath, cliBinDir) {
305
310
  seen.add(entry);
306
311
  return true;
307
312
  })
308
- .join(node_path_1.delimiter);
313
+ .join(pathDelimiter);
309
314
  }
310
- function userBinDirs() {
311
- if (process.platform === 'win32') {
315
+ function userBinDirs(platform) {
316
+ if (platform === 'win32') {
312
317
  return [];
313
318
  }
314
319
  const home = process.env.HOME || (0, node_os_1.homedir)();
315
320
  return home ? [`${home}/.local/bin`, `${home}/bin`] : [];
316
321
  }
322
+ function windowsGitBashDirs(existingPath, platform, pathExists) {
323
+ if (platform !== 'win32') {
324
+ return [];
325
+ }
326
+ const pathEntries = String(existingPath || '')
327
+ .split(';')
328
+ .map((entry) => entry.trim())
329
+ .filter(Boolean);
330
+ const gitRoots = new Set();
331
+ for (const entry of pathEntries) {
332
+ const normalized = node_path_1.win32.normalize(entry).replace(/[\\/]+$/, '');
333
+ const base = node_path_1.win32.basename(normalized).toLowerCase();
334
+ const parent = node_path_1.win32.dirname(normalized);
335
+ const parentBase = node_path_1.win32.basename(parent).toLowerCase();
336
+ const grandParent = node_path_1.win32.dirname(parent);
337
+ if (base === 'cmd' && parentBase === 'git') {
338
+ gitRoots.add(parent);
339
+ }
340
+ else if (base === 'bin' && parentBase === 'git') {
341
+ gitRoots.add(parent);
342
+ }
343
+ else if (base === 'bin' && parentBase === 'usr' && node_path_1.win32.basename(grandParent).toLowerCase() === 'git') {
344
+ gitRoots.add(grandParent);
345
+ }
346
+ }
347
+ for (const root of ['C:\\Program Files\\Git', 'C:\\Program Files (x86)\\Git', 'D:\\Program Files\\Git']) {
348
+ gitRoots.add(root);
349
+ }
350
+ const dirs = [];
351
+ for (const root of gitRoots) {
352
+ const binDir = node_path_1.win32.join(root, 'bin');
353
+ if (pathExists(node_path_1.win32.join(binDir, 'bash.exe'))) {
354
+ dirs.push(binDir);
355
+ }
356
+ const usrBinDir = node_path_1.win32.join(root, 'usr', 'bin');
357
+ if (pathExists(node_path_1.win32.join(usrBinDir, 'bash.exe'))) {
358
+ dirs.push(usrBinDir);
359
+ }
360
+ }
361
+ return dirs;
362
+ }
@@ -281,6 +281,9 @@ class LocalCoreAcpStore {
281
281
  upsertPlatformThreadBinding(input) {
282
282
  this.platform.upsertPlatformThreadBinding(input);
283
283
  }
284
+ updatePlatformThreadPreferredAgent(workspaceId, chatId, platformUserId, agentType, platform = 'lark') {
285
+ this.platform.updatePlatformThreadPreferredAgent(workspaceId, chatId, platformUserId, agentType, platform);
286
+ }
284
287
  updatePlatformThreadMessageId(workspaceId, chatId, platformUserId, messageId, platform = 'lark') {
285
288
  this.platform.updatePlatformThreadMessageId(workspaceId, chatId, platformUserId, messageId, platform);
286
289
  }
@@ -107,14 +107,14 @@ class LocalPlatformStore {
107
107
  }
108
108
  getPlatformThreadBinding(workspaceId, chatId, platformUserId, platform = 'lark') {
109
109
  return this.db.prepare(`
110
- SELECT workspace_id, platform, chat_id, platform_user_id, thread_id, last_platform_message_id, created_at, updated_at
110
+ SELECT workspace_id, platform, chat_id, platform_user_id, thread_id, last_platform_message_id, preferred_agent_type, created_at, updated_at
111
111
  FROM platform_thread_bindings
112
112
  WHERE workspace_id = ? AND platform = ? AND chat_id = ? AND platform_user_id = ?
113
113
  `).get(workspaceId, platform, chatId, platformUserId);
114
114
  }
115
115
  getPlatformThreadBindingByThreadId(threadId) {
116
116
  return this.db.prepare(`
117
- SELECT workspace_id, platform, chat_id, platform_user_id, thread_id, last_platform_message_id, created_at, updated_at
117
+ SELECT workspace_id, platform, chat_id, platform_user_id, thread_id, last_platform_message_id, preferred_agent_type, created_at, updated_at
118
118
  FROM platform_thread_bindings
119
119
  WHERE thread_id = ?
120
120
  ORDER BY updated_at DESC
@@ -127,13 +127,21 @@ class LocalPlatformStore {
127
127
  upsertPlatformThreadBinding(input) {
128
128
  this.db.prepare(`
129
129
  INSERT INTO platform_thread_bindings
130
- (workspace_id, platform, chat_id, platform_user_id, thread_id, last_platform_message_id, created_at, updated_at)
131
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
130
+ (workspace_id, platform, chat_id, platform_user_id, thread_id, last_platform_message_id, preferred_agent_type, created_at, updated_at)
131
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
132
132
  ON CONFLICT(workspace_id, platform, chat_id, platform_user_id) DO UPDATE SET
133
133
  thread_id = excluded.thread_id,
134
134
  last_platform_message_id = COALESCE(excluded.last_platform_message_id, platform_thread_bindings.last_platform_message_id),
135
+ preferred_agent_type = COALESCE(excluded.preferred_agent_type, platform_thread_bindings.preferred_agent_type),
135
136
  updated_at = excluded.updated_at
136
- `).run(input.workspace_id, input.platform || 'lark', input.chat_id, input.platform_user_id, input.thread_id, input.last_platform_message_id, input.created_at, input.updated_at);
137
+ `).run(input.workspace_id, input.platform || 'lark', input.chat_id, input.platform_user_id, input.thread_id, input.last_platform_message_id, input.preferred_agent_type ?? null, input.created_at, input.updated_at);
138
+ }
139
+ updatePlatformThreadPreferredAgent(workspaceId, chatId, platformUserId, agentType, platform = 'lark') {
140
+ this.db.prepare(`
141
+ UPDATE platform_thread_bindings
142
+ SET preferred_agent_type = ?, updated_at = ?
143
+ WHERE workspace_id = ? AND platform = ? AND chat_id = ? AND platform_user_id = ?
144
+ `).run(agentType, new Date().toISOString(), workspaceId, platform, chatId, platformUserId);
137
145
  }
138
146
  updatePlatformThreadMessageId(workspaceId, chatId, platformUserId, messageId, platform = 'lark') {
139
147
  this.db.prepare(`
@@ -301,6 +301,7 @@ function ensureLocalCoreAcpSchema(db) {
301
301
  ensureColumn(db, 'messages', 'tool_call_json', 'TEXT');
302
302
  ensureColumn(db, 'messages', 'bridge_kind', 'TEXT');
303
303
  ensureColumn(db, 'messages', 'bridge_status', 'TEXT');
304
+ ensureColumn(db, 'platform_thread_bindings', 'preferred_agent_type', 'TEXT');
304
305
  ensureColumn(db, 'scheduled_jobs', 'execution_mode', "TEXT NOT NULL DEFAULT 'same-thread'");
305
306
  ensureColumn(db, 'scheduled_job_runs', 'platform_message_ids_json', 'TEXT');
306
307
  ensureColumn(db, 'scheduled_job_runs', 'delivery_mode', 'TEXT');
@@ -31,6 +31,7 @@ class LocalThreadStore {
31
31
  runId: undefined,
32
32
  bridgeSessionKey: row.bridge_session_key,
33
33
  agentType: row.agent_type,
34
+ agentMode: row.agent_mode,
34
35
  }));
35
36
  }
36
37
  count(workspaceId) {
@@ -57,6 +58,7 @@ class LocalThreadStore {
57
58
  excerpt: '',
58
59
  bridgeSessionKey,
59
60
  agentType,
61
+ agentMode: agentMode || 'default',
60
62
  messages: [],
61
63
  selectedKnowledgeBaseIds: [],
62
64
  pendingPermissionRequest: null,
@@ -84,6 +86,7 @@ class LocalThreadStore {
84
86
  excerpt: row.excerpt,
85
87
  bridgeSessionKey: row.bridge_session_key,
86
88
  agentType: row.agent_type,
89
+ agentMode: row.agent_mode,
87
90
  messages: messages.map((message) => ({
88
91
  id: message.id,
89
92
  role: message.role,
@@ -10,7 +10,7 @@ function resolvePiModel(input) {
10
10
  }
11
11
  function buildPiLaunchConfig(input) {
12
12
  const bundledPiAcp = (0, launch_utils_js_1.resolveBundledAcpCommand)(desktop_js_1.DESKTOP_PI_ACP_PACKAGE, 'pi-acp');
13
- const bundledPiCommand = (0, launch_utils_js_1.resolveBundledAcpCommand)(desktop_js_1.DESKTOP_PI_CODING_AGENT_PACKAGE, 'pi').args[0];
13
+ const bundledPiCommand = (0, launch_utils_js_1.resolveBundledBinCommand)(desktop_js_1.DESKTOP_PI_CODING_AGENT_PACKAGE, 'pi');
14
14
  return {
15
15
  command: bundledPiAcp.command,
16
16
  args: [...bundledPiAcp.args],
@@ -9,6 +9,7 @@ exports.ensurePrivateDir = ensurePrivateDir;
9
9
  exports.writeJsonFile = writeJsonFile;
10
10
  exports.projectLocalStateDir = projectLocalStateDir;
11
11
  exports.resolveBundledAcpCommand = resolveBundledAcpCommand;
12
+ exports.resolveBundledBinCommand = resolveBundledBinCommand;
12
13
  exports.resolveBundledPackageJsonPath = resolveBundledPackageJsonPath;
13
14
  const node_module_1 = require("node:module");
14
15
  const node_fs_1 = require("node:fs");
@@ -94,6 +95,27 @@ function resolveBundledAcpCommand(packageName, binName) {
94
95
  args: [(0, node_path_1.resolve)((0, node_path_1.dirname)(packageJsonPath), relativeBinPath)],
95
96
  };
96
97
  }
98
+ function resolveBundledBinCommand(packageName, binName) {
99
+ if (process.platform === 'win32') {
100
+ const shim = resolveBundledWindowsBinShim(packageName, binName);
101
+ if (shim) {
102
+ return shim;
103
+ }
104
+ }
105
+ return resolveBundledAcpCommand(packageName, binName).args[0];
106
+ }
107
+ function resolveBundledWindowsBinShim(packageName, binName) {
108
+ const require = (0, node_module_1.createRequire)(__filename);
109
+ for (const basePath of require.resolve.paths(packageName) || []) {
110
+ for (const extension of ['.CMD', '.cmd', '.BAT', '.bat']) {
111
+ const candidate = (0, node_path_1.resolve)(basePath, '.bin', `${binName}${extension}`);
112
+ if ((0, node_fs_1.existsSync)(candidate)) {
113
+ return candidate;
114
+ }
115
+ }
116
+ }
117
+ return '';
118
+ }
97
119
  function resolveBundledPackageJsonPath(packageName) {
98
120
  const require = (0, node_module_1.createRequire)(__filename);
99
121
  try {