@kafca/agentdock 0.1.29 → 0.1.31

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 (97) hide show
  1. package/README.md +4 -0
  2. package/dist/renderer/assets/{Badge-ngf0eCzI.js → Badge-DaHt-aUT.js} +1 -1
  3. package/dist/renderer/assets/{Chat-tCGY5odh.js → Chat-Dzeq3kiD.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-vqDWgVNb.js → ChatMarkdown-B-L5Roai.js} +1 -1
  5. package/dist/renderer/assets/{Config-YsVDQmIs.js → Config-BI4LJ7Fw.js} +1 -1
  6. package/dist/renderer/assets/{CronList-DQN0T7Yc.js → CronList-Dic7pblj.js} +1 -1
  7. package/dist/renderer/assets/{Dashboard-C2O6Yxq3.js → Dashboard-C0_ATyGe.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-CTkA-fBQ.js → EmptyState-SQsG1DZP.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-DjLZDItQ.js → KnowledgeDetail-D4yUJzp7.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeHome-2NHeRZxW.js → KnowledgeHome-L0tsg-oo.js} +1 -1
  11. package/dist/renderer/assets/{Logs-CQ6j-Sct.js → Logs-C2Jdr3uQ.js} +1 -1
  12. package/dist/renderer/assets/{Modal-9g1uWJfC.js → Modal-GUH3iPXo.js} +1 -1
  13. package/dist/renderer/assets/{Page-B4mPLn6n.js → Page-m42FBy97.js} +1 -1
  14. package/dist/renderer/assets/{ProjectDetail-pBXOAeL4.js → ProjectDetail-RF_sagPO.js} +1 -1
  15. package/dist/renderer/assets/{ProjectList-B9PYfZaS.js → ProjectList-Cyr8RDK3.js} +1 -1
  16. package/dist/renderer/assets/{Select-BWFQJ2R8.js → Select-CRlDgI5s.js} +1 -1
  17. package/dist/renderer/assets/{SessionChat-fBrzJs3A.js → SessionChat-_HhzMwEO.js} +1 -1
  18. package/dist/renderer/assets/{SessionList-DjHOsk7X.js → SessionList-DNwZjGTv.js} +1 -1
  19. package/dist/renderer/assets/ThreadChat-DxBmdsAm.js +23 -0
  20. package/dist/renderer/assets/{Workspace-nfTcxlhw.js → Workspace-DFphG85O.js} +1 -1
  21. package/dist/renderer/assets/{arrow-left-CIWZ6JEB.js → arrow-left-bILMzse7.js} +1 -1
  22. package/dist/renderer/assets/{book-open-Ck6BgBhN.js → book-open-BNBWEEve.js} +1 -1
  23. package/dist/renderer/assets/{check-CtB2ZLVE.js → check-MGp5kvnb.js} +1 -1
  24. package/dist/renderer/assets/{chevron-down--8lODnN0.js → chevron-down-zsfoTlh7.js} +1 -1
  25. package/dist/renderer/assets/{circle-CKQOJcbh.js → circle-BX_xUSg-.js} +1 -1
  26. package/dist/renderer/assets/{desktop-Do2I28CT.js → desktop-CgrO_cdQ.js} +1 -1
  27. package/dist/renderer/assets/{desktop-BkMW-h5p.js → desktop-O8_6ZCVZ.js} +2 -2
  28. package/dist/renderer/assets/{funnel-CkZuFIwa.js → funnel-7442U1wq.js} +1 -1
  29. package/dist/renderer/assets/{heart-CAX_CqFQ.js → heart-B3d8bnSH.js} +1 -1
  30. package/dist/renderer/assets/{index--_L0Y77h.js → index-5YUqCvBf.js} +1 -1
  31. package/dist/renderer/assets/{index-DvAYflFj.js → index-BBaYsVjU.js} +2 -2
  32. package/dist/renderer/assets/{pencil-sIRhtchu.js → pencil-QzWgkmoH.js} +1 -1
  33. package/dist/renderer/assets/{play-CJNRbCL5.js → play-Bsc8hSI7.js} +1 -1
  34. package/dist/renderer/assets/{plug-DsFe9GBx.js → plug-CRY7sjvB.js} +1 -1
  35. package/dist/renderer/assets/{plus-KDwEI-Rs.js → plus-Dr5Ei8Ud.js} +1 -1
  36. package/dist/renderer/assets/projects-BDYSOFIJ.js +1 -0
  37. package/dist/renderer/assets/{save-C-p5r3K-.js → save-giJnp2Ki.js} +1 -1
  38. package/dist/renderer/assets/{search-BZxQJb2k.js → search-DcvHLmKs.js} +1 -1
  39. package/dist/renderer/assets/{server-BV-K022I.js → server-D_Qu8If5.js} +1 -1
  40. package/dist/renderer/assets/{session-utils-ClQTa8yS.js → session-utils-CsASahfU.js} +1 -1
  41. package/dist/renderer/assets/{sessions-B0FSCA9O.js → sessions-eMpPqp4P.js} +1 -1
  42. package/dist/renderer/assets/{shield-check-B6AjkXUd.js → shield-check-BpF0uIw-.js} +1 -1
  43. package/dist/renderer/assets/{trash-2-41Pv4qRx.js → trash-2-OJFmx3xk.js} +1 -1
  44. package/dist/renderer/assets/{user-NKKHCKm9.js → user-GL_ivaV6.js} +1 -1
  45. package/dist/renderer/assets/{wifi-off-E1ZNhLG5.js → wifi-off-CQT5VNQl.js} +1 -1
  46. package/dist/renderer/index.html +1 -1
  47. package/dist-electron/electron/agent-runtime-detector.test.js +30 -0
  48. package/dist-electron/electron/local-core-refactor.test.js +749 -44
  49. package/dist-electron/electron/plugin-kernel.test.js +81 -1
  50. package/dist-electron/electron/workspace-task-store.test.js +7 -1
  51. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +34 -4
  52. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-progress.js +239 -7
  53. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +10 -6
  54. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-transport.js +1 -0
  55. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +169 -5
  56. package/dist-electron/services/local-ai-core/src/agents/claudecode/behavior.js +5 -0
  57. package/dist-electron/services/local-ai-core/src/agents/claudecode/definition.js +36 -0
  58. package/dist-electron/services/local-ai-core/src/agents/claudecode/index.js +15 -0
  59. package/dist-electron/services/local-ai-core/src/agents/codex/behavior.js +5 -0
  60. package/dist-electron/services/local-ai-core/src/agents/codex/definition.js +24 -0
  61. package/dist-electron/services/local-ai-core/src/agents/codex/index.js +15 -0
  62. package/dist-electron/services/local-ai-core/src/agents/hermes/behavior.js +29 -0
  63. package/dist-electron/services/local-ai-core/src/agents/hermes/definition.js +22 -0
  64. package/dist-electron/services/local-ai-core/src/agents/hermes/index.js +15 -0
  65. package/dist-electron/services/local-ai-core/src/agents/index.js +98 -0
  66. package/dist-electron/services/local-ai-core/src/agents/localcore-acp/behavior.js +5 -0
  67. package/dist-electron/services/local-ai-core/src/agents/localcore-acp/definition.js +14 -0
  68. package/dist-electron/services/local-ai-core/src/agents/localcore-acp/index.js +27 -0
  69. package/dist-electron/services/local-ai-core/src/agents/opencode/behavior.js +5 -0
  70. package/dist-electron/services/local-ai-core/src/agents/opencode/definition.js +18 -0
  71. package/dist-electron/services/local-ai-core/src/agents/opencode/index.js +15 -0
  72. package/dist-electron/services/local-ai-core/src/agents/opencode/launch.js +119 -0
  73. package/dist-electron/services/local-ai-core/src/agents/pi/behavior.js +5 -0
  74. package/dist-electron/services/local-ai-core/src/agents/pi/definition.js +23 -0
  75. package/dist-electron/services/local-ai-core/src/agents/pi/index.js +15 -0
  76. package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +139 -0
  77. package/dist-electron/services/local-ai-core/src/agents/shared/acp-behavior.js +11 -0
  78. package/dist-electron/services/local-ai-core/src/agents/shared/agent-plugin.js +60 -0
  79. package/dist-electron/services/local-ai-core/src/agents/shared/definition.js +12 -0
  80. package/dist-electron/services/local-ai-core/src/agents/shared/launch-utils.js +122 -0
  81. package/dist-electron/services/local-ai-core/src/agents/shared/progress-replay.js +19 -0
  82. package/dist-electron/services/local-ai-core/src/agents/shared/replay-prefix.js +68 -0
  83. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +0 -2
  84. package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +1 -1
  85. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +13 -2
  86. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +8 -7
  87. package/dist-electron/services/local-ai-core/src/plugins/builtin/agent-localcore-acp-plugin.js +9 -130
  88. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +22 -397
  89. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +9 -45
  90. package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +62 -1
  91. package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +2 -12
  92. package/dist-electron/shared/desktop.js +3 -1
  93. package/dist-electron/src/pages/Threads/thread-chat-model.js +27 -18
  94. package/dist-electron/src/pages/Threads/thread-chat-permission.test.js +57 -18
  95. package/package.json +1 -1
  96. package/dist/renderer/assets/ThreadChat-MagPeJD0.js +0 -23
  97. package/dist/renderer/assets/projects-CJUs2vaq.js +0 -1
@@ -369,7 +369,6 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
369
369
  const sessionKey = event.sessionKey;
370
370
  const route = this.threadRouting.get(sessionKey);
371
371
  if (!route) {
372
- this.options.log?.(`localcore-weixin bridge route miss for sessionKey=${sessionKey} type=${event.type}`);
373
372
  return;
374
373
  }
375
374
  const routeInstanceId = route.instanceId || 'default';
@@ -1058,6 +1057,7 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
1058
1057
  previewText: '',
1059
1058
  finalText: '',
1060
1059
  thinkingSteps: [],
1060
+ pendingThoughtText: undefined,
1061
1061
  statusLines: [],
1062
1062
  buttonRows: [],
1063
1063
  lastSentAt: 0,
@@ -1077,6 +1077,7 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
1077
1077
  turn.previewText = '';
1078
1078
  turn.finalText = '';
1079
1079
  turn.thinkingSteps = [];
1080
+ turn.pendingThoughtText = undefined;
1080
1081
  turn.statusLines = [];
1081
1082
  turn.buttonRows = [];
1082
1083
  return;
@@ -1087,12 +1088,15 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
1087
1088
  }
1088
1089
  if (event.type === 'preview_start' || event.type === 'update_message') {
1089
1090
  if (bridgeKind === 'thought') {
1090
- this.pushUnique(turn.thinkingSteps, content);
1091
+ turn.pendingThoughtText = content;
1091
1092
  return;
1092
1093
  }
1093
1094
  turn.previewText = content;
1094
1095
  return;
1095
1096
  }
1097
+ if (bridgeKind !== 'thought') {
1098
+ this.flushPendingThought(turn);
1099
+ }
1096
1100
  if (event.type === 'status') {
1097
1101
  if (content) {
1098
1102
  this.pushUnique(turn.statusLines, content);
@@ -1148,6 +1152,13 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
1148
1152
  }
1149
1153
  return sections.join('\n\n').trim();
1150
1154
  }
1155
+ flushPendingThought(turn) {
1156
+ const text = String(turn.pendingThoughtText || '').trim();
1157
+ if (!text)
1158
+ return;
1159
+ this.pushUnique(turn.thinkingSteps, text);
1160
+ turn.pendingThoughtText = undefined;
1161
+ }
1151
1162
  isTerminalBridgeMessage(event, rendered) {
1152
1163
  if (event.type === 'buttons')
1153
1164
  return true;
@@ -8,7 +8,7 @@ const diagnostics_js_1 = require("./diagnostics.js");
8
8
  const event_bus_js_1 = require("./event-bus.js");
9
9
  const lifecycle_manager_js_1 = require("./lifecycle-manager.js");
10
10
  const plugin_registry_js_1 = require("./plugin-registry.js");
11
- const agent_localcore_acp_plugin_js_1 = require("../plugins/builtin/agent-localcore-acp-plugin.js");
11
+ const index_js_1 = require("../agents/index.js");
12
12
  const channel_lark_plugin_js_1 = require("../plugins/builtin/channel-lark-plugin.js");
13
13
  const channel_weixin_plugin_js_1 = require("../plugins/builtin/channel-weixin-plugin.js");
14
14
  const knowledge_ai_vector_plugin_js_1 = require("../plugins/builtin/knowledge-ai-vector-plugin.js");
@@ -35,8 +35,8 @@ function bootstrapLocalCoreKernel(options) {
35
35
  const lifecycle = new lifecycle_manager_js_1.LocalCoreLifecycleManager(plugins, context);
36
36
  const diagnostics = new diagnostics_js_1.LocalCoreDiagnostics(plugins, lifecycle);
37
37
  const builtIns = [
38
- ...['cursor', 'gemini', 'qoder', 'iflow'].map((agentType) => (0, agent_localcore_acp_plugin_js_1.createBuiltinStaticAgentCapabilityPlugin)(agentType)),
39
- (0, agent_localcore_acp_plugin_js_1.createBuiltinLocalCoreAcpAgentPlugin)(),
38
+ ...(0, index_js_1.getStaticAgentRuntimeDefinitions)().map((definition) => (0, index_js_1.createBuiltinStaticAgentCapabilityPlugin)(definition.agentType, definition.displayName)),
39
+ (0, index_js_1.createBuiltinLocalCoreAcpAgentPlugin)(),
40
40
  (0, scheduler_cron_plugin_js_1.createBuiltinCronSchedulerPlugin)(),
41
41
  ];
42
42
  for (const plugin of builtIns) {
@@ -163,10 +163,11 @@ function bootstrapLocalCoreRuntime(options) {
163
163
  }
164
164
  const agentPlugins = [
165
165
  localCoreAgentPlugin,
166
- (0, agent_localcore_acp_plugin_js_1.createBuiltinPiAgentPlugin)(),
167
- (0, agent_localcore_acp_plugin_js_1.createBuiltinOpencodeAgentPlugin)(),
168
- (0, agent_localcore_acp_plugin_js_1.createBuiltinCodexAgentPlugin)(),
169
- (0, agent_localcore_acp_plugin_js_1.createBuiltinClaudeCodeAgentPlugin)(),
166
+ (0, index_js_1.createBuiltinPiAgentPlugin)(),
167
+ (0, index_js_1.createBuiltinOpencodeAgentPlugin)(),
168
+ (0, index_js_1.createBuiltinCodexAgentPlugin)(),
169
+ (0, index_js_1.createBuiltinClaudeCodeAgentPlugin)(),
170
+ (0, index_js_1.createBuiltinHermesAgentPlugin)(),
170
171
  ];
171
172
  let workspaceRouter;
172
173
  let weixinChannelRuntime;
@@ -1,132 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createBuiltinLocalCoreAcpAgentPlugin = createBuiltinLocalCoreAcpAgentPlugin;
4
- exports.createBuiltinOpencodeAgentPlugin = createBuiltinOpencodeAgentPlugin;
5
- exports.createBuiltinPiAgentPlugin = createBuiltinPiAgentPlugin;
6
- exports.createBuiltinCodexAgentPlugin = createBuiltinCodexAgentPlugin;
7
- exports.createBuiltinClaudeCodeAgentPlugin = createBuiltinClaudeCodeAgentPlugin;
8
- exports.createBuiltinStaticAgentCapabilityPlugin = createBuiltinStaticAgentCapabilityPlugin;
9
- const desktop_js_1 = require("../../../../../shared/desktop.js");
10
- const workspace_route_config_js_1 = require("../../router/workspace-route-config.js");
11
- function createRuntime(agentType, match) {
12
- return {
13
- agentType,
14
- transport: desktop_js_1.LOCALCORE_ACP_AGENT_TYPE,
15
- displayName: agentType,
16
- matchesProject(project) {
17
- const normalizedAgentType = String(project.agent?.type || '').trim().toLowerCase();
18
- return match(normalizedAgentType);
19
- },
20
- createRoute(configState, project) {
21
- if (!this.matchesProject(project)) {
22
- return null;
23
- }
24
- return {
25
- kind: desktop_js_1.LOCALCORE_ACP_AGENT_TYPE,
26
- agentType,
27
- transport: desktop_js_1.LOCALCORE_ACP_AGENT_TYPE,
28
- config: {
29
- ...(0, workspace_route_config_js_1.toLocalCoreProjectConfig)(configState, project),
30
- agentType,
31
- },
32
- supportsStreamingProbe: true,
33
- };
34
- },
35
- };
36
- }
37
- function createBuiltinAgentPlugin(options) {
38
- let runtime = null;
39
- return {
40
- manifest: {
41
- id: options.pluginId,
42
- kind: 'agent',
43
- version: '0.1.0',
44
- provides: [`agent:${options.agentType}`],
45
- },
46
- capabilities: {
47
- agents: [
48
- {
49
- id: `agent.${options.agentType}`,
50
- agentType: options.agentType,
51
- displayName: options.displayName || options.agentType,
52
- },
53
- ],
54
- },
55
- createRuntime(_ctx) {
56
- if (!runtime) {
57
- runtime = createRuntime(options.agentType, options.match);
58
- }
59
- return { runtime };
60
- },
61
- };
62
- }
63
- function createBuiltinLocalCoreAcpAgentPlugin() {
64
- const plugin = createBuiltinAgentPlugin({
65
- pluginId: 'builtin.agent-localcore-acp',
66
- agentType: desktop_js_1.LOCALCORE_ACP_AGENT_TYPE,
67
- match: (normalizedAgentType) => !normalizedAgentType || normalizedAgentType === 'acp' || normalizedAgentType === desktop_js_1.LOCALCORE_ACP_AGENT_TYPE,
68
- displayName: 'LocalCore ACP',
69
- });
70
- plugin.capabilities = {
71
- ...plugin.capabilities,
72
- channels: [
73
- {
74
- id: `channel.${desktop_js_1.LOCALCORE_ACP_AGENT_TYPE}`,
75
- platform: desktop_js_1.LOCALCORE_ACP_AGENT_TYPE,
76
- displayName: 'LocalCore ACP',
77
- },
78
- ],
79
- };
80
- return plugin;
81
- }
82
- function createBuiltinOpencodeAgentPlugin() {
83
- return createBuiltinAgentPlugin({
84
- pluginId: 'builtin.agent-opencode',
85
- agentType: 'opencode',
86
- match: (normalizedAgentType) => normalizedAgentType === 'opencode',
87
- displayName: 'OpenCode',
88
- });
89
- }
90
- function createBuiltinPiAgentPlugin() {
91
- return createBuiltinAgentPlugin({
92
- pluginId: 'builtin.agent-pi',
93
- agentType: 'pi',
94
- match: (normalizedAgentType) => normalizedAgentType === 'pi',
95
- displayName: 'Pi',
96
- });
97
- }
98
- function createBuiltinCodexAgentPlugin() {
99
- return createBuiltinAgentPlugin({
100
- pluginId: 'builtin.agent-codex',
101
- agentType: 'codex',
102
- match: (normalizedAgentType) => normalizedAgentType === 'codex',
103
- displayName: 'Codex',
104
- });
105
- }
106
- function createBuiltinClaudeCodeAgentPlugin() {
107
- return createBuiltinAgentPlugin({
108
- pluginId: 'builtin.agent-claudecode',
109
- agentType: 'claudecode',
110
- match: (normalizedAgentType) => normalizedAgentType === 'claudecode',
111
- displayName: 'Claude Code',
112
- });
113
- }
114
- function createBuiltinStaticAgentCapabilityPlugin(agentType) {
115
- return {
116
- manifest: {
117
- id: `builtin.agent-${agentType}`,
118
- kind: 'agent',
119
- version: '0.1.0',
120
- provides: [`agent:${agentType}`],
121
- },
122
- capabilities: {
123
- agents: [
124
- {
125
- id: `agent.${agentType}`,
126
- agentType,
127
- displayName: agentType,
128
- },
129
- ],
130
- },
131
- };
132
- }
3
+ exports.createBuiltinStaticAgentCapabilityPlugin = exports.createBuiltinPiAgentPlugin = exports.createBuiltinOpencodeAgentPlugin = exports.createBuiltinLocalCoreAcpAgentPlugin = exports.createBuiltinHermesAgentPlugin = exports.createBuiltinClaudeCodeAgentPlugin = exports.createBuiltinCodexAgentPlugin = void 0;
4
+ var index_js_1 = require("../../agents/index.js");
5
+ Object.defineProperty(exports, "createBuiltinCodexAgentPlugin", { enumerable: true, get: function () { return index_js_1.createBuiltinCodexAgentPlugin; } });
6
+ Object.defineProperty(exports, "createBuiltinClaudeCodeAgentPlugin", { enumerable: true, get: function () { return index_js_1.createBuiltinClaudeCodeAgentPlugin; } });
7
+ Object.defineProperty(exports, "createBuiltinHermesAgentPlugin", { enumerable: true, get: function () { return index_js_1.createBuiltinHermesAgentPlugin; } });
8
+ Object.defineProperty(exports, "createBuiltinLocalCoreAcpAgentPlugin", { enumerable: true, get: function () { return index_js_1.createBuiltinLocalCoreAcpAgentPlugin; } });
9
+ Object.defineProperty(exports, "createBuiltinOpencodeAgentPlugin", { enumerable: true, get: function () { return index_js_1.createBuiltinOpencodeAgentPlugin; } });
10
+ Object.defineProperty(exports, "createBuiltinPiAgentPlugin", { enumerable: true, get: function () { return index_js_1.createBuiltinPiAgentPlugin; } });
11
+ Object.defineProperty(exports, "createBuiltinStaticAgentCapabilityPlugin", { enumerable: true, get: function () { return index_js_1.createBuiltinStaticAgentCapabilityPlugin; } });
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizePlatformTypes = normalizePlatformTypes;
4
4
  exports.isLocalCoreNativeAcpProject = isLocalCoreNativeAcpProject;
5
5
  exports.toLocalCoreProjectConfig = toLocalCoreProjectConfig;
6
- const node_module_1 = require("node:module");
7
- const node_fs_1 = require("node:fs");
8
6
  const node_path_1 = require("node:path");
9
7
  const desktop_js_1 = require("../../../../shared/desktop.js");
8
+ const index_js_1 = require("../agents/index.js");
9
+ const launch_utils_js_1 = require("../agents/shared/launch-utils.js");
10
10
  function normalizePlatformTypes(project) {
11
11
  return Array.isArray(project?.platforms)
12
12
  ? project.platforms.map((platform) => (0, desktop_js_1.normalizeDesktopPlatformType)(platform?.type)).filter(Boolean)
@@ -18,348 +18,16 @@ function isLocalCoreNativeAcpProject(project) {
18
18
  || agentType === 'acp'
19
19
  || agentType === desktop_js_1.LOCALCORE_ACP_AGENT_TYPE;
20
20
  }
21
- function resolveAgentModel(project, providers) {
21
+ function resolveAgentModel(project, providers, definition) {
22
22
  const agentType = String(project.agent?.type || '').trim().toLowerCase();
23
23
  const rawModel = String(project.agent?.options?.model || '').trim();
24
24
  const normalizedModel = (0, desktop_js_1.normalizeDesktopAgentModel)(agentType, rawModel);
25
- if (agentType === 'pi') {
26
- return rawModel || getFirstProviderModelId(providers);
27
- }
28
- if (agentType !== 'opencode') {
29
- return normalizedModel;
30
- }
31
- const configuredProviderModel = getFirstProviderModelRef(providers);
32
- if (configuredProviderModel &&
33
- (!rawModel || normalizedModel === desktop_js_1.DEFAULT_DESKTOP_OPENCODE_MODEL)) {
34
- return configuredProviderModel;
35
- }
36
- return normalizedModel;
37
- }
38
- function getFirstProviderModelId(providers) {
39
- for (const provider of providers) {
40
- const modelId = getProviderDefaultModelId(provider);
41
- if (modelId) {
42
- return modelId;
43
- }
44
- }
45
- return '';
46
- }
47
- function getFirstProviderModelRef(providers) {
48
- for (const provider of providers) {
49
- const providerId = normalizeOpencodeProviderId(provider.name);
50
- const modelId = getProviderDefaultModelId(provider);
51
- if (providerId && modelId) {
52
- return `${providerId}/${modelId}`;
53
- }
54
- }
55
- return '';
56
- }
57
- function getProviderDefaultModelId(provider) {
58
- const directModel = String(provider.model || '').trim();
59
- if (directModel) {
60
- return directModel;
61
- }
62
- const firstModel = Array.isArray(provider.models)
63
- ? provider.models.find((entry) => String(entry?.model || '').trim())
64
- : null;
65
- return String(firstModel?.model || '').trim();
66
- }
67
- function buildOpencodeInlineConfig(model, providers) {
68
- const config = {
69
- $schema: 'https://opencode.ai/config.json',
70
- };
71
- const env = {};
72
- if (model) {
73
- config.model = model;
74
- }
75
- const providerConfig = {};
76
- for (const provider of providers) {
77
- const providerId = normalizeOpencodeProviderId(provider.name);
78
- if (!providerId) {
79
- continue;
80
- }
81
- const entry = {
82
- name: String(provider.name || providerId),
83
- };
84
- if (shouldUseOpenAiCompatibleProvider(providerId)) {
85
- entry.npm = '@ai-sdk/openai-compatible';
86
- }
87
- const options = {};
88
- const baseUrl = String(provider.base_url || '').trim();
89
- if (baseUrl) {
90
- options.baseURL = baseUrl;
91
- }
92
- const apiKey = String(provider.api_key || '').trim();
93
- if (apiKey) {
94
- const envName = opencodeProviderApiKeyEnvName(providerId);
95
- env[envName] = apiKey;
96
- options.apiKey = `{env:${envName}}`;
97
- }
98
- if (Object.keys(options).length > 0) {
99
- entry.options = options;
100
- }
101
- const models = buildOpencodeProviderModels(provider);
102
- if (Object.keys(models).length > 0) {
103
- entry.models = models;
104
- }
105
- providerConfig[providerId] = entry;
106
- }
107
- if (Object.keys(providerConfig).length > 0) {
108
- config.provider = providerConfig;
109
- }
110
- return {
111
- config,
112
- env,
113
- };
114
- }
115
- function buildOpencodeProviderModels(provider) {
116
- const models = {};
117
- const addModel = (model, alias) => {
118
- const modelId = String(model || '').trim();
119
- if (!modelId || models[modelId]) {
120
- return;
121
- }
122
- models[modelId] = {
123
- name: String(alias || modelId).trim() || modelId,
124
- };
125
- };
126
- addModel(provider.model);
127
- for (const model of Array.isArray(provider.models) ? provider.models : []) {
128
- addModel(model?.model, model?.alias);
129
- }
130
- return models;
131
- }
132
- function collectProviderEnv(providers) {
133
- const env = {};
134
- for (const provider of providers) {
135
- if (!provider.env || typeof provider.env !== 'object') {
136
- continue;
137
- }
138
- for (const [key, value] of Object.entries(provider.env)) {
139
- const envKey = key.trim();
140
- if (envKey) {
141
- env[envKey] = String(value ?? '');
142
- }
143
- }
144
- }
145
- return env;
146
- }
147
- function collectPiProviderEnv(providers) {
148
- const env = {};
149
- for (const provider of providers) {
150
- const apiKey = String(provider.api_key || '').trim();
151
- const envName = piProviderApiKeyEnvName(provider.name);
152
- if (apiKey && envName) {
153
- env[envName] = apiKey;
154
- }
155
- }
156
- return env;
157
- }
158
- function resolvePiProviderModel(providers, model) {
159
- const [explicitProvider, explicitModel] = splitProviderModelRef(model);
160
- if (explicitProvider && explicitModel) {
161
- return {
162
- providerId: normalizePiProviderId(explicitProvider),
163
- modelId: explicitModel,
164
- };
165
- }
166
- for (const provider of providers) {
167
- const providerId = normalizePiProviderId(provider.name);
168
- const modelId = getProviderDefaultModelId(provider);
169
- if (providerId && modelId && (!model || model === modelId)) {
170
- return { providerId, modelId };
171
- }
172
- }
173
- const fallbackProvider = providers.find((provider) => normalizePiProviderId(provider.name));
174
- return {
175
- providerId: normalizePiProviderId(fallbackProvider?.name),
176
- modelId: model,
177
- };
178
- }
179
- function splitProviderModelRef(value) {
180
- const trimmed = value.trim();
181
- const slashIndex = trimmed.indexOf('/');
182
- if (slashIndex <= 0 || slashIndex >= trimmed.length - 1) {
183
- return ['', trimmed];
184
- }
185
- return [trimmed.slice(0, slashIndex), trimmed.slice(slashIndex + 1)];
186
- }
187
- function normalizePiProviderId(providerName) {
188
- const providerId = normalizeProviderId(providerName);
189
- const aliases = {
190
- google: 'google',
191
- gemini: 'google',
192
- kimi: 'kimi-coding',
193
- moonshot: 'moonshotai',
194
- zhipuai: 'zai',
195
- };
196
- return aliases[providerId] || providerId;
197
- }
198
- function piProviderAgentDir(configState, projectName) {
199
- const configDir = (0, node_path_1.dirname)(configState.path);
200
- const safeProjectName = String(projectName || 'workspace')
201
- .trim()
202
- .replace(/[^a-zA-Z0-9._-]+/g, '-')
203
- .replace(/^-+|-+$/g, '') || 'workspace';
204
- return (0, node_path_1.resolve)(configDir, '.pi-agent', safeProjectName);
205
- }
206
- function writeJsonFile(path, value, mode = 0o600) {
207
- (0, node_fs_1.writeFileSync)(path, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf8', mode });
208
- (0, node_fs_1.chmodSync)(path, mode);
209
- }
210
- function writePiProviderRuntimeConfig(configState, project, providers, model) {
211
- if (providers.length === 0) {
212
- return {};
213
- }
214
- const { providerId, modelId } = resolvePiProviderModel(providers, model);
215
- const agentDir = piProviderAgentDir(configState, project.name);
216
- (0, node_fs_1.mkdirSync)(agentDir, { recursive: true, mode: 0o700 });
217
- (0, node_fs_1.chmodSync)(agentDir, 0o700);
218
- const auth = {};
219
- const modelProviders = {};
220
- for (const provider of providers) {
221
- const id = normalizePiProviderId(provider.name);
222
- if (!id) {
223
- continue;
224
- }
225
- const apiKey = String(provider.api_key || '').trim();
226
- const baseUrl = String(provider.base_url || '').trim();
227
- if (apiKey) {
228
- auth[id] = { type: 'api_key', key: apiKey };
229
- }
230
- if (baseUrl || apiKey) {
231
- modelProviders[id] = {
232
- name: String(provider.name || id).trim() || id,
233
- ...(baseUrl ? { baseUrl } : {}),
234
- ...(apiKey ? { apiKey } : {}),
235
- };
236
- }
237
- }
238
- writeJsonFile((0, node_path_1.resolve)(agentDir, 'auth.json'), auth);
239
- writeJsonFile((0, node_path_1.resolve)(agentDir, 'models.json'), { providers: modelProviders });
240
- writeJsonFile((0, node_path_1.resolve)(agentDir, 'settings.json'), {
241
- ...(providerId ? { defaultProvider: providerId } : {}),
242
- ...(modelId ? { defaultModel: modelId } : {}),
243
- quietStartup: true,
244
- }, 0o644);
245
- return {
246
- PI_CODING_AGENT_DIR: agentDir,
247
- };
248
- }
249
- function normalizeOpencodeProviderId(value) {
250
- return String(value || '')
251
- .trim()
252
- .toLowerCase()
253
- .replace(/[^a-z0-9._-]+/g, '-')
254
- .replace(/^-+|-+$/g, '');
255
- }
256
- function normalizeProviderId(value) {
257
- return String(value || '')
258
- .trim()
259
- .toLowerCase()
260
- .replace(/[^a-z0-9]+/g, '-')
261
- .replace(/^-+|-+$/g, '');
262
- }
263
- function piProviderApiKeyEnvName(providerName) {
264
- const providerId = normalizeProviderId(providerName);
265
- const envNames = {
266
- anthropic: 'ANTHROPIC_API_KEY',
267
- 'azure-openai': 'AZURE_OPENAI_API_KEY',
268
- 'azure-openai-responses': 'AZURE_OPENAI_API_KEY',
269
- cerebras: 'CEREBRAS_API_KEY',
270
- cloudflare: 'CLOUDFLARE_API_KEY',
271
- 'cloudflare-ai-gateway': 'CLOUDFLARE_API_KEY',
272
- 'cloudflare-workers-ai': 'CLOUDFLARE_API_KEY',
273
- deepseek: 'DEEPSEEK_API_KEY',
274
- fireworks: 'FIREWORKS_API_KEY',
275
- gemini: 'GEMINI_API_KEY',
276
- google: 'GEMINI_API_KEY',
277
- groq: 'GROQ_API_KEY',
278
- huggingface: 'HF_TOKEN',
279
- kimi: 'KIMI_API_KEY',
280
- 'kimi-coding': 'KIMI_API_KEY',
281
- minimax: 'MINIMAX_API_KEY',
282
- 'minimax-cn': 'MINIMAX_CN_API_KEY',
283
- mistral: 'MISTRAL_API_KEY',
284
- moonshot: 'KIMI_API_KEY',
285
- openai: 'OPENAI_API_KEY',
286
- opencode: 'OPENCODE_API_KEY',
287
- 'opencode-go': 'OPENCODE_API_KEY',
288
- openrouter: 'OPENROUTER_API_KEY',
289
- siliconflow: 'SILICONFLOW_API_KEY',
290
- vercel: 'AI_GATEWAY_API_KEY',
291
- 'vercel-ai-gateway': 'AI_GATEWAY_API_KEY',
292
- xai: 'XAI_API_KEY',
293
- zai: 'ZAI_API_KEY',
294
- zhipuai: 'ZAI_API_KEY',
295
- };
296
- return envNames[providerId] || '';
297
- }
298
- function opencodeProviderApiKeyEnvName(providerId) {
299
- const suffix = providerId.toUpperCase().replace(/[^A-Z0-9]+/g, '_').replace(/^_+|_+$/g, '');
300
- return `AI_WORKSTATION_OPENCODE_${suffix || 'PROVIDER'}_API_KEY`;
301
- }
302
- function shouldUseOpenAiCompatibleProvider(providerId) {
303
- const builtInNonCompatibleProviders = new Set([
304
- 'anthropic',
305
- 'google',
306
- 'gemini',
307
- ]);
308
- return !builtInNonCompatibleProviders.has(providerId);
309
- }
310
- function resolveBundledAcpCommand(packageName, binName) {
311
- const require = (0, node_module_1.createRequire)(__filename);
312
- const packageJsonPath = resolveBundledPackageJsonPath(packageName);
313
- const packageJson = require(packageJsonPath);
314
- const binField = packageJson.bin;
315
- const relativeBinPath = typeof binField === 'string'
316
- ? binField
317
- : binField?.[binName];
318
- if (!relativeBinPath) {
319
- throw new Error(`Bundled package "${packageName}" does not declare the ${binName} bin.`);
320
- }
321
- return {
322
- command: process.execPath,
323
- args: [(0, node_path_1.resolve)((0, node_path_1.dirname)(packageJsonPath), relativeBinPath)],
324
- };
325
- }
326
- function resolveBundledPackageJsonPath(packageName) {
327
- const require = (0, node_module_1.createRequire)(__filename);
328
- try {
329
- return require.resolve(`${packageName}/package.json`);
330
- }
331
- catch (error) {
332
- if (error?.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
333
- throw error;
334
- }
335
- }
336
- for (const basePath of require.resolve.paths(packageName) || []) {
337
- const packageJsonPath = (0, node_path_1.resolve)(basePath, ...packageName.split('/'), 'package.json');
338
- if ((0, node_fs_1.existsSync)(packageJsonPath)) {
339
- return packageJsonPath;
340
- }
341
- }
342
- let current = (0, node_path_1.dirname)(require.resolve(packageName));
343
- while (current && current !== (0, node_path_1.dirname)(current)) {
344
- const packageJsonPath = (0, node_path_1.resolve)(current, 'package.json');
345
- if ((0, node_fs_1.existsSync)(packageJsonPath)) {
346
- return packageJsonPath;
347
- }
348
- current = (0, node_path_1.dirname)(current);
349
- }
350
- throw new Error(`Bundled package "${packageName}" package.json could not be resolved.`);
351
- }
352
- function resolveBundledCodexCommand() {
353
- return resolveBundledAcpCommand(desktop_js_1.DESKTOP_CODEX_ACP_PACKAGE, 'codex-acp');
354
- }
355
- function resolveBundledClaudeCodeCommand() {
356
- return resolveBundledAcpCommand(desktop_js_1.DESKTOP_CLAUDECODE_ACP_PACKAGE, 'claude-agent-acp');
357
- }
358
- function resolveBundledPiAcpCommand() {
359
- return resolveBundledAcpCommand(desktop_js_1.DESKTOP_PI_ACP_PACKAGE, 'pi-acp');
360
- }
361
- function resolveBundledPiCommand() {
362
- return resolveBundledAcpCommand(desktop_js_1.DESKTOP_PI_CODING_AGENT_PACKAGE, 'pi').args[0];
25
+ return definition?.resolveModel?.({
26
+ project,
27
+ providers,
28
+ rawModel,
29
+ normalizedModel,
30
+ }) || normalizedModel;
363
31
  }
364
32
  function toLocalCoreProjectConfig(configState, project) {
365
33
  const rawWorkDir = String(project.agent?.options?.work_dir || '.').trim() || '.';
@@ -377,63 +45,22 @@ function toLocalCoreProjectConfig(configState, project) {
377
45
  : {};
378
46
  const agentType = String(project.agent?.type || '').trim().toLowerCase();
379
47
  const providers = Array.isArray(project.agent?.providers) ? project.agent.providers : [];
380
- const model = resolveAgentModel(project, providers);
381
- const providerEnv = collectProviderEnv(providers);
382
- const piProviderEnv = agentType === 'pi'
383
- ? collectPiProviderEnv(providers)
384
- : {};
385
- const opencodeInlineConfig = agentType === 'opencode'
386
- ? buildOpencodeInlineConfig(model, providers)
387
- : null;
388
- const inferredOpencodeEnv = agentType === 'opencode'
389
- ? {
390
- ...(opencodeInlineConfig?.env || {}),
391
- OPENCODE_CONFIG_CONTENT: JSON.stringify(opencodeInlineConfig?.config || { $schema: 'https://opencode.ai/config.json' }),
392
- }
393
- : {};
394
- const inferredClaudeCodeEnv = agentType === 'claudecode' && model
395
- ? {
396
- ANTHROPIC_MODEL: model,
397
- }
398
- : {};
399
- const bundledPiAcp = agentType === 'pi'
400
- ? resolveBundledPiAcpCommand()
401
- : null;
402
- const bundledPiCommand = agentType === 'pi'
403
- ? resolveBundledPiCommand()
404
- : '';
405
- const piProviderRuntimeEnv = agentType === 'pi'
406
- ? writePiProviderRuntimeConfig(configState, project, providers, model)
407
- : {};
408
- const inferredPiEnv = agentType === 'pi'
409
- ? {
410
- ...piProviderEnv,
411
- ...piProviderRuntimeEnv,
412
- PI_ACP_PI_COMMAND: bundledPiCommand,
413
- }
414
- : {};
415
- const bundledCodex = agentType === 'codex'
416
- ? resolveBundledCodexCommand()
417
- : null;
418
- const bundledClaudeCode = agentType === 'claudecode'
419
- ? resolveBundledClaudeCodeCommand()
420
- : null;
421
- const inferredCommand = agentType === 'opencode'
422
- ? 'opencode'
423
- : bundledPiAcp?.command || bundledCodex?.command || bundledClaudeCode?.command || '';
48
+ const definition = (0, index_js_1.resolveAgentRuntimeDefinition)(agentType);
49
+ const model = resolveAgentModel(project, providers, definition);
50
+ const providerEnv = (0, launch_utils_js_1.collectProviderEnv)(providers);
51
+ const launchDefaults = definition?.buildLaunchConfig?.({
52
+ configState,
53
+ project,
54
+ agentType,
55
+ providers,
56
+ model,
57
+ }) || {};
58
+ const inferredCommand = launchDefaults.command || '';
424
59
  const command = String(project.agent?.options?.command || inferredCommand).trim();
425
60
  if (!command) {
426
61
  throw new Error(`Workspace "${project.name}" requires [projects.agent.options].command for Local AI Core ACP execution.`);
427
62
  }
428
- const defaultArgs = agentType === 'opencode'
429
- ? ['acp']
430
- : agentType === 'pi'
431
- ? [...(bundledPiAcp?.args || [])]
432
- : agentType === 'codex'
433
- ? [...(bundledCodex?.args || [])]
434
- : agentType === 'claudecode'
435
- ? [...(bundledClaudeCode?.args || [])]
436
- : [];
63
+ const defaultArgs = launchDefaults.args || [];
437
64
  return {
438
65
  workspaceId: project.name,
439
66
  agentType,
@@ -441,9 +68,7 @@ function toLocalCoreProjectConfig(configState, project) {
441
68
  command,
442
69
  args: args.length > 0 ? args : defaultArgs,
443
70
  env: {
444
- ...inferredOpencodeEnv,
445
- ...inferredClaudeCodeEnv,
446
- ...inferredPiEnv,
71
+ ...(launchDefaults.env || {}),
447
72
  ...providerEnv,
448
73
  ...env,
449
74
  },