@kafca/agentdock 0.1.44 → 0.1.46
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 +76 -11
- package/bin/agentdock.mjs +5 -5
- package/dist/renderer/assets/{Badge-Qk9qHovH.js → Badge-BIesaDYG.js} +1 -1
- package/dist/renderer/assets/Chat-CpataoDh.js +2 -0
- package/dist/renderer/assets/{ChatMarkdown-BKdW8OON.js → ChatMarkdown-_Mdmltgv.js} +1 -1
- package/dist/renderer/assets/Config-Pe5-zKZk.js +21 -0
- package/dist/renderer/assets/CronList-BnaOSPT8.js +1 -0
- package/dist/renderer/assets/Dashboard-D05l8GKE.js +26 -0
- package/dist/renderer/assets/{EmptyState-kD9yAwtw.js → EmptyState-BDBavDll.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-BAMCLrjz.js → KnowledgeDetail-DvR798l_.js} +2 -2
- package/dist/renderer/assets/KnowledgeHome-r2ZuvU8-.js +11 -0
- package/dist/renderer/assets/Logs-BaljtmAV.js +1 -0
- package/dist/renderer/assets/{Modal-DwY4lecS.js → Modal-CXhD_OWR.js} +1 -1
- package/dist/renderer/assets/MonitorList-D7tyipbx.js +1 -0
- package/dist/renderer/assets/{Page-CnB9ePsb.js → Page-KUuFYgjg.js} +1 -1
- package/dist/renderer/assets/ProjectDetail-Ddq94-yu.js +11 -0
- package/dist/renderer/assets/ProjectList-CbdHd5Ev.js +1 -0
- package/dist/renderer/assets/{Select-zfoksLGB.js → Select-Djc8BXMC.js} +1 -1
- package/dist/renderer/assets/SessionChat-DOy0iKQR.js +1 -0
- package/dist/renderer/assets/SessionList-DHgl1s1D.js +1 -0
- package/dist/renderer/assets/ThreadChat-I7dYibDc.js +23 -0
- package/dist/renderer/assets/Workspace-DTocqY-F.js +19 -0
- package/dist/renderer/assets/{arrow-left-CNEAuElg.js → arrow-left-CXyya3hP.js} +1 -1
- package/dist/renderer/assets/{book-open-BNJMhNI-.js → book-open-9n4Kxc7E.js} +1 -1
- package/dist/renderer/assets/bot-C9HBk5XH.js +6 -0
- package/dist/renderer/assets/{check-BnclClRU.js → check-CutSg9a5.js} +1 -1
- package/dist/renderer/assets/{chevron-down-Bh53e0O-.js → chevron-down-DrydR4i3.js} +1 -1
- package/dist/renderer/assets/{circle-ClZTWCWO.js → circle-BEjtahw6.js} +1 -1
- package/dist/renderer/assets/desktop-DATgk_ka.js +1 -0
- package/dist/renderer/assets/{desktop-C6q6wBae.js → desktop-JQkhNOF4.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-_5hsz0xI.js → funnel-BhqZpS4f.js} +1 -1
- package/dist/renderer/assets/{heart-u4Q1aOqj.js → heart-Dp8Vs-7_.js} +1 -1
- package/dist/renderer/assets/{index-BNFx4uYv.js → index-BKpv0P0s.js} +2 -2
- package/dist/renderer/assets/index-CO4fGqmv.css +11 -0
- package/dist/renderer/assets/{index-B36eowj-.js → index-cI3pWBnN.js} +36 -36
- package/dist/renderer/assets/ja-DtvtBRTW.js +1 -0
- package/dist/renderer/assets/{pencil-DLh9QNmT.js → pencil-ywcJzeOo.js} +1 -1
- package/dist/renderer/assets/{play-BDTk9Scm.js → play-AtN492Cx.js} +1 -1
- package/dist/renderer/assets/{plus-BSc8POsz.js → plus-BEj14BBV.js} +1 -1
- package/dist/renderer/assets/projects-Clar8lgb.js +1 -0
- package/dist/renderer/assets/save-D6ov4CNv.js +11 -0
- package/dist/renderer/assets/{search-CniPk7Ey.js → search-C3bvw7AR.js} +1 -1
- package/dist/renderer/assets/{server-GsXyQAZm.js → server-C1Uyedyx.js} +1 -1
- package/dist/renderer/assets/{session-utils-BDxzgTBC.js → session-utils-DpRwJ6Nh.js} +1 -1
- package/dist/renderer/assets/{sessions-CLcKA1Tt.js → sessions-BWmAppwK.js} +1 -1
- package/dist/renderer/assets/{shield-check-4i0E3hmf.js → shield-check-CVx1mEs2.js} +1 -1
- package/dist/renderer/assets/{trash-2-DhtOCsO5.js → trash-2-o-heXOgs.js} +1 -1
- package/dist/renderer/assets/user-dPOzUqIc.js +6 -0
- package/dist/renderer/assets/{wifi-off-BHPzPY_B.js → wifi-off-Fz5c3_x_.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/inbound.js +55 -1
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +65 -10
- 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/weixin/local-core-weixin-gateway.js +139 -29
- 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/lark-gateway.test.js +139 -0
- package/dist-electron/tests/integration/local-core-refactor.test.js +183 -20
- package/dist-electron/tests/integration/local-core-routes.test.js +34 -0
- package/package.json +2 -3
- package/dist/renderer/assets/Chat-BK-fm0Xr.js +0 -2
- package/dist/renderer/assets/Config-B93CQGvY.js +0 -16
- package/dist/renderer/assets/CronList-Z3TvSRKP.js +0 -1
- package/dist/renderer/assets/Dashboard-Ch3QkWwf.js +0 -26
- package/dist/renderer/assets/KnowledgeHome-ChvjOfrc.js +0 -11
- package/dist/renderer/assets/Logs-Cv0nth3j.js +0 -1
- package/dist/renderer/assets/MonitorList-JEvMoWUm.js +0 -1
- package/dist/renderer/assets/ProjectDetail-DJa3sMmU.js +0 -11
- package/dist/renderer/assets/ProjectList-D6CXumR_.js +0 -1
- package/dist/renderer/assets/SessionChat-DUTh4WoM.js +0 -1
- package/dist/renderer/assets/SessionList-D9o-lUst.js +0 -1
- package/dist/renderer/assets/ThreadChat-BYXlT-Kc.js +0 -23
- package/dist/renderer/assets/Workspace-BrhSwRQ-.js +0 -14
- package/dist/renderer/assets/desktop-C5vBT0yM.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/plug-BG0JHW6B.js +0 -6
- package/dist/renderer/assets/projects-DwfZwxDW.js +0 -1
- package/dist/renderer/assets/save-D5AO_G6a.js +0 -6
- package/dist/renderer/assets/user-BtC_pVXV.js +0 -11
- package/dist/renderer/assets/zh-DIcdHycM.js +0 -1
- package/dist/renderer/assets/zh-TW-BtRwreY_.js +0 -1
|
@@ -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
|
+
}
|
|
@@ -32,7 +32,10 @@ function normalizeLarkInboundMessageEvent(data, options = {}) {
|
|
|
32
32
|
detail: `chat=${String(message.chat_id || '')} message=${String(message.message_id || '')}`,
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
const
|
|
35
|
+
const rawText = messageType === 'post'
|
|
36
|
+
? extractLarkPostText(parsedContent, botOpenId)
|
|
37
|
+
: String(parsedContent.text || '').trim();
|
|
38
|
+
const text = stripLarkMentions(rawText, mentions, botOpenId);
|
|
36
39
|
const platformUserId = String(sender.sender_id?.user_id || sender.sender_id?.open_id || '').trim();
|
|
37
40
|
const chatId = String(message.chat_id || platformUserId).trim();
|
|
38
41
|
if (!platformUserId || !chatId) {
|
|
@@ -112,3 +115,54 @@ function getMentionOpenId(item) {
|
|
|
112
115
|
const id = item.id || item.user_id || item.userId || {};
|
|
113
116
|
return String(id.open_id || id.openId || item.open_id || item.openId || '').trim();
|
|
114
117
|
}
|
|
118
|
+
function extractLarkPostText(content, botOpenId) {
|
|
119
|
+
const title = String(content.title || '').trim();
|
|
120
|
+
const lines = readLarkPostLines(content)
|
|
121
|
+
.map((line) => readLarkPostLineText(line, botOpenId).trim())
|
|
122
|
+
.filter(Boolean);
|
|
123
|
+
return [
|
|
124
|
+
...(title ? [title] : []),
|
|
125
|
+
...lines,
|
|
126
|
+
].join('\n').trim();
|
|
127
|
+
}
|
|
128
|
+
function readLarkPostLines(content) {
|
|
129
|
+
const directContent = content.content;
|
|
130
|
+
if (Array.isArray(directContent)) {
|
|
131
|
+
return directContent;
|
|
132
|
+
}
|
|
133
|
+
const localizedContent = content.zh_cn?.content || content.en_us?.content;
|
|
134
|
+
return Array.isArray(localizedContent) ? localizedContent : [];
|
|
135
|
+
}
|
|
136
|
+
function readLarkPostLineText(line, botOpenId) {
|
|
137
|
+
if (Array.isArray(line)) {
|
|
138
|
+
return line.map((item) => readLarkPostInlineText(item, botOpenId)).join('');
|
|
139
|
+
}
|
|
140
|
+
return readLarkPostInlineText(line, botOpenId);
|
|
141
|
+
}
|
|
142
|
+
function readLarkPostInlineText(item, botOpenId) {
|
|
143
|
+
if (!item || typeof item !== 'object') {
|
|
144
|
+
return '';
|
|
145
|
+
}
|
|
146
|
+
const node = item;
|
|
147
|
+
const tag = String(node.tag || '').trim().toLowerCase();
|
|
148
|
+
if (tag === 'at') {
|
|
149
|
+
if (botOpenId && getMentionOpenId(node) === botOpenId) {
|
|
150
|
+
return '';
|
|
151
|
+
}
|
|
152
|
+
const name = String(node.user_name || node.name || node.display_name || node.text || '').trim();
|
|
153
|
+
return name ? `@${name}` : '';
|
|
154
|
+
}
|
|
155
|
+
if (tag === 'a') {
|
|
156
|
+
return String(node.text || node.href || '').trim();
|
|
157
|
+
}
|
|
158
|
+
if (typeof node.text === 'string') {
|
|
159
|
+
return node.text;
|
|
160
|
+
}
|
|
161
|
+
if (Array.isArray(node.children)) {
|
|
162
|
+
return node.children.map((child) => readLarkPostInlineText(child, botOpenId)).join('');
|
|
163
|
+
}
|
|
164
|
+
if (Array.isArray(node.content)) {
|
|
165
|
+
return node.content.map((child) => readLarkPostInlineText(child, botOpenId)).join('');
|
|
166
|
+
}
|
|
167
|
+
return '';
|
|
168
|
+
}
|
|
@@ -38,6 +38,7 @@ const node_events_1 = require("node:events");
|
|
|
38
38
|
const node_crypto_1 = require("node:crypto");
|
|
39
39
|
const node_fs_1 = require("node:fs");
|
|
40
40
|
const node_path_1 = require("node:path");
|
|
41
|
+
const local_core_errors_js_1 = require("../../kernel/local-core-errors.js");
|
|
41
42
|
const desktop_js_1 = require("../../../../../shared/desktop.js");
|
|
42
43
|
const content_js_1 = require("../shared/content.js");
|
|
43
44
|
const file_utils_js_1 = require("../shared/file-utils.js");
|
|
@@ -49,7 +50,7 @@ const registration_js_1 = require("./registration.js");
|
|
|
49
50
|
const messages_js_1 = require("./rendering/messages.js");
|
|
50
51
|
const inbound_js_1 = require("./inbound.js");
|
|
51
52
|
const runtime_state_js_1 = require("./runtime-state.js");
|
|
52
|
-
const
|
|
53
|
+
const thread_slash_command_dispatcher_js_1 = require("../../thread/thread-slash-command-dispatcher.js");
|
|
53
54
|
const PAIRING_EXPIRY_MS = 10 * 60 * 1000;
|
|
54
55
|
const LARK_MAX_UPLOAD_FILE_SIZE = 30 * 1024 * 1024;
|
|
55
56
|
const LARK_FINAL_PATCH_INTERVAL_MS = 900;
|
|
@@ -73,15 +74,29 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
73
74
|
constructor(options) {
|
|
74
75
|
super();
|
|
75
76
|
this.options = options;
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
const slashCommands = new thread_slash_command_dispatcher_js_1.ThreadSlashCommandDispatcher({
|
|
78
|
+
session: {
|
|
79
|
+
listThreads: (workspaceId) => this.options.getWorkspaceRouter().listThreads(workspaceId),
|
|
80
|
+
getThread: (threadId) => this.options.getWorkspaceRouter().getThread(threadId),
|
|
81
|
+
createThread: (workspaceId, title) => this.options.getWorkspaceRouter().createThread(workspaceId, title),
|
|
82
|
+
renameThread: (threadId, title) => this.options.getWorkspaceRouter().renameThread(threadId, title),
|
|
83
|
+
deleteThread: (threadId) => this.options.getWorkspaceRouter().deleteThread(threadId),
|
|
84
|
+
},
|
|
85
|
+
thread: {
|
|
86
|
+
getThreadRow: (threadId) => this.options.store.getThreadRow(threadId),
|
|
87
|
+
updateThreadAgentMode: (threadId, mode) => this.options.store.updateThreadAgentMode(threadId, mode),
|
|
88
|
+
updateThreadAgentType: (threadId, agentType) => this.options.store.updateThreadAgentType(threadId, agentType),
|
|
89
|
+
getLatestRunForThread: (threadId) => this.options.store.getLatestRunForThread(threadId),
|
|
90
|
+
createAuditEvent: (input) => this.options.store.createAuditEvent(input),
|
|
91
|
+
getAgentTypes: () => this.options.getWorkspaceRouter().getAgentTypes(),
|
|
92
|
+
setThreadMode: (threadId, mode) => this.options.getWorkspaceRouter().setThreadMode(threadId, mode),
|
|
93
|
+
closeThreadSession: (threadId) => this.options.getWorkspaceRouter().closeThreadSession(threadId),
|
|
94
|
+
interruptRun: (runId) => this.options.getWorkspaceRouter().interruptRun(runId),
|
|
95
|
+
log: this.options.log,
|
|
96
|
+
},
|
|
82
97
|
});
|
|
83
98
|
this.sessionCommandRuntime = new session_command_runtime_js_1.ChannelSessionCommandRuntime({
|
|
84
|
-
|
|
99
|
+
dispatcher: slashCommands,
|
|
85
100
|
store: this.options.store,
|
|
86
101
|
getThreadSessionKey: (threadId) => this.options.getWorkspaceRouter().getThreadSessionKey(threadId),
|
|
87
102
|
setThreadRoute: (sessionKey, route) => {
|
|
@@ -382,6 +397,8 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
382
397
|
status: binding?.status || 'disabled',
|
|
383
398
|
appId: binding?.appId || '',
|
|
384
399
|
lastError: binding?.lastError,
|
|
400
|
+
lastErrorInfo: binding?.lastErrorInfo,
|
|
401
|
+
lastErrorAt: binding?.lastErrorAt,
|
|
385
402
|
connectedAt: binding?.connectedAt,
|
|
386
403
|
pendingPairings: pairings.length,
|
|
387
404
|
authorizedUsers: users.length,
|
|
@@ -698,6 +715,7 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
698
715
|
currentThreadId: threadId,
|
|
699
716
|
text: input.text,
|
|
700
717
|
defaultTitle: `${input.displayName || 'Lark'} ${new Date().toLocaleTimeString()}`,
|
|
718
|
+
defaultAgentType: slashCommand ? await this.resolveDefaultAgentType(input.workspaceId, threadId) : '',
|
|
701
719
|
chatId: input.chatId,
|
|
702
720
|
platformUserId: input.platformUserId,
|
|
703
721
|
platformKey,
|
|
@@ -841,13 +859,20 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
841
859
|
status.status = 'running';
|
|
842
860
|
status.connected = true;
|
|
843
861
|
status.connectedAt = new Date().toISOString();
|
|
844
|
-
status
|
|
862
|
+
this.clearRuntimeError(status);
|
|
845
863
|
this.options.log?.(`localcore-lark ws ready for ${binding.workspaceId}`);
|
|
846
864
|
}
|
|
847
865
|
catch (error) {
|
|
848
866
|
status.status = 'error';
|
|
849
867
|
status.connected = false;
|
|
850
|
-
|
|
868
|
+
const errorInfo = (0, local_core_errors_js_1.toLocalCoreErrorInfo)(error instanceof local_core_errors_js_1.LocalCoreError
|
|
869
|
+
? error
|
|
870
|
+
: new local_core_errors_js_1.LocalCoreError('channel_auth_failed', error instanceof Error ? error.message : String(error), {
|
|
871
|
+
userMessage: 'Lark is not connected.',
|
|
872
|
+
suggestedAction: 'Check app credentials and restart the Lark gateway.',
|
|
873
|
+
details: { workspaceId: binding.workspaceId, instanceId: binding.instanceId },
|
|
874
|
+
}), 'channel_auth_failed');
|
|
875
|
+
this.setRuntimeError(status, errorInfo);
|
|
851
876
|
this.options.log?.(`localcore-lark start failed for ${binding.workspaceId}: ${status.lastError}`);
|
|
852
877
|
}
|
|
853
878
|
this.notifyRuntimeStateChanged();
|
|
@@ -894,6 +919,28 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
894
919
|
},
|
|
895
920
|
});
|
|
896
921
|
}
|
|
922
|
+
clearRuntimeError(state) {
|
|
923
|
+
state.lastError = undefined;
|
|
924
|
+
state.lastErrorInfo = undefined;
|
|
925
|
+
state.lastErrorAt = undefined;
|
|
926
|
+
}
|
|
927
|
+
setRuntimeError(state, errorInfo) {
|
|
928
|
+
state.lastError = errorInfo.message;
|
|
929
|
+
state.lastErrorInfo = errorInfo;
|
|
930
|
+
state.lastErrorAt = new Date().toISOString();
|
|
931
|
+
this.options.eventBus.emit({
|
|
932
|
+
type: 'localcore.error',
|
|
933
|
+
payload: {
|
|
934
|
+
scope: 'channel.lark',
|
|
935
|
+
errorInfo,
|
|
936
|
+
context: {
|
|
937
|
+
workspaceId: state.workspaceId,
|
|
938
|
+
instanceId: state.instanceId,
|
|
939
|
+
platform: 'lark',
|
|
940
|
+
},
|
|
941
|
+
},
|
|
942
|
+
});
|
|
943
|
+
}
|
|
897
944
|
async handleMessageEvent(workspaceId, instanceIdOrData, platformKeyOrData, maybeData) {
|
|
898
945
|
const legacyCall = typeof instanceIdOrData === 'object';
|
|
899
946
|
const instanceId = legacyCall ? 'default' : instanceIdOrData;
|
|
@@ -1308,6 +1355,7 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1308
1355
|
currentThreadId: sessionAction.threadId,
|
|
1309
1356
|
text: sessionAction.command,
|
|
1310
1357
|
defaultTitle: `Lark ${new Date().toLocaleTimeString()}`,
|
|
1358
|
+
defaultAgentType: await this.resolveDefaultAgentType(workspaceId, sessionAction.threadId),
|
|
1311
1359
|
chatId: route.chatId,
|
|
1312
1360
|
platformUserId: route.platformUserId,
|
|
1313
1361
|
platformKey: route.platformKey,
|
|
@@ -1344,6 +1392,13 @@ class LocalCoreLarkGateway extends node_events_1.EventEmitter {
|
|
|
1344
1392
|
threadId: binding.thread_id,
|
|
1345
1393
|
};
|
|
1346
1394
|
}
|
|
1395
|
+
async resolveDefaultAgentType(workspaceId, threadId) {
|
|
1396
|
+
const router = this.options.getWorkspaceRouter();
|
|
1397
|
+
if (typeof router.getWorkspaceDefaultAgentType === 'function') {
|
|
1398
|
+
return router.getWorkspaceDefaultAgentType(workspaceId);
|
|
1399
|
+
}
|
|
1400
|
+
return this.options.store.getThreadRow(threadId)?.agent_type || 'codex';
|
|
1401
|
+
}
|
|
1347
1402
|
async markPermissionCardActionHandled(workspaceId, instanceId, rootPayload, payload, value, response, threadId) {
|
|
1348
1403
|
const state = this.resolveRuntimeState(workspaceId, instanceId).state;
|
|
1349
1404
|
if (!state?.client) {
|
|
@@ -7,10 +7,12 @@ class ChannelSessionCommandRuntime {
|
|
|
7
7
|
this.options = options;
|
|
8
8
|
}
|
|
9
9
|
async execute(input) {
|
|
10
|
-
const result = await this.options.
|
|
10
|
+
const result = await this.options.dispatcher.execute({
|
|
11
11
|
workspaceId: input.workspaceId,
|
|
12
|
-
|
|
12
|
+
threadId: input.currentThreadId,
|
|
13
|
+
content: input.text,
|
|
13
14
|
defaultTitle: input.defaultTitle,
|
|
15
|
+
defaultAgentType: input.defaultAgentType,
|
|
14
16
|
});
|
|
15
17
|
if (!result.handled) {
|
|
16
18
|
return { handled: false, threadId: input.currentThreadId };
|