@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.
- package/README.md +77 -11
- package/bin/agentdock.mjs +5 -5
- package/dist/renderer/assets/{Badge-CbG6yRSm.js → Badge-BIojwD6s.js} +1 -1
- package/dist/renderer/assets/{Chat-BvNNWGGX.js → Chat-wjBR3XEX.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-Ct-PvJB8.js → ChatMarkdown-DqszsPB_.js} +1 -1
- package/dist/renderer/assets/Config-BDCHs5A2.js +21 -0
- package/dist/renderer/assets/{CronList-Dj_3muVG.js → CronList-CEWQYTov.js} +1 -1
- package/dist/renderer/assets/Dashboard-DrWftfk3.js +26 -0
- package/dist/renderer/assets/{EmptyState-Bn2Qh14U.js → EmptyState-BqCx1oWr.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-Bsz6Ou41.js → KnowledgeDetail-BwK8Gpfa.js} +2 -2
- package/dist/renderer/assets/{KnowledgeHome-Cgj4XFXn.js → KnowledgeHome-hhDTZMDO.js} +3 -3
- package/dist/renderer/assets/{Logs-Dp-NF6GN.js → Logs-C9xPEhFT.js} +1 -1
- package/dist/renderer/assets/{Modal-B6YPPBN6.js → Modal-D2U4r2V0.js} +1 -1
- package/dist/renderer/assets/{MonitorList-xEZWg460.js → MonitorList-CayKbfwJ.js} +1 -1
- package/dist/renderer/assets/{Page-Bn7RjGOS.js → Page-urf5GcT_.js} +1 -1
- package/dist/renderer/assets/ProjectDetail-B1GyAr7a.js +11 -0
- package/dist/renderer/assets/{ProjectList-BDk5_gqY.js → ProjectList-BoipQypE.js} +1 -1
- package/dist/renderer/assets/{Select-xshfMIEQ.js → Select-CAscWpy5.js} +1 -1
- package/dist/renderer/assets/{SessionChat-BkHy90z3.js → SessionChat-BAVy5221.js} +1 -1
- package/dist/renderer/assets/{SessionList-BZyXT92L.js → SessionList-BZpuMvh0.js} +1 -1
- package/dist/renderer/assets/{ThreadChat-DUOIyXrS.js → ThreadChat-JX7m9biG.js} +1 -1
- package/dist/renderer/assets/Workspace-CFW8otjU.js +14 -0
- package/dist/renderer/assets/{arrow-left-C54ZI-AS.js → arrow-left-7HrNuS-V.js} +1 -1
- package/dist/renderer/assets/{book-open-Dl7GO0zn.js → book-open-BDoAu82s.js} +1 -1
- package/dist/renderer/assets/{check-CiqgtrOL.js → check-DGlyq4xX.js} +1 -1
- package/dist/renderer/assets/{chevron-down-DTL2OuVh.js → chevron-down-Bb_3EHq9.js} +1 -1
- package/dist/renderer/assets/{circle-DaVKfa3P.js → circle-DIpqZnYw.js} +1 -1
- package/dist/renderer/assets/desktop-Ci1fnRDR.js +1 -0
- package/dist/renderer/assets/{desktop-C6q6wBae.js → desktop-Do_UrC-o.js} +5 -5
- package/dist/renderer/assets/en-CmAr_0e6.js +1 -0
- package/dist/renderer/assets/es-Cs9x52ca.js +1 -0
- package/dist/renderer/assets/{funnel-CrmnLMJI.js → funnel-Bbf0ERLP.js} +1 -1
- package/dist/renderer/assets/{heart-BMfQI7y_.js → heart-CGqU-qfw.js} +1 -1
- package/dist/renderer/assets/{index-nreiKY1f.js → index-Df-Trovt.js} +2 -2
- package/dist/renderer/assets/{index-HPNb1zfx.js → index-DwhTjLA1.js} +36 -36
- package/dist/renderer/assets/index-RaTga2BC.css +11 -0
- package/dist/renderer/assets/ja-DtvtBRTW.js +1 -0
- package/dist/renderer/assets/{pencil-wTQ4l465.js → pencil-CHiy1MvK.js} +1 -1
- package/dist/renderer/assets/{play-BK--MXmw.js → play-CGYnmC4Q.js} +1 -1
- package/dist/renderer/assets/{plug-BIx9fjip.js → plug-Mexu4gyV.js} +1 -1
- package/dist/renderer/assets/{plus-Dn7JFWQ8.js → plus-B_Q5-Oj7.js} +1 -1
- package/dist/renderer/assets/projects-C6bbkC-O.js +1 -0
- package/dist/renderer/assets/{save-CC3zOSWb.js → save-CJ_QFPw0.js} +1 -1
- package/dist/renderer/assets/{search-CDTy9Czu.js → search-D8Dkhsyq.js} +1 -1
- package/dist/renderer/assets/{server-DtQk3t2a.js → server-Cd96R7WL.js} +1 -1
- package/dist/renderer/assets/{session-utils-4ep5D66T.js → session-utils-BNUbQBfF.js} +1 -1
- package/dist/renderer/assets/{sessions-Dor1LteH.js → sessions-BACfV8s1.js} +1 -1
- package/dist/renderer/assets/{shield-check-Cz2LpU6r.js → shield-check-Cnn-yQUA.js} +1 -1
- package/dist/renderer/assets/{trash-2-C2EmWFZV.js → trash-2-oWCxwQ9D.js} +1 -1
- package/dist/renderer/assets/{user-I8B-cs5A.js → user-BzE9BwsY.js} +1 -1
- package/dist/renderer/assets/{wifi-off-CPevTQJn.js → wifi-off-DHxnNkdY.js} +1 -1
- package/dist/renderer/assets/zh-CcJ9vBZj.js +1 -0
- package/dist/renderer/assets/zh-TW-elI72AC1.js +1 -0
- package/dist/renderer/index.html +2 -2
- package/dist-electron/electron/main.js +26 -1
- package/dist-electron/packages/core-sdk/src/index.js +28 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +111 -62
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +80 -7
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-transport.js +78 -5
- package/dist-electron/services/local-ai-core/src/acp/store/external-store.js +98 -0
- package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +33 -0
- package/dist-electron/services/local-ai-core/src/acp/store/model-provider-store.js +88 -0
- package/dist-electron/services/local-ai-core/src/acp/store/schema.js +43 -0
- package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +2 -119
- package/dist-electron/services/local-ai-core/src/agents/pi/provider-materializer.js +148 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/config.js +2 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/inbound.js +114 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +117 -75
- package/dist-electron/services/local-ai-core/src/channel/shared/session-command-runtime.js +4 -2
- package/dist-electron/services/local-ai-core/src/channel/shared/thread-routing.js +34 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +151 -47
- package/dist-electron/services/local-ai-core/src/execution/agent-execution-backend.js +56 -0
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +18 -57
- package/dist-electron/services/local-ai-core/src/kernel/local-core-errors.js +255 -0
- package/dist-electron/services/local-ai-core/src/plugins/builtin/catalog.js +78 -0
- package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +3 -1
- package/dist-electron/services/local-ai-core/src/router/workspace-router.js +64 -9
- package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +5 -2
- package/dist-electron/services/local-ai-core/src/runtime/config-migration.js +152 -0
- package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +175 -0
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +330 -3
- package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +11 -2
- package/dist-electron/services/local-ai-core/src/runtime/provider-config-migration.js +32 -0
- package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +76 -8
- package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +62 -0
- package/dist-electron/services/local-ai-core/src/runtime/server.js +708 -4
- package/dist-electron/services/local-ai-core/src/runtime/standalone.js +13 -3
- package/dist-electron/services/local-ai-core/src/sandbox/opensandbox-client.js +113 -0
- package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +273 -0
- package/dist-electron/services/local-ai-core/src/sandbox/sandbox-manager.js +215 -0
- package/dist-electron/services/local-ai-core/src/sandbox/sandbox-stdio-proxy.js +188 -0
- package/dist-electron/services/local-ai-core/src/thread/slash-command-registry.js +3 -0
- package/dist-electron/services/local-ai-core/src/thread/thread-command-service.js +32 -0
- package/dist-electron/services/local-ai-core/src/thread/thread-slash-command-dispatcher.js +71 -0
- package/dist-electron/shared/desktop.js +85 -1
- package/dist-electron/tests/contracts/architecture-docs.test.js +83 -0
- package/dist-electron/tests/electron/plugin-kernel.test.js +225 -18
- package/dist-electron/tests/electron/runtime-detection-service.test.js +57 -5
- package/dist-electron/tests/electron/sandbox-config.test.js +541 -0
- package/dist-electron/tests/electron/workspace-task-store.test.js +257 -0
- package/dist-electron/tests/integration/channel-gateways.test.js +32 -0
- package/dist-electron/tests/integration/lark-gateway.test.js +1977 -0
- package/dist-electron/tests/integration/local-core-acp-progress.test.js +1772 -0
- package/dist-electron/tests/integration/local-core-refactor.test.js +775 -5156
- package/dist-electron/tests/integration/local-core-routes.test.js +238 -0
- package/dist-electron/tests/integration/weixin-gateway.test.js +927 -0
- package/package.json +2 -3
- package/dist/renderer/assets/Config-lQX2qVVV.js +0 -16
- package/dist/renderer/assets/Dashboard-eh_RhGYb.js +0 -26
- package/dist/renderer/assets/ProjectDetail-Cv_jIE61.js +0 -11
- package/dist/renderer/assets/Workspace-Dl80fNEC.js +0 -14
- package/dist/renderer/assets/desktop-jaAiayNB.js +0 -1
- package/dist/renderer/assets/en-D2SkCrhG.js +0 -1
- package/dist/renderer/assets/es-C8UBPhxM.js +0 -1
- package/dist/renderer/assets/index-CaQZSRbg.css +0 -11
- package/dist/renderer/assets/ja-ChF4vbBL.js +0 -1
- package/dist/renderer/assets/projects-brJZgwEJ.js +0 -1
- package/dist/renderer/assets/zh-DIcdHycM.js +0 -1
- 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
|
-
...
|
|
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,
|