@kafca/agentdock 0.1.43 → 0.1.45

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 (119) hide show
  1. package/README.md +77 -11
  2. package/bin/agentdock.mjs +5 -5
  3. package/dist/renderer/assets/{Badge-CbG6yRSm.js → Badge-BIojwD6s.js} +1 -1
  4. package/dist/renderer/assets/{Chat-BvNNWGGX.js → Chat-wjBR3XEX.js} +1 -1
  5. package/dist/renderer/assets/{ChatMarkdown-Ct-PvJB8.js → ChatMarkdown-DqszsPB_.js} +1 -1
  6. package/dist/renderer/assets/Config-BDCHs5A2.js +21 -0
  7. package/dist/renderer/assets/{CronList-Dj_3muVG.js → CronList-CEWQYTov.js} +1 -1
  8. package/dist/renderer/assets/Dashboard-DrWftfk3.js +26 -0
  9. package/dist/renderer/assets/{EmptyState-Bn2Qh14U.js → EmptyState-BqCx1oWr.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeDetail-Bsz6Ou41.js → KnowledgeDetail-BwK8Gpfa.js} +2 -2
  11. package/dist/renderer/assets/{KnowledgeHome-Cgj4XFXn.js → KnowledgeHome-hhDTZMDO.js} +3 -3
  12. package/dist/renderer/assets/{Logs-Dp-NF6GN.js → Logs-C9xPEhFT.js} +1 -1
  13. package/dist/renderer/assets/{Modal-B6YPPBN6.js → Modal-D2U4r2V0.js} +1 -1
  14. package/dist/renderer/assets/{MonitorList-xEZWg460.js → MonitorList-CayKbfwJ.js} +1 -1
  15. package/dist/renderer/assets/{Page-Bn7RjGOS.js → Page-urf5GcT_.js} +1 -1
  16. package/dist/renderer/assets/ProjectDetail-B1GyAr7a.js +11 -0
  17. package/dist/renderer/assets/{ProjectList-BDk5_gqY.js → ProjectList-BoipQypE.js} +1 -1
  18. package/dist/renderer/assets/{Select-xshfMIEQ.js → Select-CAscWpy5.js} +1 -1
  19. package/dist/renderer/assets/{SessionChat-BkHy90z3.js → SessionChat-BAVy5221.js} +1 -1
  20. package/dist/renderer/assets/{SessionList-BZyXT92L.js → SessionList-BZpuMvh0.js} +1 -1
  21. package/dist/renderer/assets/{ThreadChat-DUOIyXrS.js → ThreadChat-JX7m9biG.js} +1 -1
  22. package/dist/renderer/assets/Workspace-CFW8otjU.js +14 -0
  23. package/dist/renderer/assets/{arrow-left-C54ZI-AS.js → arrow-left-7HrNuS-V.js} +1 -1
  24. package/dist/renderer/assets/{book-open-Dl7GO0zn.js → book-open-BDoAu82s.js} +1 -1
  25. package/dist/renderer/assets/{check-CiqgtrOL.js → check-DGlyq4xX.js} +1 -1
  26. package/dist/renderer/assets/{chevron-down-DTL2OuVh.js → chevron-down-Bb_3EHq9.js} +1 -1
  27. package/dist/renderer/assets/{circle-DaVKfa3P.js → circle-DIpqZnYw.js} +1 -1
  28. package/dist/renderer/assets/desktop-Ci1fnRDR.js +1 -0
  29. package/dist/renderer/assets/{desktop-C6q6wBae.js → desktop-Do_UrC-o.js} +5 -5
  30. package/dist/renderer/assets/en-CmAr_0e6.js +1 -0
  31. package/dist/renderer/assets/es-Cs9x52ca.js +1 -0
  32. package/dist/renderer/assets/{funnel-CrmnLMJI.js → funnel-Bbf0ERLP.js} +1 -1
  33. package/dist/renderer/assets/{heart-BMfQI7y_.js → heart-CGqU-qfw.js} +1 -1
  34. package/dist/renderer/assets/{index-nreiKY1f.js → index-Df-Trovt.js} +2 -2
  35. package/dist/renderer/assets/{index-HPNb1zfx.js → index-DwhTjLA1.js} +36 -36
  36. package/dist/renderer/assets/index-RaTga2BC.css +11 -0
  37. package/dist/renderer/assets/ja-DtvtBRTW.js +1 -0
  38. package/dist/renderer/assets/{pencil-wTQ4l465.js → pencil-CHiy1MvK.js} +1 -1
  39. package/dist/renderer/assets/{play-BK--MXmw.js → play-CGYnmC4Q.js} +1 -1
  40. package/dist/renderer/assets/{plug-BIx9fjip.js → plug-Mexu4gyV.js} +1 -1
  41. package/dist/renderer/assets/{plus-Dn7JFWQ8.js → plus-B_Q5-Oj7.js} +1 -1
  42. package/dist/renderer/assets/projects-C6bbkC-O.js +1 -0
  43. package/dist/renderer/assets/{save-CC3zOSWb.js → save-CJ_QFPw0.js} +1 -1
  44. package/dist/renderer/assets/{search-CDTy9Czu.js → search-D8Dkhsyq.js} +1 -1
  45. package/dist/renderer/assets/{server-DtQk3t2a.js → server-Cd96R7WL.js} +1 -1
  46. package/dist/renderer/assets/{session-utils-4ep5D66T.js → session-utils-BNUbQBfF.js} +1 -1
  47. package/dist/renderer/assets/{sessions-Dor1LteH.js → sessions-BACfV8s1.js} +1 -1
  48. package/dist/renderer/assets/{shield-check-Cz2LpU6r.js → shield-check-Cnn-yQUA.js} +1 -1
  49. package/dist/renderer/assets/{trash-2-C2EmWFZV.js → trash-2-oWCxwQ9D.js} +1 -1
  50. package/dist/renderer/assets/{user-I8B-cs5A.js → user-BzE9BwsY.js} +1 -1
  51. package/dist/renderer/assets/{wifi-off-CPevTQJn.js → wifi-off-DHxnNkdY.js} +1 -1
  52. package/dist/renderer/assets/zh-CcJ9vBZj.js +1 -0
  53. package/dist/renderer/assets/zh-TW-elI72AC1.js +1 -0
  54. package/dist/renderer/index.html +2 -2
  55. package/dist-electron/electron/main.js +26 -1
  56. package/dist-electron/packages/core-sdk/src/index.js +28 -0
  57. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +111 -62
  58. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +80 -7
  59. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-transport.js +78 -5
  60. package/dist-electron/services/local-ai-core/src/acp/store/external-store.js +98 -0
  61. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +33 -0
  62. package/dist-electron/services/local-ai-core/src/acp/store/model-provider-store.js +88 -0
  63. package/dist-electron/services/local-ai-core/src/acp/store/schema.js +43 -0
  64. package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +2 -119
  65. package/dist-electron/services/local-ai-core/src/agents/pi/provider-materializer.js +148 -0
  66. package/dist-electron/services/local-ai-core/src/channel/lark/config.js +2 -0
  67. package/dist-electron/services/local-ai-core/src/channel/lark/inbound.js +114 -0
  68. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +117 -75
  69. package/dist-electron/services/local-ai-core/src/channel/shared/session-command-runtime.js +4 -2
  70. package/dist-electron/services/local-ai-core/src/channel/shared/thread-routing.js +34 -0
  71. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +151 -47
  72. package/dist-electron/services/local-ai-core/src/execution/agent-execution-backend.js +56 -0
  73. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +18 -57
  74. package/dist-electron/services/local-ai-core/src/kernel/local-core-errors.js +255 -0
  75. package/dist-electron/services/local-ai-core/src/plugins/builtin/catalog.js +78 -0
  76. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +3 -1
  77. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +64 -9
  78. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +5 -2
  79. package/dist-electron/services/local-ai-core/src/runtime/config-migration.js +152 -0
  80. package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +175 -0
  81. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +330 -3
  82. package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +11 -2
  83. package/dist-electron/services/local-ai-core/src/runtime/provider-config-migration.js +32 -0
  84. package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +76 -8
  85. package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +62 -0
  86. package/dist-electron/services/local-ai-core/src/runtime/server.js +708 -4
  87. package/dist-electron/services/local-ai-core/src/runtime/standalone.js +13 -3
  88. package/dist-electron/services/local-ai-core/src/sandbox/opensandbox-client.js +113 -0
  89. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +273 -0
  90. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-manager.js +215 -0
  91. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-stdio-proxy.js +188 -0
  92. package/dist-electron/services/local-ai-core/src/thread/slash-command-registry.js +3 -0
  93. package/dist-electron/services/local-ai-core/src/thread/thread-command-service.js +32 -0
  94. package/dist-electron/services/local-ai-core/src/thread/thread-slash-command-dispatcher.js +71 -0
  95. package/dist-electron/shared/desktop.js +85 -1
  96. package/dist-electron/tests/contracts/architecture-docs.test.js +83 -0
  97. package/dist-electron/tests/electron/plugin-kernel.test.js +225 -18
  98. package/dist-electron/tests/electron/runtime-detection-service.test.js +57 -5
  99. package/dist-electron/tests/electron/sandbox-config.test.js +541 -0
  100. package/dist-electron/tests/electron/workspace-task-store.test.js +257 -0
  101. package/dist-electron/tests/integration/channel-gateways.test.js +32 -0
  102. package/dist-electron/tests/integration/lark-gateway.test.js +1977 -0
  103. package/dist-electron/tests/integration/local-core-acp-progress.test.js +1772 -0
  104. package/dist-electron/tests/integration/local-core-refactor.test.js +775 -5156
  105. package/dist-electron/tests/integration/local-core-routes.test.js +238 -0
  106. package/dist-electron/tests/integration/weixin-gateway.test.js +927 -0
  107. package/package.json +2 -3
  108. package/dist/renderer/assets/Config-lQX2qVVV.js +0 -16
  109. package/dist/renderer/assets/Dashboard-eh_RhGYb.js +0 -26
  110. package/dist/renderer/assets/ProjectDetail-Cv_jIE61.js +0 -11
  111. package/dist/renderer/assets/Workspace-Dl80fNEC.js +0 -14
  112. package/dist/renderer/assets/desktop-jaAiayNB.js +0 -1
  113. package/dist/renderer/assets/en-D2SkCrhG.js +0 -1
  114. package/dist/renderer/assets/es-C8UBPhxM.js +0 -1
  115. package/dist/renderer/assets/index-CaQZSRbg.css +0 -11
  116. package/dist/renderer/assets/ja-ChF4vbBL.js +0 -1
  117. package/dist/renderer/assets/projects-brJZgwEJ.js +0 -1
  118. package/dist/renderer/assets/zh-DIcdHycM.js +0 -1
  119. package/dist/renderer/assets/zh-TW-BtRwreY_.js +0 -1
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalExternalStore = void 0;
4
+ const utils_js_1 = require("./utils.js");
5
+ class LocalExternalStore {
6
+ db;
7
+ constructor(db) {
8
+ this.db = db;
9
+ }
10
+ getProject(userId, externalProjectId) {
11
+ const row = this.db.prepare(`
12
+ SELECT user_id, external_project_id, workspace_id, workspace_path, display_name, agent_type, provider_id, metadata_json, created_at, updated_at
13
+ FROM external_projects
14
+ WHERE user_id = ? AND external_project_id = ?
15
+ `).get(userId, externalProjectId);
16
+ return row ? this.toProject(row) : undefined;
17
+ }
18
+ upsertProject(input) {
19
+ const now = new Date().toISOString();
20
+ const existing = this.getProject(input.userId, input.externalProjectId);
21
+ this.db.prepare(`
22
+ INSERT INTO external_projects (
23
+ user_id, external_project_id, workspace_id, workspace_path, display_name, agent_type, provider_id,
24
+ metadata_json, created_at, updated_at
25
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
26
+ ON CONFLICT(user_id, external_project_id) DO UPDATE SET
27
+ workspace_id = excluded.workspace_id,
28
+ workspace_path = excluded.workspace_path,
29
+ display_name = excluded.display_name,
30
+ agent_type = excluded.agent_type,
31
+ provider_id = excluded.provider_id,
32
+ metadata_json = excluded.metadata_json,
33
+ updated_at = excluded.updated_at
34
+ `).run(input.userId, input.externalProjectId, input.workspaceId, input.workspacePath, input.displayName, input.agentType, input.providerId, JSON.stringify(input.metadata || existing?.metadata || {}), existing?.createdAt || input.createdAt || now, now);
35
+ return this.getProject(input.userId, input.externalProjectId);
36
+ }
37
+ getThread(userId, externalProjectId, externalThreadId) {
38
+ const row = this.db.prepare(`
39
+ SELECT user_id, external_project_id, external_thread_id, workspace_id, thread_id, workspace_path, metadata_json, created_at, updated_at
40
+ FROM external_threads
41
+ WHERE user_id = ? AND external_project_id = ? AND external_thread_id = ?
42
+ `).get(userId, externalProjectId, externalThreadId);
43
+ return row ? this.toThread(row) : undefined;
44
+ }
45
+ getThreadByThreadId(threadId) {
46
+ const row = this.db.prepare(`
47
+ SELECT user_id, external_project_id, external_thread_id, workspace_id, thread_id, workspace_path, metadata_json, created_at, updated_at
48
+ FROM external_threads
49
+ WHERE thread_id = ?
50
+ `).get(threadId);
51
+ return row ? this.toThread(row) : undefined;
52
+ }
53
+ upsertThread(input) {
54
+ const now = new Date().toISOString();
55
+ const existing = this.getThread(input.userId, input.externalProjectId, input.externalThreadId);
56
+ this.db.prepare(`
57
+ INSERT INTO external_threads (
58
+ user_id, external_project_id, external_thread_id, workspace_id, thread_id, workspace_path,
59
+ metadata_json, created_at, updated_at
60
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
61
+ ON CONFLICT(user_id, external_project_id, external_thread_id) DO UPDATE SET
62
+ workspace_id = excluded.workspace_id,
63
+ thread_id = excluded.thread_id,
64
+ workspace_path = excluded.workspace_path,
65
+ metadata_json = excluded.metadata_json,
66
+ updated_at = excluded.updated_at
67
+ `).run(input.userId, input.externalProjectId, input.externalThreadId, input.workspaceId, input.threadId, input.workspacePath, JSON.stringify(input.metadata || existing?.metadata || {}), existing?.createdAt || input.createdAt || now, now);
68
+ return this.getThread(input.userId, input.externalProjectId, input.externalThreadId);
69
+ }
70
+ toProject(row) {
71
+ return {
72
+ userId: row.user_id,
73
+ externalProjectId: row.external_project_id,
74
+ workspaceId: row.workspace_id,
75
+ workspacePath: row.workspace_path,
76
+ displayName: row.display_name,
77
+ agentType: row.agent_type,
78
+ providerId: row.provider_id,
79
+ createdAt: row.created_at,
80
+ updatedAt: row.updated_at,
81
+ metadata: (0, utils_js_1.parseJson)(row.metadata_json, {}),
82
+ };
83
+ }
84
+ toThread(row) {
85
+ return {
86
+ userId: row.user_id,
87
+ externalProjectId: row.external_project_id,
88
+ externalThreadId: row.external_thread_id,
89
+ workspaceId: row.workspace_id,
90
+ threadId: row.thread_id,
91
+ workspacePath: row.workspace_path,
92
+ createdAt: row.created_at,
93
+ updatedAt: row.updated_at,
94
+ metadata: (0, utils_js_1.parseJson)(row.metadata_json, {}),
95
+ };
96
+ }
97
+ }
98
+ exports.LocalExternalStore = LocalExternalStore;
@@ -13,6 +13,8 @@ const scheduler_store_js_1 = require("./scheduler-store.js");
13
13
  const security_store_js_1 = require("./security-store.js");
14
14
  const thread_store_js_1 = require("./thread-store.js");
15
15
  const workspace_registry_store_js_1 = require("./workspace-registry-store.js");
16
+ const model_provider_store_js_1 = require("./model-provider-store.js");
17
+ const external_store_js_1 = require("./external-store.js");
16
18
  class LocalCoreAcpStore {
17
19
  db;
18
20
  threads;
@@ -22,6 +24,8 @@ class LocalCoreAcpStore {
22
24
  scheduler;
23
25
  automationMonitors;
24
26
  platform;
27
+ modelProviders;
28
+ external;
25
29
  constructor(userDataPath) {
26
30
  const dbPath = (0, node_path_1.join)(userDataPath, 'runtime', 'local-core.db');
27
31
  (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(dbPath), { recursive: true });
@@ -37,6 +41,8 @@ class LocalCoreAcpStore {
37
41
  this.scheduler = new scheduler_store_js_1.LocalSchedulerStore(this.db);
38
42
  this.automationMonitors = new automation_monitor_store_js_1.LocalAutomationMonitorStore(this.db);
39
43
  this.platform = new platform_store_js_1.LocalPlatformStore(this.db);
44
+ this.modelProviders = new model_provider_store_js_1.LocalModelProviderStore(this.db);
45
+ this.external = new external_store_js_1.LocalExternalStore(this.db);
40
46
  (0, schema_js_1.ensureLocalCoreAcpSchema)(this.db);
41
47
  }
42
48
  close() {
@@ -95,6 +101,33 @@ class LocalCoreAcpStore {
95
101
  touchWorkspaceRegistryEntry(workspaceId) {
96
102
  this.workspaceRegistry.touch(workspaceId);
97
103
  }
104
+ listModelProviders() {
105
+ return this.modelProviders.list();
106
+ }
107
+ getModelProvider(providerId) {
108
+ return this.modelProviders.get(providerId);
109
+ }
110
+ upsertModelProvider(input) {
111
+ return this.modelProviders.upsert(input);
112
+ }
113
+ deleteModelProvider(providerId) {
114
+ return this.modelProviders.delete(providerId);
115
+ }
116
+ getExternalProject(userId, externalProjectId) {
117
+ return this.external.getProject(userId, externalProjectId);
118
+ }
119
+ upsertExternalProject(input) {
120
+ return this.external.upsertProject(input);
121
+ }
122
+ getExternalThread(userId, externalProjectId, externalThreadId) {
123
+ return this.external.getThread(userId, externalProjectId, externalThreadId);
124
+ }
125
+ getExternalThreadByThreadId(threadId) {
126
+ return this.external.getThreadByThreadId(threadId);
127
+ }
128
+ upsertExternalThread(input) {
129
+ return this.external.upsertThread(input);
130
+ }
98
131
  getWorkspaceSecuritySettings(workspaceId) {
99
132
  return this.security.getWorkspaceSecuritySettings(workspaceId);
100
133
  }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalModelProviderStore = void 0;
4
+ exports.slugifyProviderId = slugifyProviderId;
5
+ const utils_js_1 = require("./utils.js");
6
+ class LocalModelProviderStore {
7
+ db;
8
+ constructor(db) {
9
+ this.db = db;
10
+ }
11
+ list() {
12
+ const rows = this.db.prepare(`
13
+ SELECT id, name, api_key, base_url, model, models_json, thinking, env_json, created_at, updated_at
14
+ FROM model_providers
15
+ ORDER BY name ASC, id ASC
16
+ `).all();
17
+ return rows.map((row) => this.toProvider(row));
18
+ }
19
+ get(providerId) {
20
+ const row = this.db.prepare(`
21
+ SELECT id, name, api_key, base_url, model, models_json, thinking, env_json, created_at, updated_at
22
+ FROM model_providers
23
+ WHERE id = ?
24
+ `).get(providerId);
25
+ return row ? this.toProvider(row) : undefined;
26
+ }
27
+ upsert(input) {
28
+ const now = new Date().toISOString();
29
+ const requestedId = String(input.id || '').trim();
30
+ const id = requestedId || this.allocateProviderId(input.name);
31
+ const existing = this.get(id);
32
+ this.db.prepare(`
33
+ INSERT INTO model_providers (
34
+ id, name, api_key, base_url, model, models_json, thinking, env_json, created_at, updated_at
35
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
36
+ ON CONFLICT(id) DO UPDATE SET
37
+ name = excluded.name,
38
+ api_key = excluded.api_key,
39
+ base_url = excluded.base_url,
40
+ model = excluded.model,
41
+ models_json = excluded.models_json,
42
+ thinking = excluded.thinking,
43
+ env_json = excluded.env_json,
44
+ updated_at = excluded.updated_at
45
+ `).run(id, String(input.name || id).trim() || id, stringOrNull(input.api_key), stringOrNull(input.base_url), stringOrNull(input.model), JSON.stringify(Array.isArray(input.models) ? input.models : []), stringOrNull(input.thinking), JSON.stringify(input.env && typeof input.env === 'object' ? input.env : {}), existing?.createdAt || now, now);
46
+ return this.get(id);
47
+ }
48
+ delete(providerId) {
49
+ this.db.prepare('DELETE FROM model_providers WHERE id = ?').run(providerId);
50
+ return { deleted: true };
51
+ }
52
+ allocateProviderId(name) {
53
+ const base = slugifyProviderId(name, 'provider');
54
+ let candidate = base;
55
+ let index = 2;
56
+ while (this.get(candidate)) {
57
+ candidate = `${base}-${index}`;
58
+ index += 1;
59
+ }
60
+ return candidate;
61
+ }
62
+ toProvider(row) {
63
+ return {
64
+ id: row.id,
65
+ name: row.name,
66
+ api_key: row.api_key || undefined,
67
+ base_url: row.base_url || undefined,
68
+ model: row.model || undefined,
69
+ models: (0, utils_js_1.parseJson)(row.models_json, []),
70
+ thinking: row.thinking || undefined,
71
+ env: (0, utils_js_1.parseJson)(row.env_json, {}),
72
+ createdAt: row.created_at,
73
+ updatedAt: row.updated_at,
74
+ };
75
+ }
76
+ }
77
+ exports.LocalModelProviderStore = LocalModelProviderStore;
78
+ function slugifyProviderId(value, fallback) {
79
+ return String(value || '')
80
+ .trim()
81
+ .toLowerCase()
82
+ .replace(/[^a-z0-9._-]+/g, '-')
83
+ .replace(/^-+|-+$/g, '') || fallback;
84
+ }
85
+ function stringOrNull(value) {
86
+ const normalized = String(value || '').trim();
87
+ return normalized || null;
88
+ }
@@ -176,6 +176,49 @@ function ensureLocalCoreAcpSchema(db) {
176
176
  last_opened_at TEXT
177
177
  );
178
178
  CREATE INDEX IF NOT EXISTS idx_workspace_registry_updated ON workspace_registry (updated_at DESC);
179
+ CREATE TABLE IF NOT EXISTS model_providers (
180
+ id TEXT PRIMARY KEY,
181
+ name TEXT NOT NULL,
182
+ api_key TEXT,
183
+ base_url TEXT,
184
+ model TEXT,
185
+ models_json TEXT NOT NULL DEFAULT '[]',
186
+ thinking TEXT,
187
+ env_json TEXT NOT NULL DEFAULT '{}',
188
+ created_at TEXT NOT NULL,
189
+ updated_at TEXT NOT NULL
190
+ );
191
+ CREATE INDEX IF NOT EXISTS idx_model_providers_name ON model_providers (name);
192
+ CREATE TABLE IF NOT EXISTS external_projects (
193
+ user_id TEXT NOT NULL,
194
+ external_project_id TEXT NOT NULL,
195
+ workspace_id TEXT NOT NULL,
196
+ workspace_path TEXT NOT NULL,
197
+ display_name TEXT NOT NULL,
198
+ agent_type TEXT NOT NULL,
199
+ provider_id TEXT NOT NULL,
200
+ metadata_json TEXT NOT NULL DEFAULT '{}',
201
+ created_at TEXT NOT NULL,
202
+ updated_at TEXT NOT NULL,
203
+ PRIMARY KEY (user_id, external_project_id),
204
+ UNIQUE(workspace_id)
205
+ );
206
+ CREATE TABLE IF NOT EXISTS external_threads (
207
+ user_id TEXT NOT NULL,
208
+ external_project_id TEXT NOT NULL,
209
+ external_thread_id TEXT NOT NULL,
210
+ workspace_id TEXT NOT NULL,
211
+ thread_id TEXT NOT NULL,
212
+ workspace_path TEXT NOT NULL,
213
+ metadata_json TEXT NOT NULL DEFAULT '{}',
214
+ created_at TEXT NOT NULL,
215
+ updated_at TEXT NOT NULL,
216
+ PRIMARY KEY (user_id, external_project_id, external_thread_id),
217
+ UNIQUE(thread_id),
218
+ FOREIGN KEY (thread_id) REFERENCES threads(id) ON DELETE CASCADE
219
+ );
220
+ CREATE INDEX IF NOT EXISTS idx_external_threads_thread ON external_threads (thread_id);
221
+ CREATE INDEX IF NOT EXISTS idx_external_threads_workspace ON external_threads (workspace_id);
179
222
  CREATE TABLE IF NOT EXISTS agent_tasks (
180
223
  id TEXT PRIMARY KEY,
181
224
  workspace_id TEXT NOT NULL,
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolvePiModel = resolvePiModel;
4
4
  exports.buildPiLaunchConfig = buildPiLaunchConfig;
5
- const node_path_1 = require("node:path");
6
5
  const desktop_js_1 = require("../../../../../shared/desktop.js");
7
6
  const launch_utils_js_1 = require("../shared/launch-utils.js");
7
+ const provider_materializer_js_1 = require("./provider-materializer.js");
8
8
  function resolvePiModel(input) {
9
9
  return input.rawModel || (0, launch_utils_js_1.getFirstProviderModelId)(input.providers);
10
10
  }
@@ -15,125 +15,8 @@ function buildPiLaunchConfig(input) {
15
15
  command: bundledPiAcp.command,
16
16
  args: [...bundledPiAcp.args],
17
17
  env: {
18
- ...collectPiProviderEnv(input.providers),
19
- ...writePiProviderRuntimeConfig(input),
18
+ ...(0, provider_materializer_js_1.materializePiProviderConfig)(input),
20
19
  PI_ACP_PI_COMMAND: bundledPiCommand,
21
20
  },
22
21
  };
23
22
  }
24
- function collectPiProviderEnv(providers) {
25
- const env = {};
26
- for (const provider of providers) {
27
- const apiKey = String(provider.api_key || '').trim();
28
- const envName = piProviderApiKeyEnvName(provider.name);
29
- if (apiKey && envName) {
30
- env[envName] = apiKey;
31
- }
32
- }
33
- return env;
34
- }
35
- function writePiProviderRuntimeConfig(input) {
36
- if (input.providers.length === 0) {
37
- return {};
38
- }
39
- const { providerId, modelId } = resolvePiProviderModel(input.providers, input.model);
40
- const agentDir = (0, launch_utils_js_1.projectLocalStateDir)(input.configState, '.pi-agent', input.project.name);
41
- (0, launch_utils_js_1.ensurePrivateDir)(agentDir);
42
- const auth = {};
43
- const modelProviders = {};
44
- for (const provider of input.providers) {
45
- const id = normalizePiProviderId(provider.name);
46
- if (!id) {
47
- continue;
48
- }
49
- const apiKey = String(provider.api_key || '').trim();
50
- const baseUrl = String(provider.base_url || '').trim();
51
- if (apiKey) {
52
- auth[id] = { type: 'api_key', key: apiKey };
53
- }
54
- if (baseUrl || apiKey) {
55
- modelProviders[id] = {
56
- name: String(provider.name || id).trim() || id,
57
- ...(baseUrl ? { baseUrl } : {}),
58
- ...(apiKey ? { apiKey } : {}),
59
- };
60
- }
61
- }
62
- (0, launch_utils_js_1.writeJsonFile)((0, node_path_1.resolve)(agentDir, 'auth.json'), auth);
63
- (0, launch_utils_js_1.writeJsonFile)((0, node_path_1.resolve)(agentDir, 'models.json'), { providers: modelProviders });
64
- (0, launch_utils_js_1.writeJsonFile)((0, node_path_1.resolve)(agentDir, 'settings.json'), {
65
- ...(providerId ? { defaultProvider: providerId } : {}),
66
- ...(modelId ? { defaultModel: modelId } : {}),
67
- quietStartup: true,
68
- }, 0o644);
69
- return {
70
- PI_CODING_AGENT_DIR: agentDir,
71
- };
72
- }
73
- function resolvePiProviderModel(providers, model) {
74
- const [explicitProvider, explicitModel] = (0, launch_utils_js_1.splitProviderModelRef)(model);
75
- if (explicitProvider && explicitModel) {
76
- return {
77
- providerId: normalizePiProviderId(explicitProvider),
78
- modelId: explicitModel,
79
- };
80
- }
81
- for (const provider of providers) {
82
- const providerId = normalizePiProviderId(provider.name);
83
- const modelId = (0, launch_utils_js_1.getProviderDefaultModelId)(provider);
84
- if (providerId && modelId && (!model || model === modelId)) {
85
- return { providerId, modelId };
86
- }
87
- }
88
- const fallbackProvider = providers.find((provider) => normalizePiProviderId(provider.name));
89
- return {
90
- providerId: normalizePiProviderId(fallbackProvider?.name),
91
- modelId: model,
92
- };
93
- }
94
- function normalizePiProviderId(providerName) {
95
- const providerId = (0, launch_utils_js_1.normalizeProviderId)(providerName);
96
- const aliases = {
97
- google: 'google',
98
- gemini: 'google',
99
- kimi: 'kimi-coding',
100
- moonshot: 'moonshotai',
101
- zhipuai: 'zai',
102
- };
103
- return aliases[providerId] || providerId;
104
- }
105
- function piProviderApiKeyEnvName(providerName) {
106
- const providerId = (0, launch_utils_js_1.normalizeProviderId)(providerName);
107
- const envNames = {
108
- anthropic: 'ANTHROPIC_API_KEY',
109
- 'azure-openai': 'AZURE_OPENAI_API_KEY',
110
- 'azure-openai-responses': 'AZURE_OPENAI_API_KEY',
111
- cerebras: 'CEREBRAS_API_KEY',
112
- cloudflare: 'CLOUDFLARE_API_KEY',
113
- 'cloudflare-ai-gateway': 'CLOUDFLARE_API_KEY',
114
- 'cloudflare-workers-ai': 'CLOUDFLARE_API_KEY',
115
- deepseek: 'DEEPSEEK_API_KEY',
116
- fireworks: 'FIREWORKS_API_KEY',
117
- gemini: 'GEMINI_API_KEY',
118
- google: 'GEMINI_API_KEY',
119
- groq: 'GROQ_API_KEY',
120
- huggingface: 'HF_TOKEN',
121
- kimi: 'KIMI_API_KEY',
122
- 'kimi-coding': 'KIMI_API_KEY',
123
- minimax: 'MINIMAX_API_KEY',
124
- 'minimax-cn': 'MINIMAX_CN_API_KEY',
125
- mistral: 'MISTRAL_API_KEY',
126
- moonshot: 'KIMI_API_KEY',
127
- openai: 'OPENAI_API_KEY',
128
- opencode: 'OPENCODE_API_KEY',
129
- 'opencode-go': 'OPENCODE_API_KEY',
130
- openrouter: 'OPENROUTER_API_KEY',
131
- siliconflow: 'SILICONFLOW_API_KEY',
132
- vercel: 'AI_GATEWAY_API_KEY',
133
- 'vercel-ai-gateway': 'AI_GATEWAY_API_KEY',
134
- xai: 'XAI_API_KEY',
135
- zai: 'ZAI_API_KEY',
136
- zhipuai: 'ZAI_API_KEY',
137
- };
138
- return envNames[providerId] || '';
139
- }
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.materializePiProviderConfig = materializePiProviderConfig;
4
+ exports.collectPiProviderEnv = collectPiProviderEnv;
5
+ exports.writePiProviderRuntimeConfig = writePiProviderRuntimeConfig;
6
+ exports.resolvePiProviderModel = resolvePiProviderModel;
7
+ exports.normalizePiProviderIdFromConfig = normalizePiProviderIdFromConfig;
8
+ exports.normalizePiProviderId = normalizePiProviderId;
9
+ exports.piProviderApiKeyEnvName = piProviderApiKeyEnvName;
10
+ const node_path_1 = require("node:path");
11
+ const launch_utils_js_1 = require("../shared/launch-utils.js");
12
+ function materializePiProviderConfig(input) {
13
+ return {
14
+ ...collectPiProviderEnv(input.providers),
15
+ ...writePiProviderRuntimeConfig(input),
16
+ };
17
+ }
18
+ function collectPiProviderEnv(providers) {
19
+ const env = {};
20
+ for (const provider of providers) {
21
+ const apiKey = String(provider.api_key || '').trim();
22
+ const envName = piProviderApiKeyEnvName(normalizePiProviderIdFromConfig(provider));
23
+ if (apiKey && envName) {
24
+ env[envName] = apiKey;
25
+ }
26
+ }
27
+ return env;
28
+ }
29
+ function writePiProviderRuntimeConfig(input) {
30
+ if (input.providers.length === 0) {
31
+ return {};
32
+ }
33
+ const { providerId, modelId } = resolvePiProviderModel(input.providers, input.model);
34
+ const agentDir = (0, launch_utils_js_1.projectLocalStateDir)(input.configState, '.pi-agent', input.project.name);
35
+ (0, launch_utils_js_1.ensurePrivateDir)(agentDir);
36
+ const auth = {};
37
+ const modelProviders = {};
38
+ for (const provider of input.providers) {
39
+ const id = normalizePiProviderIdFromConfig(provider);
40
+ if (!id) {
41
+ continue;
42
+ }
43
+ const apiKey = String(provider.api_key || '').trim();
44
+ const baseUrl = String(provider.base_url || '').trim();
45
+ if (apiKey) {
46
+ auth[id] = { type: 'api_key', key: apiKey };
47
+ }
48
+ if (baseUrl || apiKey) {
49
+ modelProviders[id] = {
50
+ name: String(provider.name || id).trim() || id,
51
+ ...(baseUrl ? { baseUrl } : {}),
52
+ ...(apiKey ? { apiKey } : {}),
53
+ };
54
+ }
55
+ }
56
+ (0, launch_utils_js_1.writeJsonFile)((0, node_path_1.resolve)(agentDir, 'auth.json'), auth);
57
+ (0, launch_utils_js_1.writeJsonFile)((0, node_path_1.resolve)(agentDir, 'models.json'), { providers: modelProviders });
58
+ (0, launch_utils_js_1.writeJsonFile)((0, node_path_1.resolve)(agentDir, 'settings.json'), {
59
+ ...(providerId ? { defaultProvider: providerId } : {}),
60
+ ...(modelId ? { defaultModel: modelId } : {}),
61
+ quietStartup: true,
62
+ }, 0o644);
63
+ return {
64
+ PI_CODING_AGENT_DIR: agentDir,
65
+ };
66
+ }
67
+ function resolvePiProviderModel(providers, model) {
68
+ const [explicitProvider, explicitModel] = (0, launch_utils_js_1.splitProviderModelRef)(model);
69
+ if (explicitProvider && explicitModel) {
70
+ return {
71
+ providerId: normalizePiProviderId(explicitProvider),
72
+ modelId: explicitModel,
73
+ };
74
+ }
75
+ for (const provider of providers) {
76
+ const providerId = normalizePiProviderIdFromConfig(provider);
77
+ const modelId = (0, launch_utils_js_1.getProviderDefaultModelId)(provider);
78
+ if (providerId && modelId && (!model || model === modelId)) {
79
+ return { providerId, modelId };
80
+ }
81
+ }
82
+ const fallbackProvider = providers.find((provider) => normalizePiProviderId(provider.name));
83
+ return {
84
+ providerId: fallbackProvider ? normalizePiProviderIdFromConfig(fallbackProvider) : '',
85
+ modelId: model,
86
+ };
87
+ }
88
+ function normalizePiProviderIdFromConfig(provider) {
89
+ const providerId = normalizePiProviderId(provider.name);
90
+ if (providerId && piProviderApiKeyEnvName(providerId)) {
91
+ return providerId;
92
+ }
93
+ const providerName = (0, launch_utils_js_1.normalizeProviderId)(provider.name);
94
+ if (providerName.startsWith('deepseek-')) {
95
+ return 'deepseek';
96
+ }
97
+ const baseUrl = String(provider.base_url || '').toLowerCase();
98
+ if (baseUrl.includes('api.deepseek.com') || baseUrl.includes('deepseek.com')) {
99
+ return 'deepseek';
100
+ }
101
+ return providerId;
102
+ }
103
+ function normalizePiProviderId(providerName) {
104
+ const providerId = (0, launch_utils_js_1.normalizeProviderId)(providerName);
105
+ const aliases = {
106
+ google: 'google',
107
+ gemini: 'google',
108
+ kimi: 'kimi-coding',
109
+ moonshot: 'moonshotai',
110
+ zhipuai: 'zai',
111
+ };
112
+ return aliases[providerId] || providerId;
113
+ }
114
+ function piProviderApiKeyEnvName(providerName) {
115
+ const providerId = (0, launch_utils_js_1.normalizeProviderId)(providerName);
116
+ const envNames = {
117
+ anthropic: 'ANTHROPIC_API_KEY',
118
+ 'azure-openai': 'AZURE_OPENAI_API_KEY',
119
+ 'azure-openai-responses': 'AZURE_OPENAI_API_KEY',
120
+ cerebras: 'CEREBRAS_API_KEY',
121
+ cloudflare: 'CLOUDFLARE_API_KEY',
122
+ 'cloudflare-ai-gateway': 'CLOUDFLARE_API_KEY',
123
+ 'cloudflare-workers-ai': 'CLOUDFLARE_API_KEY',
124
+ deepseek: 'DEEPSEEK_API_KEY',
125
+ fireworks: 'FIREWORKS_API_KEY',
126
+ gemini: 'GEMINI_API_KEY',
127
+ google: 'GEMINI_API_KEY',
128
+ groq: 'GROQ_API_KEY',
129
+ huggingface: 'HF_TOKEN',
130
+ kimi: 'KIMI_API_KEY',
131
+ 'kimi-coding': 'KIMI_API_KEY',
132
+ minimax: 'MINIMAX_API_KEY',
133
+ 'minimax-cn': 'MINIMAX_CN_API_KEY',
134
+ mistral: 'MISTRAL_API_KEY',
135
+ moonshot: 'KIMI_API_KEY',
136
+ openai: 'OPENAI_API_KEY',
137
+ opencode: 'OPENCODE_API_KEY',
138
+ 'opencode-go': 'OPENCODE_API_KEY',
139
+ openrouter: 'OPENROUTER_API_KEY',
140
+ siliconflow: 'SILICONFLOW_API_KEY',
141
+ vercel: 'AI_GATEWAY_API_KEY',
142
+ 'vercel-ai-gateway': 'AI_GATEWAY_API_KEY',
143
+ xai: 'XAI_API_KEY',
144
+ zai: 'ZAI_API_KEY',
145
+ zhipuai: 'ZAI_API_KEY',
146
+ };
147
+ return envNames[providerId] || '';
148
+ }
@@ -45,6 +45,8 @@ function collectLarkWorkspaceBindings(config, options) {
45
45
  || platform.options.card_actions === true
46
46
  || platform.options.enable_card_actions === true
47
47
  || options.defaultCardActionsEnabled,
48
+ groupReplyAll: String(platform.options.group_reply_all || '').trim().toLowerCase() === 'true'
49
+ || platform.options.group_reply_all === true,
48
50
  brand: String(platform.options.brand || platform.options.lark_brand || '').trim().toLowerCase() === 'lark' ? 'lark' : 'feishu',
49
51
  enabled: Boolean(String(platform.options.app_id || '').trim() && String(platform.options.app_secret || '').trim()),
50
52
  project,