@tencent-ai/cloud-agent-sdk 0.2.13 → 0.2.14-next.0a3c83c.20260321
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/dist/e2b-filesystem-4-LU6-jg.cjs +168 -0
- package/dist/e2b-filesystem-4-LU6-jg.cjs.map +1 -0
- package/dist/e2b-filesystem-BNmEfpoW.mjs +162 -0
- package/dist/e2b-filesystem-BNmEfpoW.mjs.map +1 -0
- package/dist/e2b-filesystem-B_WoA22S.cjs +252 -0
- package/dist/e2b-filesystem-B_WoA22S.cjs.map +1 -0
- package/dist/e2b-filesystem-Cac-bpRR.cjs +3 -0
- package/dist/e2b-filesystem-DM_jsT05.mjs +234 -0
- package/dist/e2b-filesystem-DM_jsT05.mjs.map +1 -0
- package/dist/e2b-filesystem-DWj9UkV8.mjs +3 -0
- package/dist/e2b-filesystem-DcVVT_tP.cjs +4 -0
- package/dist/e2b-filesystem-UheQECjB.mjs +3 -0
- package/dist/index.cjs +2179 -383
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1851 -70
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1851 -70
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2171 -376
- package/dist/index.mjs.map +1 -1
- package/dist/legacy/index.cjs +24010 -0
- package/dist/legacy/index.cjs.map +1 -0
- package/dist/legacy/index.d.cts +6400 -0
- package/dist/legacy/index.d.cts.map +1 -0
- package/dist/legacy/index.d.mts +6400 -0
- package/dist/legacy/index.d.mts.map +1 -0
- package/dist/legacy/index.mjs +13286 -0
- package/dist/legacy/index.mjs.map +1 -0
- package/dist/tencent-ai-cloud-agent-sdk-0.2.14-next.0a3c83c.20260321.tgz +0 -0
- package/package.json +44 -7
- package/dist/tencent-ai-cloud-agent-sdk-0.2.13.tgz +0 -0
package/dist/index.cjs
CHANGED
|
@@ -39,6 +39,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
39
39
|
}) : target, mod));
|
|
40
40
|
|
|
41
41
|
//#endregion
|
|
42
|
+
const require_e2b_filesystem = require('./e2b-filesystem-4-LU6-jg.cjs');
|
|
42
43
|
let zod = require("zod");
|
|
43
44
|
let _agentclientprotocol_sdk = require("@agentclientprotocol/sdk");
|
|
44
45
|
require("@bufbuild/protobuf");
|
|
@@ -59,7 +60,6 @@ crypto = __toESM(crypto);
|
|
|
59
60
|
let zlib = require("zlib");
|
|
60
61
|
zlib = __toESM(zlib);
|
|
61
62
|
let events = require("events");
|
|
62
|
-
let e2b = require("e2b");
|
|
63
63
|
|
|
64
64
|
//#region ../agent-provider/src/common/_legacy/tool-schemas.ts
|
|
65
65
|
/**
|
|
@@ -93,7 +93,6 @@ const ToolInputSchemas = {
|
|
|
93
93
|
queryString: zod.z.string().describe("用户的实际问题或搜索查询"),
|
|
94
94
|
knowledgeBaseNames: zod.z.string().describe("知识库名称,多个用逗号分隔")
|
|
95
95
|
}),
|
|
96
|
-
read_rules: zod.z.object({ ruleNames: zod.z.string().describe("要读取的规则关键词,用逗号分隔,格式:{ruleName}_{ruleId}") }),
|
|
97
96
|
mcp_get_tool_description: zod.z.object({ toolRequests: zod.z.string().describe("JSON 字符串,二维数组格式:[[\"server1\", \"tool1\"], [\"server2\", \"tool2\"]]") }),
|
|
98
97
|
mcp_call_tool: zod.z.object({
|
|
99
98
|
serverName: zod.z.string().describe("MCP 服务器名称"),
|
|
@@ -107,13 +106,6 @@ const ToolInputSchemas = {
|
|
|
107
106
|
arguments: zod.z.record(zod.z.unknown()).optional().describe("资源模板的参数"),
|
|
108
107
|
downloadPath: zod.z.string().optional().describe("可选的绝对路径,用于保存资源到磁盘")
|
|
109
108
|
}),
|
|
110
|
-
create_rule: zod.z.object({
|
|
111
|
-
ruleScope: zod.z.string().describe("规则范围,project rule 或 user rule"),
|
|
112
|
-
ruleName: zod.z.string().describe("规则文件名,不带扩展名"),
|
|
113
|
-
ruleType: zod.z.string().describe("规则类型,always、manual 或 requested"),
|
|
114
|
-
ruleContent: zod.z.string().describe("规则内容,使用 Markdown 格式"),
|
|
115
|
-
ruleDescription: zod.z.string().optional().describe("规则描述,使用 Markdown 格式")
|
|
116
|
-
}),
|
|
117
109
|
update_memory: zod.z.object({
|
|
118
110
|
action: zod.z.enum([
|
|
119
111
|
"create",
|
|
@@ -172,7 +164,6 @@ const ToolInputSchemas = {
|
|
|
172
164
|
cloud_studio_fetch_log: zod.z.object({}).passthrough(),
|
|
173
165
|
cloud_studio_execute_command: zod.z.object({}).passthrough(),
|
|
174
166
|
cloud_studio_deploy_sandbox: zod.z.object({}).passthrough(),
|
|
175
|
-
component_get_prompt: zod.z.object({}).passthrough(),
|
|
176
167
|
web_fetch: zod.z.object({
|
|
177
168
|
url: zod.z.string().describe("要获取内容的 URL"),
|
|
178
169
|
fetchInfo: zod.z.string().describe("用户想要获取的信息描述")
|
|
@@ -180,7 +171,9 @@ const ToolInputSchemas = {
|
|
|
180
171
|
use_skill: zod.z.object({ command: zod.z.string().describe("技能名称(不含参数),如 \"pdf\" 或 \"xlsx\"") }),
|
|
181
172
|
web_search: zod.z.object({
|
|
182
173
|
explanation: zod.z.string().describe("为什么使用此工具的一句话解释"),
|
|
183
|
-
|
|
174
|
+
query: zod.z.string().describe("搜索关键词"),
|
|
175
|
+
max_results: zod.z.number().optional().describe("最大返回数量"),
|
|
176
|
+
language: zod.z.string().optional().describe("语言代码,例如 zh-CN")
|
|
184
177
|
}),
|
|
185
178
|
task: zod.z.object({
|
|
186
179
|
subagent_name: zod.z.string().describe("要调用的子代理名称"),
|
|
@@ -258,11 +251,6 @@ const ToolOutputSchemas = {
|
|
|
258
251
|
selectedKnowledgeBases: zod.z.string(),
|
|
259
252
|
queryInput: zod.z.string()
|
|
260
253
|
}),
|
|
261
|
-
read_rules: zod.z.object({
|
|
262
|
-
type: zod.z.literal("rule_match_result"),
|
|
263
|
-
ruleDescription: zod.z.string(),
|
|
264
|
-
filePaths: zod.z.array(zod.z.string())
|
|
265
|
-
}),
|
|
266
254
|
mcp_get_tool_description: zod.z.object({}).passthrough(),
|
|
267
255
|
mcp_call_tool: zod.z.object({
|
|
268
256
|
type: zod.z.literal("mcp_call_tool_result"),
|
|
@@ -299,17 +287,6 @@ const ToolOutputSchemas = {
|
|
|
299
287
|
content: zod.z.string(),
|
|
300
288
|
downloadPath: zod.z.string().optional()
|
|
301
289
|
}),
|
|
302
|
-
create_rule: zod.z.object({
|
|
303
|
-
type: zod.z.literal("rule_create_result"),
|
|
304
|
-
ruleName: zod.z.string(),
|
|
305
|
-
createState: zod.z.enum([
|
|
306
|
-
"success",
|
|
307
|
-
"invoke",
|
|
308
|
-
"cancelled"
|
|
309
|
-
]),
|
|
310
|
-
hint: zod.z.string().optional(),
|
|
311
|
-
filePath: zod.z.string().optional()
|
|
312
|
-
}),
|
|
313
290
|
update_memory: zod.z.object({
|
|
314
291
|
type: zod.z.literal("update_memory_result"),
|
|
315
292
|
success: zod.z.boolean(),
|
|
@@ -323,9 +300,9 @@ const ToolOutputSchemas = {
|
|
|
323
300
|
}),
|
|
324
301
|
search_content: zod.z.object({
|
|
325
302
|
type: zod.z.literal("search_content_result"),
|
|
326
|
-
|
|
303
|
+
path: zod.z.string(),
|
|
327
304
|
pattern: zod.z.string(),
|
|
328
|
-
|
|
305
|
+
glob: zod.z.string(),
|
|
329
306
|
matches: zod.z.array(zod.z.object({
|
|
330
307
|
filePath: zod.z.string(),
|
|
331
308
|
content: zod.z.string(),
|
|
@@ -337,7 +314,7 @@ const ToolOutputSchemas = {
|
|
|
337
314
|
totalCount: zod.z.number(),
|
|
338
315
|
hasMore: zod.z.boolean(),
|
|
339
316
|
offset: zod.z.number(),
|
|
340
|
-
|
|
317
|
+
headLimit: zod.z.number(),
|
|
341
318
|
contextBefore: zod.z.number(),
|
|
342
319
|
contextAfter: zod.z.number(),
|
|
343
320
|
contextAround: zod.z.number().optional(),
|
|
@@ -523,15 +500,6 @@ const ToolOutputSchemas = {
|
|
|
523
500
|
}).optional()
|
|
524
501
|
}))
|
|
525
502
|
}),
|
|
526
|
-
component_get_prompt: zod.z.object({
|
|
527
|
-
type: zod.z.literal("component_get_prompt_result"),
|
|
528
|
-
componentType: zod.z.string(),
|
|
529
|
-
webFramework: zod.z.string(),
|
|
530
|
-
data: zod.z.object({
|
|
531
|
-
type: zod.z.literal("text"),
|
|
532
|
-
text: zod.z.string()
|
|
533
|
-
})
|
|
534
|
-
}),
|
|
535
503
|
web_fetch: zod.z.object({
|
|
536
504
|
type: zod.z.literal("web_fetch_tool_result"),
|
|
537
505
|
message: zod.z.string(),
|
|
@@ -547,14 +515,29 @@ const ToolOutputSchemas = {
|
|
|
547
515
|
}),
|
|
548
516
|
web_search: zod.z.object({
|
|
549
517
|
type: zod.z.literal("web_search_tool_result"),
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
518
|
+
query: zod.z.string().optional(),
|
|
519
|
+
searchType: zod.z.literal("text2text").optional(),
|
|
520
|
+
provider: zod.z.string().optional(),
|
|
521
|
+
results: zod.z.array(zod.z.object({
|
|
554
522
|
title: zod.z.string(),
|
|
555
|
-
|
|
556
|
-
|
|
523
|
+
url: zod.z.string(),
|
|
524
|
+
snippet: zod.z.string().optional(),
|
|
525
|
+
site: zod.z.string().optional(),
|
|
526
|
+
highlights: zod.z.array(zod.z.string()).optional(),
|
|
527
|
+
content: zod.z.string().optional(),
|
|
528
|
+
favicon: zod.z.string().optional()
|
|
557
529
|
})),
|
|
530
|
+
images: zod.z.array(zod.z.object({
|
|
531
|
+
url: zod.z.string(),
|
|
532
|
+
description: zod.z.string().optional(),
|
|
533
|
+
sourceUrl: zod.z.string().optional(),
|
|
534
|
+
width: zod.z.number().optional(),
|
|
535
|
+
height: zod.z.number().optional(),
|
|
536
|
+
title: zod.z.string().optional(),
|
|
537
|
+
siteName: zod.z.string().optional()
|
|
538
|
+
})),
|
|
539
|
+
totalResults: zod.z.number().optional(),
|
|
540
|
+
responseTimeMs: zod.z.number().optional(),
|
|
558
541
|
searchInput: zod.z.string().optional()
|
|
559
542
|
}),
|
|
560
543
|
task: zod.z.object({
|
|
@@ -700,7 +683,11 @@ const ExtensionMethod = {
|
|
|
700
683
|
CHECKPOINT: "_codebuddy.ai/checkpoint",
|
|
701
684
|
USAGE: "_codebuddy.ai/usage",
|
|
702
685
|
COMMAND: "_codebuddy.ai/command",
|
|
703
|
-
AUTH_URL: "_codebuddy.ai/authUrl"
|
|
686
|
+
AUTH_URL: "_codebuddy.ai/authUrl",
|
|
687
|
+
FILE_HISTORY_SNAPSHOT: "_codebuddy.ai/file_history_snapshot",
|
|
688
|
+
DELEGATE_TOOL: "_codebuddy.ai/delegateTool",
|
|
689
|
+
DELEGATE_TOOLS_CHANGED: "_codebuddy.ai/delegateToolsChanged",
|
|
690
|
+
UI_CONTROL: "_codebuddy.ai/uiControl"
|
|
704
691
|
};
|
|
705
692
|
/**
|
|
706
693
|
* All known extension methods
|
|
@@ -711,7 +698,10 @@ const KNOWN_EXTENSIONS = [
|
|
|
711
698
|
ExtensionMethod.CHECKPOINT,
|
|
712
699
|
ExtensionMethod.USAGE,
|
|
713
700
|
ExtensionMethod.COMMAND,
|
|
714
|
-
ExtensionMethod.AUTH_URL
|
|
701
|
+
ExtensionMethod.AUTH_URL,
|
|
702
|
+
ExtensionMethod.FILE_HISTORY_SNAPSHOT,
|
|
703
|
+
ExtensionMethod.DELEGATE_TOOL,
|
|
704
|
+
ExtensionMethod.DELEGATE_TOOLS_CHANGED
|
|
715
705
|
];
|
|
716
706
|
|
|
717
707
|
//#endregion
|
|
@@ -762,7 +752,7 @@ function parseSSELine(line, currentEvent) {
|
|
|
762
752
|
};
|
|
763
753
|
}
|
|
764
754
|
function streamableHttp(options) {
|
|
765
|
-
const { endpoint, authToken, headers: customHeaders = {}, reconnect = {}, signal: externalSignal, fetch: customFetch = globalThis.fetch, onConnect, onDisconnect, onError, heartbeatTimeout = 6e4, postTimeout = 3e4, backpressure = {} } = options;
|
|
755
|
+
const { endpoint, authToken, headers: customHeaders = {}, reconnect = {}, signal: externalSignal, fetch: customFetch = globalThis.fetch, onConnect, onDisconnect, onError, heartbeatTimeout = 6e4, connectionTimeout = 3e4, postTimeout = 3e4, backpressure = {} } = options;
|
|
766
756
|
const { enabled: reconnectEnabled = true, initialDelay = 1e3, maxDelay = 3e4, maxRetries = Infinity, jitter: jitterEnabled = true } = reconnect;
|
|
767
757
|
const { highWaterMark = 100, lowWaterMark = 50, pauseTimeout = 5e3 } = backpressure;
|
|
768
758
|
let connectionId;
|
|
@@ -973,11 +963,21 @@ function streamableHttp(options) {
|
|
|
973
963
|
const headers = buildHeaders();
|
|
974
964
|
headers["Accept"] = "text/event-stream";
|
|
975
965
|
if (lastEventId) headers["Last-Event-ID"] = lastEventId;
|
|
976
|
-
const
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
});
|
|
966
|
+
const connectTimeoutMs = connectionTimeout > 0 ? connectionTimeout : 3e4;
|
|
967
|
+
const connectController = new AbortController();
|
|
968
|
+
const connectTimer = setTimeout(() => connectController.abort(), connectTimeoutMs);
|
|
969
|
+
if (externalSignal) externalSignal.addEventListener("abort", () => connectController.abort(), { once: true });
|
|
970
|
+
abortController.signal.addEventListener("abort", () => connectController.abort(), { once: true });
|
|
971
|
+
let response;
|
|
972
|
+
try {
|
|
973
|
+
response = await customFetch(endpoint, {
|
|
974
|
+
method: "GET",
|
|
975
|
+
headers,
|
|
976
|
+
signal: connectController.signal
|
|
977
|
+
});
|
|
978
|
+
} finally {
|
|
979
|
+
clearTimeout(connectTimer);
|
|
980
|
+
}
|
|
981
981
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
982
982
|
const newConnectionId = response.headers.get("Acp-Connection-Id");
|
|
983
983
|
if (!newConnectionId) throw new Error("Server did not return Acp-Connection-Id header");
|
|
@@ -1913,6 +1913,9 @@ var StreamableHttpClient = class {
|
|
|
1913
1913
|
headers: this.options.headers,
|
|
1914
1914
|
reconnect: this.options.reconnect,
|
|
1915
1915
|
fetch: this.options.fetch,
|
|
1916
|
+
heartbeatTimeout: this.options.heartbeatTimeout,
|
|
1917
|
+
postTimeout: this.options.postTimeout,
|
|
1918
|
+
connectionTimeout: this.options.connectionTimeout,
|
|
1916
1919
|
onConnect: (connectionId) => {
|
|
1917
1920
|
this.options.logger?.debug(`Transport connected: ${connectionId}`);
|
|
1918
1921
|
},
|
|
@@ -1987,10 +1990,6 @@ var StreamableHttpClient = class {
|
|
|
1987
1990
|
},
|
|
1988
1991
|
requestPermission: async (params) => this.handleRequestPermission(params),
|
|
1989
1992
|
extNotification: async (method, params) => {
|
|
1990
|
-
console.log("[ACP-Client] extNotification callback invoked:", {
|
|
1991
|
-
method,
|
|
1992
|
-
paramsKeys: Object.keys(params)
|
|
1993
|
-
});
|
|
1994
1993
|
await this.handleExtNotification(method, params);
|
|
1995
1994
|
},
|
|
1996
1995
|
extMethod: async (method, params) => this.handleExtMethod(method, params)
|
|
@@ -1998,10 +1997,15 @@ var StreamableHttpClient = class {
|
|
|
1998
1997
|
}
|
|
1999
1998
|
/**
|
|
2000
1999
|
* Create a new session
|
|
2000
|
+
*
|
|
2001
|
+
* Retries on transient network errors (e.g., proxy connection reset)
|
|
2002
|
+
* since session/new is idempotent and safe to retry.
|
|
2001
2003
|
*/
|
|
2002
2004
|
async createSession(cwd) {
|
|
2003
2005
|
this.ensureInitialized("createSession");
|
|
2004
|
-
|
|
2006
|
+
const maxRetries = 2;
|
|
2007
|
+
let lastError;
|
|
2008
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) try {
|
|
2005
2009
|
const response = await this.connection.newSession({
|
|
2006
2010
|
cwd,
|
|
2007
2011
|
mcpServers: []
|
|
@@ -2009,8 +2013,16 @@ var StreamableHttpClient = class {
|
|
|
2009
2013
|
this.options.logger?.info(`Session created: ${response.sessionId}`);
|
|
2010
2014
|
return response;
|
|
2011
2015
|
} catch (err) {
|
|
2012
|
-
|
|
2016
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
2017
|
+
if (attempt < maxRetries && isRetryableNetworkError(err)) {
|
|
2018
|
+
const delay = 500 * Math.pow(2, attempt);
|
|
2019
|
+
this.options.logger?.warn(`session/new network error, retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries}): ${lastError.message}`);
|
|
2020
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2021
|
+
continue;
|
|
2022
|
+
}
|
|
2023
|
+
throw new SessionError(`Failed to create session: ${lastError.message}`, void 0, lastError);
|
|
2013
2024
|
}
|
|
2025
|
+
throw new SessionError(`Failed to create session: ${lastError?.message}`, void 0, lastError);
|
|
2014
2026
|
}
|
|
2015
2027
|
/**
|
|
2016
2028
|
* Load an existing session
|
|
@@ -2234,6 +2246,18 @@ var StreamableHttpClient = class {
|
|
|
2234
2246
|
if (this.state !== "initialized") throw new InvalidStateError(operation, this.state, ["initialized"]);
|
|
2235
2247
|
}
|
|
2236
2248
|
};
|
|
2249
|
+
/**
|
|
2250
|
+
* Check if an error is a retryable network-level error.
|
|
2251
|
+
* Only network failures (TypeError from fetch) are retried, NOT HTTP errors (4xx/5xx).
|
|
2252
|
+
*/
|
|
2253
|
+
function isRetryableNetworkError(error) {
|
|
2254
|
+
if (error instanceof TypeError) return true;
|
|
2255
|
+
if (error instanceof Error) {
|
|
2256
|
+
const msg = error.message.toLowerCase();
|
|
2257
|
+
return msg.includes("failed to fetch") || msg.includes("fetch failed") || msg.includes("network request failed") || msg.includes("econnreset") || msg.includes("econnrefused") || msg.includes("socket hang up");
|
|
2258
|
+
}
|
|
2259
|
+
return false;
|
|
2260
|
+
}
|
|
2237
2261
|
|
|
2238
2262
|
//#endregion
|
|
2239
2263
|
//#region ../agent-provider/src/common/providers/cloud-agent-provider/cloud-connection.ts
|
|
@@ -2269,7 +2293,7 @@ var CloudAgentConnection = class {
|
|
|
2269
2293
|
fetch: config.fetch,
|
|
2270
2294
|
clientCapabilities: config.clientCapabilities,
|
|
2271
2295
|
onSessionUpdate: (update) => {
|
|
2272
|
-
if (!this._isStreaming) this.emit("sessionUpdate", update);
|
|
2296
|
+
if (!this._isStreaming && this.isOwnSessionNotification(update)) this.emit("sessionUpdate", update);
|
|
2273
2297
|
},
|
|
2274
2298
|
onArtifact: (artifact, event) => {
|
|
2275
2299
|
console.log("[CloudConnection] onArtifact callback:", {
|
|
@@ -2283,10 +2307,41 @@ var CloudAgentConnection = class {
|
|
|
2283
2307
|
},
|
|
2284
2308
|
onUsageUpdate: (usage) => {
|
|
2285
2309
|
this.emit("usageUpdate", usage);
|
|
2310
|
+
},
|
|
2311
|
+
onExtNotification: (method, params) => {
|
|
2312
|
+
console.log("[CloudConnection] Received extNotification:", {
|
|
2313
|
+
method,
|
|
2314
|
+
paramsKeys: Object.keys(params)
|
|
2315
|
+
});
|
|
2316
|
+
if (method === ExtensionMethod.COMMAND) {
|
|
2317
|
+
const action = params.action;
|
|
2318
|
+
const commandParams = params.params;
|
|
2319
|
+
console.log("[CloudConnection] Emitting command event:", {
|
|
2320
|
+
action,
|
|
2321
|
+
paramsKeys: commandParams ? Object.keys(commandParams) : []
|
|
2322
|
+
});
|
|
2323
|
+
this.emit("command", {
|
|
2324
|
+
action,
|
|
2325
|
+
params: commandParams
|
|
2326
|
+
});
|
|
2327
|
+
}
|
|
2286
2328
|
}
|
|
2287
2329
|
});
|
|
2288
2330
|
this.setupEventForwarding();
|
|
2289
2331
|
}
|
|
2332
|
+
/**
|
|
2333
|
+
* Check whether a notification belongs to this connection's own session.
|
|
2334
|
+
*
|
|
2335
|
+
* CloudConnection.createSession() overrides sessionId to agentId, so the
|
|
2336
|
+
* rest of the client stack uses agentId as the canonical session
|
|
2337
|
+
* identifier. Notifications whose sessionId differs from agentId
|
|
2338
|
+
* originate from sub-agent sessions running inside the same sandbox and
|
|
2339
|
+
* should be silently ignored at this layer — the adapter layer handles
|
|
2340
|
+
* sub-agent messages independently via parentToolUseId in _meta.
|
|
2341
|
+
*/
|
|
2342
|
+
isOwnSessionNotification(notification) {
|
|
2343
|
+
return notification.sessionId === this.agentId;
|
|
2344
|
+
}
|
|
2290
2345
|
setupEventForwarding() {
|
|
2291
2346
|
this.client.on("connecting", () => {
|
|
2292
2347
|
this.emit("connecting", void 0);
|
|
@@ -2447,6 +2502,7 @@ var CloudAgentConnection = class {
|
|
|
2447
2502
|
let resolveUpdate = null;
|
|
2448
2503
|
let done = false;
|
|
2449
2504
|
const listener = (update) => {
|
|
2505
|
+
if (!this.isOwnSessionNotification(update)) return;
|
|
2450
2506
|
if (resolveUpdate) {
|
|
2451
2507
|
resolveUpdate(update);
|
|
2452
2508
|
resolveUpdate = null;
|
|
@@ -2529,6 +2585,16 @@ var CloudAgentConnection = class {
|
|
|
2529
2585
|
get sessionConnectionInfo() {
|
|
2530
2586
|
return this._sessionConnectionInfo;
|
|
2531
2587
|
}
|
|
2588
|
+
async reportTelemetry(eventName, payload) {
|
|
2589
|
+
try {
|
|
2590
|
+
await this.client.extMethod("reportTelemetry", {
|
|
2591
|
+
eventName,
|
|
2592
|
+
payload
|
|
2593
|
+
});
|
|
2594
|
+
} catch (error) {
|
|
2595
|
+
console.warn("[CloudAgentConnection] reportTelemetry failed:", error);
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2532
2598
|
async extMethod(method, params) {
|
|
2533
2599
|
return this.client.extMethod(method, params);
|
|
2534
2600
|
}
|
|
@@ -3131,7 +3197,7 @@ var utils_default = {
|
|
|
3131
3197
|
*
|
|
3132
3198
|
* @returns {Error} The created error.
|
|
3133
3199
|
*/
|
|
3134
|
-
function AxiosError(message, code, config, request, response) {
|
|
3200
|
+
function AxiosError$1(message, code, config, request, response) {
|
|
3135
3201
|
Error.call(this);
|
|
3136
3202
|
if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
|
|
3137
3203
|
else this.stack = (/* @__PURE__ */ new Error()).stack;
|
|
@@ -3145,7 +3211,7 @@ function AxiosError(message, code, config, request, response) {
|
|
|
3145
3211
|
this.status = response.status ? response.status : null;
|
|
3146
3212
|
}
|
|
3147
3213
|
}
|
|
3148
|
-
utils_default.inherits(AxiosError, Error, { toJSON: function toJSON() {
|
|
3214
|
+
utils_default.inherits(AxiosError$1, Error, { toJSON: function toJSON() {
|
|
3149
3215
|
return {
|
|
3150
3216
|
message: this.message,
|
|
3151
3217
|
name: this.name,
|
|
@@ -3160,7 +3226,7 @@ utils_default.inherits(AxiosError, Error, { toJSON: function toJSON() {
|
|
|
3160
3226
|
status: this.status
|
|
3161
3227
|
};
|
|
3162
3228
|
} });
|
|
3163
|
-
const prototype$1 = AxiosError.prototype;
|
|
3229
|
+
const prototype$1 = AxiosError$1.prototype;
|
|
3164
3230
|
const descriptors = {};
|
|
3165
3231
|
[
|
|
3166
3232
|
"ERR_BAD_OPTION_VALUE",
|
|
@@ -3178,22 +3244,22 @@ const descriptors = {};
|
|
|
3178
3244
|
].forEach((code) => {
|
|
3179
3245
|
descriptors[code] = { value: code };
|
|
3180
3246
|
});
|
|
3181
|
-
Object.defineProperties(AxiosError, descriptors);
|
|
3247
|
+
Object.defineProperties(AxiosError$1, descriptors);
|
|
3182
3248
|
Object.defineProperty(prototype$1, "isAxiosError", { value: true });
|
|
3183
|
-
AxiosError.from = (error, code, config, request, response, customProps) => {
|
|
3249
|
+
AxiosError$1.from = (error, code, config, request, response, customProps) => {
|
|
3184
3250
|
const axiosError = Object.create(prototype$1);
|
|
3185
3251
|
utils_default.toFlatObject(error, axiosError, function filter(obj) {
|
|
3186
3252
|
return obj !== Error.prototype;
|
|
3187
3253
|
}, (prop) => {
|
|
3188
3254
|
return prop !== "isAxiosError";
|
|
3189
3255
|
});
|
|
3190
|
-
AxiosError.call(axiosError, error.message, code, config, request, response);
|
|
3256
|
+
AxiosError$1.call(axiosError, error.message, code, config, request, response);
|
|
3191
3257
|
axiosError.cause = error;
|
|
3192
3258
|
axiosError.name = error.name;
|
|
3193
3259
|
customProps && Object.assign(axiosError, customProps);
|
|
3194
3260
|
return axiosError;
|
|
3195
3261
|
};
|
|
3196
|
-
var AxiosError_default = AxiosError;
|
|
3262
|
+
var AxiosError_default = AxiosError$1;
|
|
3197
3263
|
|
|
3198
3264
|
//#endregion
|
|
3199
3265
|
//#region ../../node_modules/delayed-stream/lib/delayed_stream.js
|
|
@@ -11920,7 +11986,7 @@ const predicates = utils_default.toFlatObject(utils_default, {}, null, function
|
|
|
11920
11986
|
*
|
|
11921
11987
|
* @returns
|
|
11922
11988
|
*/
|
|
11923
|
-
function toFormData(obj, formData, options) {
|
|
11989
|
+
function toFormData$1(obj, formData, options) {
|
|
11924
11990
|
if (!utils_default.isObject(obj)) throw new TypeError("target must be an object");
|
|
11925
11991
|
formData = formData || new (FormData_default || FormData)();
|
|
11926
11992
|
options = utils_default.toFlatObject(options, {
|
|
@@ -11991,7 +12057,7 @@ function toFormData(obj, formData, options) {
|
|
|
11991
12057
|
build(obj);
|
|
11992
12058
|
return formData;
|
|
11993
12059
|
}
|
|
11994
|
-
var toFormData_default = toFormData;
|
|
12060
|
+
var toFormData_default = toFormData$1;
|
|
11995
12061
|
|
|
11996
12062
|
//#endregion
|
|
11997
12063
|
//#region ../agent-provider/node_modules/axios/lib/helpers/AxiosURLSearchParams.js
|
|
@@ -12515,7 +12581,7 @@ function buildAccessors(obj, header) {
|
|
|
12515
12581
|
});
|
|
12516
12582
|
});
|
|
12517
12583
|
}
|
|
12518
|
-
var AxiosHeaders = class {
|
|
12584
|
+
var AxiosHeaders$1 = class {
|
|
12519
12585
|
constructor(headers) {
|
|
12520
12586
|
headers && this.set(headers);
|
|
12521
12587
|
}
|
|
@@ -12653,7 +12719,7 @@ var AxiosHeaders = class {
|
|
|
12653
12719
|
return this;
|
|
12654
12720
|
}
|
|
12655
12721
|
};
|
|
12656
|
-
AxiosHeaders.accessor([
|
|
12722
|
+
AxiosHeaders$1.accessor([
|
|
12657
12723
|
"Content-Type",
|
|
12658
12724
|
"Content-Length",
|
|
12659
12725
|
"Accept",
|
|
@@ -12661,7 +12727,7 @@ AxiosHeaders.accessor([
|
|
|
12661
12727
|
"User-Agent",
|
|
12662
12728
|
"Authorization"
|
|
12663
12729
|
]);
|
|
12664
|
-
utils_default.reduceDescriptors(AxiosHeaders.prototype, ({ value }, key) => {
|
|
12730
|
+
utils_default.reduceDescriptors(AxiosHeaders$1.prototype, ({ value }, key) => {
|
|
12665
12731
|
let mapped = key[0].toUpperCase() + key.slice(1);
|
|
12666
12732
|
return {
|
|
12667
12733
|
get: () => value,
|
|
@@ -12670,8 +12736,8 @@ utils_default.reduceDescriptors(AxiosHeaders.prototype, ({ value }, key) => {
|
|
|
12670
12736
|
}
|
|
12671
12737
|
};
|
|
12672
12738
|
});
|
|
12673
|
-
utils_default.freezeMethods(AxiosHeaders);
|
|
12674
|
-
var AxiosHeaders_default = AxiosHeaders;
|
|
12739
|
+
utils_default.freezeMethods(AxiosHeaders$1);
|
|
12740
|
+
var AxiosHeaders_default = AxiosHeaders$1;
|
|
12675
12741
|
|
|
12676
12742
|
//#endregion
|
|
12677
12743
|
//#region ../agent-provider/node_modules/axios/lib/core/transformData.js
|
|
@@ -12697,7 +12763,7 @@ function transformData(fns, response) {
|
|
|
12697
12763
|
|
|
12698
12764
|
//#endregion
|
|
12699
12765
|
//#region ../agent-provider/node_modules/axios/lib/cancel/isCancel.js
|
|
12700
|
-
function isCancel(value) {
|
|
12766
|
+
function isCancel$1(value) {
|
|
12701
12767
|
return !!(value && value.__CANCEL__);
|
|
12702
12768
|
}
|
|
12703
12769
|
|
|
@@ -12712,12 +12778,12 @@ function isCancel(value) {
|
|
|
12712
12778
|
*
|
|
12713
12779
|
* @returns {CanceledError} The created error.
|
|
12714
12780
|
*/
|
|
12715
|
-
function CanceledError(message, config, request) {
|
|
12781
|
+
function CanceledError$1(message, config, request) {
|
|
12716
12782
|
AxiosError_default.call(this, message == null ? "canceled" : message, AxiosError_default.ERR_CANCELED, config, request);
|
|
12717
12783
|
this.name = "CanceledError";
|
|
12718
12784
|
}
|
|
12719
|
-
utils_default.inherits(CanceledError, AxiosError_default, { __CANCEL__: true });
|
|
12720
|
-
var CanceledError_default = CanceledError;
|
|
12785
|
+
utils_default.inherits(CanceledError$1, AxiosError_default, { __CANCEL__: true });
|
|
12786
|
+
var CanceledError_default = CanceledError$1;
|
|
12721
12787
|
|
|
12722
12788
|
//#endregion
|
|
12723
12789
|
//#region ../agent-provider/node_modules/axios/lib/core/settle.js
|
|
@@ -14119,7 +14185,9 @@ var require_follow_redirects = /* @__PURE__ */ __commonJSMin(((exports, module)
|
|
|
14119
14185
|
|
|
14120
14186
|
//#endregion
|
|
14121
14187
|
//#region ../agent-provider/node_modules/axios/lib/env/data.js
|
|
14122
|
-
|
|
14188
|
+
var import_follow_redirects = /* @__PURE__ */ __toESM(require_follow_redirects(), 1);
|
|
14189
|
+
var import_proxy_from_env = /* @__PURE__ */ __toESM(require_proxy_from_env(), 1);
|
|
14190
|
+
const VERSION$1 = "1.10.0";
|
|
14123
14191
|
|
|
14124
14192
|
//#endregion
|
|
14125
14193
|
//#region ../agent-provider/node_modules/axios/lib/helpers/parseProtocol.js
|
|
@@ -14482,8 +14550,6 @@ const asyncDecorator = (fn) => (...args) => utils_default.asap(() => fn(...args)
|
|
|
14482
14550
|
|
|
14483
14551
|
//#endregion
|
|
14484
14552
|
//#region ../agent-provider/node_modules/axios/lib/adapters/http.js
|
|
14485
|
-
var import_proxy_from_env = /* @__PURE__ */ __toESM(require_proxy_from_env(), 1);
|
|
14486
|
-
var import_follow_redirects = /* @__PURE__ */ __toESM(require_follow_redirects(), 1);
|
|
14487
14553
|
const zlibOptions = {
|
|
14488
14554
|
flush: zlib.default.constants.Z_SYNC_FLUSH,
|
|
14489
14555
|
finishFlush: zlib.default.constants.Z_SYNC_FLUSH
|
|
@@ -14649,7 +14715,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
14649
14715
|
}
|
|
14650
14716
|
if (supportedProtocols.indexOf(protocol) === -1) return reject(new AxiosError_default("Unsupported protocol " + protocol, AxiosError_default.ERR_BAD_REQUEST, config));
|
|
14651
14717
|
const headers = AxiosHeaders_default.from(config.headers).normalize();
|
|
14652
|
-
headers.set("User-Agent", "axios/" + VERSION, false);
|
|
14718
|
+
headers.set("User-Agent", "axios/" + VERSION$1, false);
|
|
14653
14719
|
const { onUploadProgress, onDownloadProgress } = config;
|
|
14654
14720
|
const maxRate = config.maxRate;
|
|
14655
14721
|
let maxUploadRate = void 0;
|
|
@@ -14659,7 +14725,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
14659
14725
|
data = formDataToStream_default(data, (formHeaders) => {
|
|
14660
14726
|
headers.set(formHeaders);
|
|
14661
14727
|
}, {
|
|
14662
|
-
tag: `axios-${VERSION}-boundary`,
|
|
14728
|
+
tag: `axios-${VERSION$1}-boundary`,
|
|
14663
14729
|
boundary: userBoundary && userBoundary[1] || void 0
|
|
14664
14730
|
});
|
|
14665
14731
|
} else if (utils_default.isFormData(data) && utils_default.isFunction(data.getHeaders)) {
|
|
@@ -14924,7 +14990,7 @@ const headersToObject = (thing) => thing instanceof AxiosHeaders_default ? { ...
|
|
|
14924
14990
|
*
|
|
14925
14991
|
* @returns {Object} New object resulting from merging config2 to config1
|
|
14926
14992
|
*/
|
|
14927
|
-
function mergeConfig(config1, config2) {
|
|
14993
|
+
function mergeConfig$1(config1, config2) {
|
|
14928
14994
|
config2 = config2 || {};
|
|
14929
14995
|
const config = {};
|
|
14930
14996
|
function getMergedValue(target, source, prop, caseless) {
|
|
@@ -14990,7 +15056,7 @@ function mergeConfig(config1, config2) {
|
|
|
14990
15056
|
//#endregion
|
|
14991
15057
|
//#region ../agent-provider/node_modules/axios/lib/helpers/resolveConfig.js
|
|
14992
15058
|
var resolveConfig_default = (config) => {
|
|
14993
|
-
const newConfig = mergeConfig({}, config);
|
|
15059
|
+
const newConfig = mergeConfig$1({}, config);
|
|
14994
15060
|
let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;
|
|
14995
15061
|
newConfig.headers = headers = AxiosHeaders_default.from(headers);
|
|
14996
15062
|
newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);
|
|
@@ -15421,7 +15487,7 @@ function dispatchRequest(config) {
|
|
|
15421
15487
|
response.headers = AxiosHeaders_default.from(response.headers);
|
|
15422
15488
|
return response;
|
|
15423
15489
|
}, function onAdapterRejection(reason) {
|
|
15424
|
-
if (!isCancel(reason)) {
|
|
15490
|
+
if (!isCancel$1(reason)) {
|
|
15425
15491
|
throwIfCancellationRequested(config);
|
|
15426
15492
|
if (reason && reason.response) {
|
|
15427
15493
|
reason.response.data = transformData.call(config, config.transformResponse, reason.response);
|
|
@@ -15459,7 +15525,7 @@ const deprecatedWarnings = {};
|
|
|
15459
15525
|
*/
|
|
15460
15526
|
validators$1.transitional = function transitional(validator, version, message) {
|
|
15461
15527
|
function formatMessage(opt, desc) {
|
|
15462
|
-
return "[Axios v" + VERSION + "] Transitional option '" + opt + "'" + desc + (message ? ". " + message : "");
|
|
15528
|
+
return "[Axios v" + VERSION$1 + "] Transitional option '" + opt + "'" + desc + (message ? ". " + message : "");
|
|
15463
15529
|
}
|
|
15464
15530
|
return (value, opt, opts) => {
|
|
15465
15531
|
if (validator === false) throw new AxiosError_default(formatMessage(opt, " has been removed" + (version ? " in " + version : "")), AxiosError_default.ERR_DEPRECATED);
|
|
@@ -15516,7 +15582,7 @@ const validators = validator_default.validators;
|
|
|
15516
15582
|
*
|
|
15517
15583
|
* @return {Axios} A new instance of Axios
|
|
15518
15584
|
*/
|
|
15519
|
-
var Axios = class {
|
|
15585
|
+
var Axios$1 = class {
|
|
15520
15586
|
constructor(instanceConfig) {
|
|
15521
15587
|
this.defaults = instanceConfig || {};
|
|
15522
15588
|
this.interceptors = {
|
|
@@ -15553,7 +15619,7 @@ var Axios = class {
|
|
|
15553
15619
|
config = config || {};
|
|
15554
15620
|
config.url = configOrUrl;
|
|
15555
15621
|
} else config = configOrUrl || {};
|
|
15556
|
-
config = mergeConfig(this.defaults, config);
|
|
15622
|
+
config = mergeConfig$1(this.defaults, config);
|
|
15557
15623
|
const { transitional, paramsSerializer, headers } = config;
|
|
15558
15624
|
if (transitional !== void 0) validator_default.assertOptions(transitional, {
|
|
15559
15625
|
silentJSONParsing: validators.transitional(validators.boolean),
|
|
@@ -15632,7 +15698,7 @@ var Axios = class {
|
|
|
15632
15698
|
return promise;
|
|
15633
15699
|
}
|
|
15634
15700
|
getUri(config) {
|
|
15635
|
-
config = mergeConfig(this.defaults, config);
|
|
15701
|
+
config = mergeConfig$1(this.defaults, config);
|
|
15636
15702
|
return buildURL(buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls), config.params, config.paramsSerializer);
|
|
15637
15703
|
}
|
|
15638
15704
|
};
|
|
@@ -15642,8 +15708,8 @@ utils_default.forEach([
|
|
|
15642
15708
|
"head",
|
|
15643
15709
|
"options"
|
|
15644
15710
|
], function forEachMethodNoData(method) {
|
|
15645
|
-
Axios.prototype[method] = function(url, config) {
|
|
15646
|
-
return this.request(mergeConfig(config || {}, {
|
|
15711
|
+
Axios$1.prototype[method] = function(url, config) {
|
|
15712
|
+
return this.request(mergeConfig$1(config || {}, {
|
|
15647
15713
|
method,
|
|
15648
15714
|
url,
|
|
15649
15715
|
data: (config || {}).data
|
|
@@ -15657,7 +15723,7 @@ utils_default.forEach([
|
|
|
15657
15723
|
], function forEachMethodWithData(method) {
|
|
15658
15724
|
function generateHTTPMethod(isForm) {
|
|
15659
15725
|
return function httpMethod(url, data, config) {
|
|
15660
|
-
return this.request(mergeConfig(config || {}, {
|
|
15726
|
+
return this.request(mergeConfig$1(config || {}, {
|
|
15661
15727
|
method,
|
|
15662
15728
|
headers: isForm ? { "Content-Type": "multipart/form-data" } : {},
|
|
15663
15729
|
url,
|
|
@@ -15665,10 +15731,10 @@ utils_default.forEach([
|
|
|
15665
15731
|
}));
|
|
15666
15732
|
};
|
|
15667
15733
|
}
|
|
15668
|
-
Axios.prototype[method] = generateHTTPMethod();
|
|
15669
|
-
Axios.prototype[method + "Form"] = generateHTTPMethod(true);
|
|
15734
|
+
Axios$1.prototype[method] = generateHTTPMethod();
|
|
15735
|
+
Axios$1.prototype[method + "Form"] = generateHTTPMethod(true);
|
|
15670
15736
|
});
|
|
15671
|
-
var Axios_default = Axios;
|
|
15737
|
+
var Axios_default = Axios$1;
|
|
15672
15738
|
|
|
15673
15739
|
//#endregion
|
|
15674
15740
|
//#region ../agent-provider/node_modules/axios/lib/cancel/CancelToken.js
|
|
@@ -15679,7 +15745,7 @@ var Axios_default = Axios;
|
|
|
15679
15745
|
*
|
|
15680
15746
|
* @returns {CancelToken}
|
|
15681
15747
|
*/
|
|
15682
|
-
var CancelToken = class CancelToken {
|
|
15748
|
+
var CancelToken$1 = class CancelToken$1 {
|
|
15683
15749
|
constructor(executor) {
|
|
15684
15750
|
if (typeof executor !== "function") throw new TypeError("executor must be a function.");
|
|
15685
15751
|
let resolvePromise;
|
|
@@ -15751,14 +15817,14 @@ var CancelToken = class CancelToken {
|
|
|
15751
15817
|
static source() {
|
|
15752
15818
|
let cancel;
|
|
15753
15819
|
return {
|
|
15754
|
-
token: new CancelToken(function executor(c) {
|
|
15820
|
+
token: new CancelToken$1(function executor(c) {
|
|
15755
15821
|
cancel = c;
|
|
15756
15822
|
}),
|
|
15757
15823
|
cancel
|
|
15758
15824
|
};
|
|
15759
15825
|
}
|
|
15760
15826
|
};
|
|
15761
|
-
var CancelToken_default = CancelToken;
|
|
15827
|
+
var CancelToken_default = CancelToken$1;
|
|
15762
15828
|
|
|
15763
15829
|
//#endregion
|
|
15764
15830
|
//#region ../agent-provider/node_modules/axios/lib/helpers/spread.js
|
|
@@ -15783,7 +15849,7 @@ var CancelToken_default = CancelToken;
|
|
|
15783
15849
|
*
|
|
15784
15850
|
* @returns {Function}
|
|
15785
15851
|
*/
|
|
15786
|
-
function spread(callback) {
|
|
15852
|
+
function spread$1(callback) {
|
|
15787
15853
|
return function wrap(arr) {
|
|
15788
15854
|
return callback.apply(null, arr);
|
|
15789
15855
|
};
|
|
@@ -15798,13 +15864,13 @@ function spread(callback) {
|
|
|
15798
15864
|
*
|
|
15799
15865
|
* @returns {boolean} True if the payload is an error thrown by Axios, otherwise false
|
|
15800
15866
|
*/
|
|
15801
|
-
function isAxiosError(payload) {
|
|
15867
|
+
function isAxiosError$1(payload) {
|
|
15802
15868
|
return utils_default.isObject(payload) && payload.isAxiosError === true;
|
|
15803
15869
|
}
|
|
15804
15870
|
|
|
15805
15871
|
//#endregion
|
|
15806
15872
|
//#region ../agent-provider/node_modules/axios/lib/helpers/HttpStatusCode.js
|
|
15807
|
-
const HttpStatusCode = {
|
|
15873
|
+
const HttpStatusCode$1 = {
|
|
15808
15874
|
Continue: 100,
|
|
15809
15875
|
SwitchingProtocols: 101,
|
|
15810
15876
|
Processing: 102,
|
|
@@ -15869,10 +15935,10 @@ const HttpStatusCode = {
|
|
|
15869
15935
|
NotExtended: 510,
|
|
15870
15936
|
NetworkAuthenticationRequired: 511
|
|
15871
15937
|
};
|
|
15872
|
-
Object.entries(HttpStatusCode).forEach(([key, value]) => {
|
|
15873
|
-
HttpStatusCode[value] = key;
|
|
15938
|
+
Object.entries(HttpStatusCode$1).forEach(([key, value]) => {
|
|
15939
|
+
HttpStatusCode$1[value] = key;
|
|
15874
15940
|
});
|
|
15875
|
-
var HttpStatusCode_default = HttpStatusCode;
|
|
15941
|
+
var HttpStatusCode_default = HttpStatusCode$1;
|
|
15876
15942
|
|
|
15877
15943
|
//#endregion
|
|
15878
15944
|
//#region ../agent-provider/node_modules/axios/lib/axios.js
|
|
@@ -15889,7 +15955,7 @@ function createInstance(defaultConfig) {
|
|
|
15889
15955
|
utils_default.extend(instance, Axios_default.prototype, context, { allOwnKeys: true });
|
|
15890
15956
|
utils_default.extend(instance, context, null, { allOwnKeys: true });
|
|
15891
15957
|
instance.create = function create(instanceConfig) {
|
|
15892
|
-
return createInstance(mergeConfig(defaultConfig, instanceConfig));
|
|
15958
|
+
return createInstance(mergeConfig$1(defaultConfig, instanceConfig));
|
|
15893
15959
|
};
|
|
15894
15960
|
return instance;
|
|
15895
15961
|
}
|
|
@@ -15897,17 +15963,17 @@ const axios = createInstance(defaults_default);
|
|
|
15897
15963
|
axios.Axios = Axios_default;
|
|
15898
15964
|
axios.CanceledError = CanceledError_default;
|
|
15899
15965
|
axios.CancelToken = CancelToken_default;
|
|
15900
|
-
axios.isCancel = isCancel;
|
|
15901
|
-
axios.VERSION = VERSION;
|
|
15966
|
+
axios.isCancel = isCancel$1;
|
|
15967
|
+
axios.VERSION = VERSION$1;
|
|
15902
15968
|
axios.toFormData = toFormData_default;
|
|
15903
15969
|
axios.AxiosError = AxiosError_default;
|
|
15904
15970
|
axios.Cancel = axios.CanceledError;
|
|
15905
15971
|
axios.all = function all(promises) {
|
|
15906
15972
|
return Promise.all(promises);
|
|
15907
15973
|
};
|
|
15908
|
-
axios.spread = spread;
|
|
15909
|
-
axios.isAxiosError = isAxiosError;
|
|
15910
|
-
axios.mergeConfig = mergeConfig;
|
|
15974
|
+
axios.spread = spread$1;
|
|
15975
|
+
axios.isAxiosError = isAxiosError$1;
|
|
15976
|
+
axios.mergeConfig = mergeConfig$1;
|
|
15911
15977
|
axios.AxiosHeaders = AxiosHeaders_default;
|
|
15912
15978
|
axios.formToJSON = (thing) => formDataToJSON_default(utils_default.isHTMLForm(thing) ? new FormData(thing) : thing);
|
|
15913
15979
|
axios.getAdapter = adapters_default.getAdapter;
|
|
@@ -15915,6 +15981,10 @@ axios.HttpStatusCode = HttpStatusCode_default;
|
|
|
15915
15981
|
axios.default = axios;
|
|
15916
15982
|
var axios_default = axios;
|
|
15917
15983
|
|
|
15984
|
+
//#endregion
|
|
15985
|
+
//#region ../agent-provider/node_modules/axios/index.js
|
|
15986
|
+
const { Axios, AxiosError, CanceledError, isCancel, CancelToken, VERSION, all, Cancel, isAxiosError, spread, toFormData, AxiosHeaders, HttpStatusCode, formToJSON, getAdapter, mergeConfig } = axios_default;
|
|
15987
|
+
|
|
15918
15988
|
//#endregion
|
|
15919
15989
|
//#region ../agent-provider/src/http/http-service.ts
|
|
15920
15990
|
/**
|
|
@@ -15923,7 +15993,7 @@ var axios_default = axios;
|
|
|
15923
15993
|
* 特性:
|
|
15924
15994
|
* - 单例模式,全局唯一实例,延迟初始化(首次使用时自动创建)
|
|
15925
15995
|
* - 支持拦截器注册(其他模块可注入 header)
|
|
15926
|
-
* - 统一 401
|
|
15996
|
+
* - 统一 401 处理(支持自动刷新 token 并重试)
|
|
15927
15997
|
* - 自动携带凭证(withCredentials)
|
|
15928
15998
|
* - 类型安全
|
|
15929
15999
|
*
|
|
@@ -15963,6 +16033,8 @@ var HttpService = class HttpService {
|
|
|
15963
16033
|
*/
|
|
15964
16034
|
constructor(config = {}) {
|
|
15965
16035
|
this.unauthorizedCallbacks = /* @__PURE__ */ new Set();
|
|
16036
|
+
this.isRefreshing = false;
|
|
16037
|
+
this.refreshSubscribers = [];
|
|
15966
16038
|
this.config = config;
|
|
15967
16039
|
this.axiosInstance = axios_default.create({
|
|
15968
16040
|
baseURL: config.baseURL?.replace(/\/$/, "") || "",
|
|
@@ -16003,18 +16075,54 @@ var HttpService = class HttpService {
|
|
|
16003
16075
|
}, (error) => Promise.reject(error));
|
|
16004
16076
|
}
|
|
16005
16077
|
/**
|
|
16006
|
-
* 注册默认响应拦截器(处理 401
|
|
16078
|
+
* 注册默认响应拦截器(处理 401,支持自动重试)
|
|
16007
16079
|
*/
|
|
16008
16080
|
registerDefaultResponseInterceptor() {
|
|
16009
|
-
this.axiosInstance.interceptors.response.use((response) => response, (error) => {
|
|
16010
|
-
|
|
16011
|
-
|
|
16012
|
-
|
|
16081
|
+
this.axiosInstance.interceptors.response.use((response) => response, async (error) => {
|
|
16082
|
+
const originalRequest = error.config;
|
|
16083
|
+
if (error.response?.status === 401 && originalRequest && !originalRequest._retry) {
|
|
16084
|
+
if (originalRequest.url?.includes("/console/accounts")) {
|
|
16085
|
+
console.warn("[HttpService] Unauthorized 401 on refresh endpoint, not retrying");
|
|
16086
|
+
return Promise.reject(error);
|
|
16087
|
+
}
|
|
16088
|
+
console.warn("[HttpService] Unauthorized 401, attempting token refresh and retry");
|
|
16089
|
+
originalRequest._retry = true;
|
|
16090
|
+
if (this.isRefreshing) return new Promise((resolve, reject) => {
|
|
16091
|
+
this.refreshSubscribers.push((success) => {
|
|
16092
|
+
if (success) this.axiosInstance.request(originalRequest).then(resolve).catch(reject);
|
|
16093
|
+
else reject(error);
|
|
16094
|
+
});
|
|
16095
|
+
});
|
|
16096
|
+
this.isRefreshing = true;
|
|
16097
|
+
try {
|
|
16098
|
+
await this.triggerUnauthorizedCallbacks();
|
|
16099
|
+
this.onRefreshSuccess();
|
|
16100
|
+
return this.axiosInstance.request(originalRequest);
|
|
16101
|
+
} catch (refreshError) {
|
|
16102
|
+
this.onRefreshFailure();
|
|
16103
|
+
return Promise.reject(error);
|
|
16104
|
+
} finally {
|
|
16105
|
+
this.isRefreshing = false;
|
|
16106
|
+
}
|
|
16013
16107
|
}
|
|
16014
16108
|
return Promise.reject(error);
|
|
16015
16109
|
});
|
|
16016
16110
|
}
|
|
16017
16111
|
/**
|
|
16112
|
+
* token 刷新成功,通知所有等待的请求
|
|
16113
|
+
*/
|
|
16114
|
+
onRefreshSuccess() {
|
|
16115
|
+
this.refreshSubscribers.forEach((callback) => callback(true));
|
|
16116
|
+
this.refreshSubscribers = [];
|
|
16117
|
+
}
|
|
16118
|
+
/**
|
|
16119
|
+
* token 刷新失败,通知所有等待的请求
|
|
16120
|
+
*/
|
|
16121
|
+
onRefreshFailure() {
|
|
16122
|
+
this.refreshSubscribers.forEach((callback) => callback(false));
|
|
16123
|
+
this.refreshSubscribers = [];
|
|
16124
|
+
}
|
|
16125
|
+
/**
|
|
16018
16126
|
* 注册请求拦截器
|
|
16019
16127
|
* @param onFulfilled 请求成功拦截器
|
|
16020
16128
|
* @param onRejected 请求失败拦截器
|
|
@@ -16091,16 +16199,18 @@ var HttpService = class HttpService {
|
|
|
16091
16199
|
this.unauthorizedCallbacks.delete(callback);
|
|
16092
16200
|
}
|
|
16093
16201
|
/**
|
|
16094
|
-
* 触发所有 401
|
|
16202
|
+
* 触发所有 401 回调并等待完成
|
|
16203
|
+
* @returns Promise,等待所有回调完成
|
|
16204
|
+
* @throws 如果任何回调失败,则抛出错误
|
|
16095
16205
|
*/
|
|
16096
|
-
triggerUnauthorizedCallbacks() {
|
|
16097
|
-
this.unauthorizedCallbacks
|
|
16098
|
-
|
|
16099
|
-
|
|
16100
|
-
|
|
16101
|
-
|
|
16102
|
-
|
|
16103
|
-
}
|
|
16206
|
+
async triggerUnauthorizedCallbacks() {
|
|
16207
|
+
const callbacks = Array.from(this.unauthorizedCallbacks);
|
|
16208
|
+
const failedResults = (await Promise.allSettled(callbacks.map((callback) => callback()))).filter((r) => r.status === "rejected");
|
|
16209
|
+
if (failedResults.length > 0) {
|
|
16210
|
+
const errors = failedResults.map((r) => r.reason);
|
|
16211
|
+
console.error("[HttpService] Some unauthorized callbacks failed:", errors);
|
|
16212
|
+
throw errors[0];
|
|
16213
|
+
}
|
|
16104
16214
|
}
|
|
16105
16215
|
/**
|
|
16106
16216
|
* 更新 authToken
|
|
@@ -16166,6 +16276,14 @@ var HttpService = class HttpService {
|
|
|
16166
16276
|
return (await this.axiosInstance.put(url, data, config)).data;
|
|
16167
16277
|
}
|
|
16168
16278
|
/**
|
|
16279
|
+
* 通用请求方法
|
|
16280
|
+
* @param config axios 请求配置
|
|
16281
|
+
* @returns 原始 AxiosResponse
|
|
16282
|
+
*/
|
|
16283
|
+
async request(config) {
|
|
16284
|
+
return this.axiosInstance.request(config);
|
|
16285
|
+
}
|
|
16286
|
+
/**
|
|
16169
16287
|
* 获取原始 axios 实例(用于高级场景)
|
|
16170
16288
|
*/
|
|
16171
16289
|
getAxiosInstance() {
|
|
@@ -16359,6 +16477,109 @@ const accountService = new AccountService();
|
|
|
16359
16477
|
*/
|
|
16360
16478
|
if (typeof window !== "undefined") window.__genieAccountService = accountService;
|
|
16361
16479
|
|
|
16480
|
+
//#endregion
|
|
16481
|
+
//#region ../agent-provider/src/common/utils/lru-cache.ts
|
|
16482
|
+
/**
|
|
16483
|
+
* LRU (Least Recently Used) Cache
|
|
16484
|
+
* 当缓存达到容量上限时,自动淘汰最久未使用的数据
|
|
16485
|
+
*
|
|
16486
|
+
* @template K - Key 类型
|
|
16487
|
+
* @template V - Value 类型
|
|
16488
|
+
*/
|
|
16489
|
+
var LRUCache = class {
|
|
16490
|
+
/**
|
|
16491
|
+
* 创建 LRU 缓存实例
|
|
16492
|
+
* @param capacity - 缓存容量上限
|
|
16493
|
+
*/
|
|
16494
|
+
constructor(capacity) {
|
|
16495
|
+
if (capacity <= 0) throw new Error("Cache capacity must be greater than 0");
|
|
16496
|
+
this.capacity = capacity;
|
|
16497
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
16498
|
+
}
|
|
16499
|
+
/**
|
|
16500
|
+
* 获取缓存值
|
|
16501
|
+
* @param key - 键
|
|
16502
|
+
* @returns 值,如果不存在返回 undefined
|
|
16503
|
+
*/
|
|
16504
|
+
get(key) {
|
|
16505
|
+
if (!this.cache.has(key)) return;
|
|
16506
|
+
const value = this.cache.get(key);
|
|
16507
|
+
this.cache.delete(key);
|
|
16508
|
+
this.cache.set(key, value);
|
|
16509
|
+
return value;
|
|
16510
|
+
}
|
|
16511
|
+
/**
|
|
16512
|
+
* 设置缓存值
|
|
16513
|
+
* @param key - 键
|
|
16514
|
+
* @param value - 值
|
|
16515
|
+
*/
|
|
16516
|
+
set(key, value) {
|
|
16517
|
+
if (this.cache.has(key)) this.cache.delete(key);
|
|
16518
|
+
else if (this.cache.size >= this.capacity) {
|
|
16519
|
+
const firstKey = this.cache.keys().next().value;
|
|
16520
|
+
this.cache.delete(firstKey);
|
|
16521
|
+
}
|
|
16522
|
+
this.cache.set(key, value);
|
|
16523
|
+
}
|
|
16524
|
+
/**
|
|
16525
|
+
* 检查 key 是否存在
|
|
16526
|
+
* @param key - 键
|
|
16527
|
+
* @returns 是否存在
|
|
16528
|
+
*/
|
|
16529
|
+
has(key) {
|
|
16530
|
+
return this.cache.has(key);
|
|
16531
|
+
}
|
|
16532
|
+
/**
|
|
16533
|
+
* 删除指定 key
|
|
16534
|
+
* @param key - 键
|
|
16535
|
+
* @returns 是否删除成功
|
|
16536
|
+
*/
|
|
16537
|
+
delete(key) {
|
|
16538
|
+
return this.cache.delete(key);
|
|
16539
|
+
}
|
|
16540
|
+
/**
|
|
16541
|
+
* 清空缓存
|
|
16542
|
+
*/
|
|
16543
|
+
clear() {
|
|
16544
|
+
this.cache.clear();
|
|
16545
|
+
}
|
|
16546
|
+
/**
|
|
16547
|
+
* 获取当前缓存大小
|
|
16548
|
+
* @returns 当前缓存的元素数量
|
|
16549
|
+
*/
|
|
16550
|
+
get size() {
|
|
16551
|
+
return this.cache.size;
|
|
16552
|
+
}
|
|
16553
|
+
/**
|
|
16554
|
+
* 获取缓存容量
|
|
16555
|
+
* @returns 缓存容量上限
|
|
16556
|
+
*/
|
|
16557
|
+
get maxSize() {
|
|
16558
|
+
return this.capacity;
|
|
16559
|
+
}
|
|
16560
|
+
/**
|
|
16561
|
+
* 获取所有 key
|
|
16562
|
+
* @returns key 数组
|
|
16563
|
+
*/
|
|
16564
|
+
keys() {
|
|
16565
|
+
return Array.from(this.cache.keys());
|
|
16566
|
+
}
|
|
16567
|
+
/**
|
|
16568
|
+
* 获取所有 value
|
|
16569
|
+
* @returns value 数组
|
|
16570
|
+
*/
|
|
16571
|
+
values() {
|
|
16572
|
+
return Array.from(this.cache.values());
|
|
16573
|
+
}
|
|
16574
|
+
/**
|
|
16575
|
+
* 遍历缓存
|
|
16576
|
+
* @param callback - 回调函数
|
|
16577
|
+
*/
|
|
16578
|
+
forEach(callback) {
|
|
16579
|
+
this.cache.forEach((value, key) => callback(value, key));
|
|
16580
|
+
}
|
|
16581
|
+
};
|
|
16582
|
+
|
|
16362
16583
|
//#endregion
|
|
16363
16584
|
//#region ../agent-provider/src/common/utils/concurrency.ts
|
|
16364
16585
|
/**
|
|
@@ -16460,20 +16681,32 @@ var CosUploadService = class {
|
|
|
16460
16681
|
* 上传单个文件到 COS
|
|
16461
16682
|
*
|
|
16462
16683
|
* @param file - 要上传的文件
|
|
16684
|
+
* @param abortSignal - 可选的 AbortSignal,用于取消上传
|
|
16463
16685
|
* @returns 上传结果,包含访问 URL 或错误信息
|
|
16464
16686
|
*/
|
|
16465
|
-
async uploadFile(file) {
|
|
16687
|
+
async uploadFile(file, abortSignal) {
|
|
16466
16688
|
const filename = file.name;
|
|
16467
16689
|
this.logger?.info(`[CosUploadService] Uploading file: ${filename}`);
|
|
16468
16690
|
try {
|
|
16691
|
+
if (abortSignal?.aborted) return {
|
|
16692
|
+
success: false,
|
|
16693
|
+
error: "Upload cancelled",
|
|
16694
|
+
aborted: true
|
|
16695
|
+
};
|
|
16469
16696
|
const objectKey = this.generateObjectKey(filename);
|
|
16470
16697
|
this.logger?.debug(`[CosUploadService] Generated objectKey: ${objectKey}`);
|
|
16471
16698
|
const presignedItem = (await this.getPresignedUrls([objectKey])).items[0];
|
|
16472
16699
|
if (!presignedItem) throw new Error("No presigned URL item returned");
|
|
16700
|
+
if (abortSignal?.aborted) return {
|
|
16701
|
+
success: false,
|
|
16702
|
+
error: "Upload cancelled",
|
|
16703
|
+
aborted: true
|
|
16704
|
+
};
|
|
16473
16705
|
const uploadResponse = await fetch(presignedItem.upload_url, {
|
|
16474
16706
|
method: "PUT",
|
|
16475
16707
|
body: file,
|
|
16476
|
-
headers: { "Content-Type": file.type || "application/octet-stream" }
|
|
16708
|
+
headers: { "Content-Type": file.type || "application/octet-stream" },
|
|
16709
|
+
signal: abortSignal
|
|
16477
16710
|
});
|
|
16478
16711
|
if (!uploadResponse.ok) {
|
|
16479
16712
|
const errorText = await uploadResponse.text().catch(() => uploadResponse.statusText);
|
|
@@ -16487,6 +16720,11 @@ var CosUploadService = class {
|
|
|
16487
16720
|
objectKey
|
|
16488
16721
|
};
|
|
16489
16722
|
} catch (error) {
|
|
16723
|
+
if (error instanceof Error && error.name === "AbortError") return {
|
|
16724
|
+
success: false,
|
|
16725
|
+
error: "Upload cancelled",
|
|
16726
|
+
aborted: true
|
|
16727
|
+
};
|
|
16490
16728
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
16491
16729
|
this.logger?.error(`[CosUploadService] Upload failed: ${filename}`, error);
|
|
16492
16730
|
return {
|
|
@@ -16501,14 +16739,25 @@ var CosUploadService = class {
|
|
|
16501
16739
|
* 使用并发控制,限制同时上传的文件数量
|
|
16502
16740
|
*
|
|
16503
16741
|
* @param files - 要上传的文件数组
|
|
16742
|
+
* @param abortSignal - 可选的 AbortSignal,用于取消上传
|
|
16504
16743
|
* @returns 所有文件的上传结果
|
|
16505
16744
|
*/
|
|
16506
|
-
async uploadFiles(files) {
|
|
16745
|
+
async uploadFiles(files, abortSignal) {
|
|
16507
16746
|
if (files.length === 0) return {
|
|
16508
16747
|
success: true,
|
|
16509
16748
|
urls: [],
|
|
16510
16749
|
results: []
|
|
16511
16750
|
};
|
|
16751
|
+
if (abortSignal?.aborted) return {
|
|
16752
|
+
success: false,
|
|
16753
|
+
error: "Upload cancelled",
|
|
16754
|
+
aborted: true,
|
|
16755
|
+
results: files.map(() => ({
|
|
16756
|
+
success: false,
|
|
16757
|
+
error: "Upload cancelled",
|
|
16758
|
+
aborted: true
|
|
16759
|
+
}))
|
|
16760
|
+
};
|
|
16512
16761
|
this.logger?.info(`[CosUploadService] Uploading ${files.length} file(s) with concurrency ${this.uploadConcurrency}`);
|
|
16513
16762
|
try {
|
|
16514
16763
|
const fileInfos = files.map((file) => ({
|
|
@@ -16520,6 +16769,12 @@ var CosUploadService = class {
|
|
|
16520
16769
|
this.logger?.debug(`[CosUploadService] Got ${presignedResponse.items.length} presigned URLs`);
|
|
16521
16770
|
if (presignedResponse.items.length !== fileInfos.length) throw new Error(`Expected ${fileInfos.length} presigned URLs, got ${presignedResponse.items.length}`);
|
|
16522
16771
|
const results = (await runWithConcurrencySettled(fileInfos.map(({ file }, index) => async () => {
|
|
16772
|
+
if (abortSignal?.aborted) return {
|
|
16773
|
+
success: false,
|
|
16774
|
+
error: "Upload cancelled",
|
|
16775
|
+
aborted: true,
|
|
16776
|
+
objectKey: fileInfos[index].objectKey
|
|
16777
|
+
};
|
|
16523
16778
|
const presignedItem = presignedResponse.items[index];
|
|
16524
16779
|
if (!presignedItem) return {
|
|
16525
16780
|
success: false,
|
|
@@ -16530,7 +16785,8 @@ var CosUploadService = class {
|
|
|
16530
16785
|
const uploadResponse = await fetch(presignedItem.upload_url, {
|
|
16531
16786
|
method: "PUT",
|
|
16532
16787
|
body: file,
|
|
16533
|
-
headers: { "Content-Type": file.type || "application/octet-stream" }
|
|
16788
|
+
headers: { "Content-Type": file.type || "application/octet-stream" },
|
|
16789
|
+
signal: abortSignal
|
|
16534
16790
|
});
|
|
16535
16791
|
if (!uploadResponse.ok) {
|
|
16536
16792
|
const errorText = await uploadResponse.text().catch(() => uploadResponse.statusText);
|
|
@@ -16547,6 +16803,12 @@ var CosUploadService = class {
|
|
|
16547
16803
|
objectKey: presignedItem.object_key
|
|
16548
16804
|
};
|
|
16549
16805
|
} catch (error) {
|
|
16806
|
+
if (error instanceof Error && error.name === "AbortError") return {
|
|
16807
|
+
success: false,
|
|
16808
|
+
error: "Upload cancelled",
|
|
16809
|
+
aborted: true,
|
|
16810
|
+
objectKey: presignedItem.object_key
|
|
16811
|
+
};
|
|
16550
16812
|
return {
|
|
16551
16813
|
success: false,
|
|
16552
16814
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
@@ -16594,91 +16856,6 @@ var CosUploadService = class {
|
|
|
16594
16856
|
}
|
|
16595
16857
|
};
|
|
16596
16858
|
|
|
16597
|
-
//#endregion
|
|
16598
|
-
//#region ../agent-provider/src/common/providers/cloud-agent-provider/e2b-filesystem.ts
|
|
16599
|
-
/**
|
|
16600
|
-
* E2B Filesystem Implementation
|
|
16601
|
-
*
|
|
16602
|
-
* Provides FilesResource implementation using E2B Sandbox SDK.
|
|
16603
|
-
* Directly uses e2b SDK types.
|
|
16604
|
-
*
|
|
16605
|
-
* @see https://e2b.dev/docs/filesystem/read-write
|
|
16606
|
-
* @see https://e2b.dev/docs/filesystem/watch
|
|
16607
|
-
*/
|
|
16608
|
-
/**
|
|
16609
|
-
* E2B Filesystem Implementation
|
|
16610
|
-
*
|
|
16611
|
-
* Wraps E2B Sandbox SDK's filesystem operations to implement FilesResource interface.
|
|
16612
|
-
*
|
|
16613
|
-
* @example
|
|
16614
|
-
* ```typescript
|
|
16615
|
-
* const fs = await E2BFilesystem.connect({
|
|
16616
|
-
* sandboxId: 'sandbox-123',
|
|
16617
|
-
* apiKey: 'e2b_xxx'
|
|
16618
|
-
* });
|
|
16619
|
-
*
|
|
16620
|
-
* // Read/write files
|
|
16621
|
-
* await fs.write('/test.txt', 'Hello World');
|
|
16622
|
-
* const content = await fs.read('/test.txt');
|
|
16623
|
-
*
|
|
16624
|
-
* // Watch for changes
|
|
16625
|
-
* const handle = await fs.watchDir('/workspace', (event) => {
|
|
16626
|
-
* console.log('File changed:', event);
|
|
16627
|
-
* });
|
|
16628
|
-
* ```
|
|
16629
|
-
*/
|
|
16630
|
-
var E2BFilesystem = class E2BFilesystem {
|
|
16631
|
-
constructor(sandbox) {
|
|
16632
|
-
this.sandbox = sandbox;
|
|
16633
|
-
}
|
|
16634
|
-
/**
|
|
16635
|
-
* Connect to an E2B Sandbox and create filesystem instance
|
|
16636
|
-
*/
|
|
16637
|
-
static async connect(info) {
|
|
16638
|
-
return new E2BFilesystem(await e2b.Sandbox.connect(info.sandboxId, {
|
|
16639
|
-
domain: info.domain,
|
|
16640
|
-
apiUrl: info.apiUrl,
|
|
16641
|
-
requestTimeoutMs: info.requestTimeoutMs,
|
|
16642
|
-
debug: info.debug,
|
|
16643
|
-
headers: info.headers
|
|
16644
|
-
}));
|
|
16645
|
-
}
|
|
16646
|
-
/**
|
|
16647
|
-
* Get the underlying E2B Sandbox instance
|
|
16648
|
-
*/
|
|
16649
|
-
getSandbox() {
|
|
16650
|
-
return this.sandbox;
|
|
16651
|
-
}
|
|
16652
|
-
read(path, opts) {
|
|
16653
|
-
return this.sandbox.files.read(path, opts);
|
|
16654
|
-
}
|
|
16655
|
-
write(pathOrFiles, dataOrOpts, opts) {
|
|
16656
|
-
if (Array.isArray(pathOrFiles)) return this.sandbox.files.write(pathOrFiles, dataOrOpts);
|
|
16657
|
-
return this.sandbox.files.write(pathOrFiles, dataOrOpts, opts);
|
|
16658
|
-
}
|
|
16659
|
-
async list(path, opts) {
|
|
16660
|
-
return this.sandbox.files.list(path, opts);
|
|
16661
|
-
}
|
|
16662
|
-
async exists(path, opts) {
|
|
16663
|
-
return this.sandbox.files.exists(path, opts);
|
|
16664
|
-
}
|
|
16665
|
-
async makeDir(path, opts) {
|
|
16666
|
-
return this.sandbox.files.makeDir(path, opts);
|
|
16667
|
-
}
|
|
16668
|
-
async remove(path, opts) {
|
|
16669
|
-
return this.sandbox.files.remove(path, opts);
|
|
16670
|
-
}
|
|
16671
|
-
async rename(oldPath, newPath, opts) {
|
|
16672
|
-
return this.sandbox.files.rename(oldPath, newPath, opts);
|
|
16673
|
-
}
|
|
16674
|
-
async getInfo(path, opts) {
|
|
16675
|
-
return this.sandbox.files.getInfo(path, opts);
|
|
16676
|
-
}
|
|
16677
|
-
async watchDir(path, onEvent, opts) {
|
|
16678
|
-
return this.sandbox.files.watchDir(path, onEvent, opts);
|
|
16679
|
-
}
|
|
16680
|
-
};
|
|
16681
|
-
|
|
16682
16859
|
//#endregion
|
|
16683
16860
|
//#region ../agent-provider/src/common/providers/cloud-agent-provider/cloud-provider.ts
|
|
16684
16861
|
/**
|
|
@@ -16827,8 +17004,11 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
16827
17004
|
this.filesystemCache = /* @__PURE__ */ new Map();
|
|
16828
17005
|
this.connectionCache = /* @__PURE__ */ new Map();
|
|
16829
17006
|
this.eventListeners = /* @__PURE__ */ new Map();
|
|
17007
|
+
this.productConfigCache = null;
|
|
16830
17008
|
this.options = options;
|
|
16831
17009
|
this.logger = options.logger;
|
|
17010
|
+
this.marketplaceCache = new LRUCache(200);
|
|
17011
|
+
this.pluginCache = new LRUCache(2e3);
|
|
16832
17012
|
if (options.endpoint) httpService.setBaseURL(options.endpoint);
|
|
16833
17013
|
if (options.authToken) httpService.setAuthToken(options.authToken);
|
|
16834
17014
|
if (options.headers && Object.keys(options.headers).length > 0) this.requestInterceptorId = httpService.registerRequestInterceptor((config) => {
|
|
@@ -16879,7 +17059,19 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
16879
17059
|
const cached = this.filesystemCache.get(agentId);
|
|
16880
17060
|
if (cached) return cached;
|
|
16881
17061
|
const info = await this.getSandboxInfo(agentId);
|
|
16882
|
-
|
|
17062
|
+
let e2bFilesystem;
|
|
17063
|
+
if (this.options.filesystemFactory) e2bFilesystem = await this.options.filesystemFactory(info);
|
|
17064
|
+
else {
|
|
17065
|
+
const { E2BFilesystem } = await Promise.resolve().then(() => require("./e2b-filesystem-Cac-bpRR.cjs"));
|
|
17066
|
+
e2bFilesystem = await E2BFilesystem.connect(info);
|
|
17067
|
+
}
|
|
17068
|
+
if (e2bFilesystem.setReconnectFn) e2bFilesystem.setReconnectFn(async () => {
|
|
17069
|
+
this.logger?.debug(`Reconnecting E2B sandbox for agent: ${agentId}`);
|
|
17070
|
+
const newInfo = await this.getSandboxInfo(agentId);
|
|
17071
|
+
this.logger?.debug(`E2B sandbox reconnected for agent: ${agentId}`);
|
|
17072
|
+
return newInfo;
|
|
17073
|
+
});
|
|
17074
|
+
const filesystem = createAgentFilesystem(e2bFilesystem);
|
|
16883
17075
|
this.filesystemCache.set(agentId, filesystem);
|
|
16884
17076
|
this.logger?.debug(`Created filesystem for agent: ${agentId}`);
|
|
16885
17077
|
return filesystem;
|
|
@@ -16947,15 +17139,9 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
16947
17139
|
const url = this.buildGetUrl("/console/as/conversations/", params);
|
|
16948
17140
|
const apiResponse = await httpService.get(url);
|
|
16949
17141
|
if (!apiResponse.data) throw new Error("No data in API response");
|
|
16950
|
-
const agents = apiResponse.data.conversations.map((a) => this.toAgentState(a));
|
|
16951
|
-
const pagination = apiResponse.data.pagination;
|
|
16952
|
-
console.log("[CloudAgentProvider] API response:", {
|
|
16953
|
-
agentsCount: agents.length,
|
|
16954
|
-
pagination
|
|
16955
|
-
});
|
|
16956
17142
|
return {
|
|
16957
|
-
agents,
|
|
16958
|
-
pagination
|
|
17143
|
+
agents: apiResponse.data.conversations.map((a) => this.toAgentState(a)),
|
|
17144
|
+
pagination: apiResponse.data.pagination
|
|
16959
17145
|
};
|
|
16960
17146
|
} catch (error) {
|
|
16961
17147
|
this.logger?.error("Failed to list agents:", error);
|
|
@@ -16965,15 +17151,17 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
16965
17151
|
/**
|
|
16966
17152
|
* Create a new conversation
|
|
16967
17153
|
* POST {endpoint}/console/as/conversations
|
|
16968
|
-
* @param params -
|
|
17154
|
+
* @param params - Session params containing cwd and optional configuration
|
|
16969
17155
|
*/
|
|
16970
17156
|
async create(params) {
|
|
16971
17157
|
try {
|
|
16972
|
-
const
|
|
17158
|
+
const { options = {} } = params;
|
|
17159
|
+
const codebuddyMeta = options._meta?.["codebuddy.ai"];
|
|
17160
|
+
const tagsObj = options.tags || codebuddyMeta?.tags;
|
|
16973
17161
|
const tagsArray = tagsObj ? Object.entries(tagsObj).map(([key, value]) => `${key}:${value}`) : void 0;
|
|
16974
17162
|
const createPayload = {
|
|
16975
|
-
prompt: "",
|
|
16976
|
-
model: "deepseek-r1",
|
|
17163
|
+
prompt: (options.prompt || "").slice(0, 100),
|
|
17164
|
+
model: options.model || "deepseek-r1",
|
|
16977
17165
|
...tagsArray && tagsArray.length > 0 ? { tags: tagsArray } : {}
|
|
16978
17166
|
};
|
|
16979
17167
|
console.log("[CloudAgentProvider] Creating conversation with payload:", createPayload);
|
|
@@ -17027,7 +17215,14 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
17027
17215
|
} catch (error) {
|
|
17028
17216
|
this.logger?.debug(`Failed to fetch conversation details for ${agentId}:`, error);
|
|
17029
17217
|
}
|
|
17030
|
-
|
|
17218
|
+
const existingConnection = this.connectionCache.get(endpoint);
|
|
17219
|
+
if (existingConnection) {
|
|
17220
|
+
this.connectionCache.delete(endpoint);
|
|
17221
|
+
existingConnection.removeAllListeners();
|
|
17222
|
+
existingConnection.disconnect().catch((err) => {
|
|
17223
|
+
this.logger?.debug("Failed to disconnect old connection:", err);
|
|
17224
|
+
});
|
|
17225
|
+
}
|
|
17031
17226
|
const clientCapabilities = {
|
|
17032
17227
|
...this.options.clientCapabilities,
|
|
17033
17228
|
_meta: {
|
|
@@ -17147,6 +17342,35 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
17147
17342
|
}
|
|
17148
17343
|
}
|
|
17149
17344
|
/**
|
|
17345
|
+
* Update conversation status by ID
|
|
17346
|
+
* POST {endpoint}/console/as/conversations/{agentId}
|
|
17347
|
+
*
|
|
17348
|
+
* @param agentId - Conversation ID to update
|
|
17349
|
+
* @param status - New status for the conversation
|
|
17350
|
+
* @returns PatchConversationResponse containing the updated conversation ID
|
|
17351
|
+
*
|
|
17352
|
+
* @example
|
|
17353
|
+
* ```typescript
|
|
17354
|
+
* const result = await provider.updateStatus('agent-123', 'completed');
|
|
17355
|
+
* console.log('Updated conversation status:', result.id);
|
|
17356
|
+
* ```
|
|
17357
|
+
*/
|
|
17358
|
+
async updateStatus(agentId, status) {
|
|
17359
|
+
try {
|
|
17360
|
+
const body = { status };
|
|
17361
|
+
const apiResponse = await httpService.post(`/console/as/conversations/${agentId}`, body);
|
|
17362
|
+
if (!apiResponse.data) {
|
|
17363
|
+
this.logger?.info(`Updated conversation status: ${agentId} to "${status}"`);
|
|
17364
|
+
return { id: agentId };
|
|
17365
|
+
}
|
|
17366
|
+
this.logger?.info(`Updated conversation status: ${apiResponse.data.id} to "${status}"`);
|
|
17367
|
+
return apiResponse.data;
|
|
17368
|
+
} catch (error) {
|
|
17369
|
+
this.logger?.error(`Failed to update conversation status ${agentId}:`, error);
|
|
17370
|
+
throw error;
|
|
17371
|
+
}
|
|
17372
|
+
}
|
|
17373
|
+
/**
|
|
17150
17374
|
* Get available models from product configuration
|
|
17151
17375
|
*
|
|
17152
17376
|
* GET {endpoint}/console/enterprises/{personal|enterpriseId}/models?repos[]={repo}
|
|
@@ -17177,9 +17401,13 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
17177
17401
|
this.logger?.warn("[CloudAgentProvider] No data in config response, returning empty models");
|
|
17178
17402
|
return [];
|
|
17179
17403
|
}
|
|
17180
|
-
|
|
17181
|
-
|
|
17182
|
-
|
|
17404
|
+
this.productConfigCache = apiResponse.data;
|
|
17405
|
+
const productConfig = apiResponse.data;
|
|
17406
|
+
const allModels = productConfig.models ?? [];
|
|
17407
|
+
const cliModelIds = (productConfig.agents ?? []).find((agent) => agent.name === "cli")?.models ?? [];
|
|
17408
|
+
const filteredModels = cliModelIds.length > 0 ? allModels.filter((model) => cliModelIds.includes(model.id)) : allModels;
|
|
17409
|
+
this.logger?.info(`[CloudAgentProvider] Retrieved ${filteredModels.length} models for cli agent (total: ${allModels.length})`);
|
|
17410
|
+
return filteredModels.map((model) => ({
|
|
17183
17411
|
id: model.id,
|
|
17184
17412
|
name: model.name ?? model.id,
|
|
17185
17413
|
description: model.description,
|
|
@@ -17201,6 +17429,43 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
17201
17429
|
}
|
|
17202
17430
|
}
|
|
17203
17431
|
/**
|
|
17432
|
+
* 获取产品部署类型(从缓存)
|
|
17433
|
+
* 需要先调用 getModels() 初始化缓存
|
|
17434
|
+
*
|
|
17435
|
+
* @returns 部署类型:'SaaS' | 'Cloud-Hosted' | 'Self-Hosted',默认为 'SaaS'
|
|
17436
|
+
*/
|
|
17437
|
+
getDeploymentType() {
|
|
17438
|
+
return this.productConfigCache?.deploymentType ?? "SaaS";
|
|
17439
|
+
}
|
|
17440
|
+
/**
|
|
17441
|
+
* 获取 Credit 购买引导配置(从缓存)
|
|
17442
|
+
* 需要先调用 getModels() 初始化缓存
|
|
17443
|
+
*
|
|
17444
|
+
* @returns Credit 购买引导配置,key 为错误码。如果后端未返回,则使用默认配置
|
|
17445
|
+
*/
|
|
17446
|
+
getCreditPurchaseActions() {
|
|
17447
|
+
return this.productConfigCache?.config?.creditPurchaseActions ?? {
|
|
17448
|
+
"14018": {
|
|
17449
|
+
labelZh: "获取 Credits",
|
|
17450
|
+
labelEn: "Get credits",
|
|
17451
|
+
url: "https://www.codebuddy.cn/profile/plan",
|
|
17452
|
+
showButton: true
|
|
17453
|
+
},
|
|
17454
|
+
"6004": {
|
|
17455
|
+
labelZh: "升级专业版",
|
|
17456
|
+
labelEn: "Upgrade to Pro",
|
|
17457
|
+
url: "https://www.codebuddy.cn/profile/plan",
|
|
17458
|
+
showButton: true
|
|
17459
|
+
},
|
|
17460
|
+
"6005": {
|
|
17461
|
+
labelZh: "升级专业版",
|
|
17462
|
+
labelEn: "Upgrade to Pro",
|
|
17463
|
+
url: "https://www.codebuddy.cn/profile/plan",
|
|
17464
|
+
showButton: true
|
|
17465
|
+
}
|
|
17466
|
+
};
|
|
17467
|
+
}
|
|
17468
|
+
/**
|
|
17204
17469
|
* Generate a unique request ID
|
|
17205
17470
|
*/
|
|
17206
17471
|
generateRequestId() {
|
|
@@ -17283,7 +17548,7 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
17283
17548
|
/**
|
|
17284
17549
|
* Upload files to cloud storage via COS presigned URL
|
|
17285
17550
|
*
|
|
17286
|
-
* @param params - files array (File objects in browser)
|
|
17551
|
+
* @param params - files array (File objects in browser), optional abortSignal
|
|
17287
17552
|
* @returns Response with corresponding cloud URLs
|
|
17288
17553
|
*/
|
|
17289
17554
|
async uploadFile(params) {
|
|
@@ -17293,12 +17558,13 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
17293
17558
|
success: false,
|
|
17294
17559
|
error: "No valid File objects provided"
|
|
17295
17560
|
};
|
|
17296
|
-
const result = await this.cosUploadService.uploadFiles(files);
|
|
17561
|
+
const result = await this.cosUploadService.uploadFiles(files, params.abortSignal);
|
|
17297
17562
|
return {
|
|
17298
17563
|
success: result.success,
|
|
17299
17564
|
urls: result.urls,
|
|
17300
17565
|
expireSeconds: result.expireSeconds,
|
|
17301
|
-
error: result.error
|
|
17566
|
+
error: result.error,
|
|
17567
|
+
aborted: result.aborted
|
|
17302
17568
|
};
|
|
17303
17569
|
}
|
|
17304
17570
|
/**
|
|
@@ -17340,20 +17606,22 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
17340
17606
|
}
|
|
17341
17607
|
/**
|
|
17342
17608
|
* 获取支持的场景列表
|
|
17343
|
-
* API 端点: GET /
|
|
17609
|
+
* API 端点: GET /v2/as/support/scenes (不鉴权)
|
|
17344
17610
|
* 用于 Welcome 页面的 QuickActions 快捷操作
|
|
17345
17611
|
*
|
|
17612
|
+
* @param locale - 可选,语言环境(如 'zh-CN', 'en-US'),用于获取对应语言的场景数据
|
|
17346
17613
|
* @returns Promise<SupportScene[]> 支持的场景列表
|
|
17347
17614
|
*/
|
|
17348
|
-
async getSupportScenes() {
|
|
17615
|
+
async getSupportScenes(locale) {
|
|
17349
17616
|
try {
|
|
17350
|
-
const
|
|
17617
|
+
const url = this.buildGetUrl("/v2/as/support/scenes", locale ? { locale } : void 0);
|
|
17618
|
+
const apiResponse = await httpService.get(url);
|
|
17351
17619
|
if (!apiResponse.data) {
|
|
17352
17620
|
this.logger?.warn("[CloudAgentProvider] No data in support scenes response");
|
|
17353
17621
|
return [];
|
|
17354
17622
|
}
|
|
17355
17623
|
const scenes = apiResponse.data.scenes || [];
|
|
17356
|
-
this.logger?.info(`[CloudAgentProvider] Retrieved ${scenes.length} support scenes`);
|
|
17624
|
+
this.logger?.info(`[CloudAgentProvider] Retrieved ${scenes.length} support scenes${locale ? ` for locale: ${locale}` : ""}`);
|
|
17357
17625
|
return scenes;
|
|
17358
17626
|
} catch (error) {
|
|
17359
17627
|
this.logger?.error("[CloudAgentProvider] Failed to get support scenes:", error);
|
|
@@ -17369,7 +17637,9 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
17369
17637
|
type: "cloud",
|
|
17370
17638
|
status,
|
|
17371
17639
|
createdAt: data.createdAt ? new Date(data.createdAt) : void 0,
|
|
17372
|
-
|
|
17640
|
+
updatedAt: data.updatedAt ? new Date(data.updatedAt) : void 0,
|
|
17641
|
+
capabilities: this.options.clientCapabilities,
|
|
17642
|
+
isUserDefinedTitle: data.isUserDefinedTitle
|
|
17373
17643
|
};
|
|
17374
17644
|
}
|
|
17375
17645
|
/**
|
|
@@ -17385,55 +17655,498 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
17385
17655
|
const queryString = searchParams.toString();
|
|
17386
17656
|
return queryString ? `${path}?${queryString}` : path;
|
|
17387
17657
|
}
|
|
17388
|
-
};
|
|
17389
|
-
|
|
17390
|
-
//#endregion
|
|
17391
|
-
//#region ../agent-provider/src/common/providers/local-agent-provider/local-connection.ts
|
|
17392
|
-
/**
|
|
17393
|
-
* Local Agent Connection
|
|
17394
|
-
* Wraps AcpJsonRpcClient to implement AgentConnection interface
|
|
17395
|
-
*
|
|
17396
|
-
* Uses IWidgetChannel for IPC communication with ExtensionHost
|
|
17397
|
-
* Migrated from ipc-agent-provider for unified local agent access
|
|
17398
|
-
*/
|
|
17399
|
-
|
|
17400
|
-
//#endregion
|
|
17401
|
-
//#region ../agent-provider/src/common/client/session.ts
|
|
17402
|
-
/**
|
|
17403
|
-
* ActiveSessionImpl - Implements the ActiveSession interface
|
|
17404
|
-
*
|
|
17405
|
-
* This class wraps an AgentConnection and provides the session-centric API.
|
|
17406
|
-
* It is created by SessionManager when creating or loading sessions.
|
|
17407
|
-
*
|
|
17408
|
-
* @example
|
|
17409
|
-
* ```typescript
|
|
17410
|
-
* // Created by client.sessions.new() or client.sessions.load()
|
|
17411
|
-
* const session = await client.sessions.new({ cwd: '/workspace' });
|
|
17412
|
-
*
|
|
17413
|
-
* // Access agent state
|
|
17414
|
-
* console.log(session.agentState.status);
|
|
17415
|
-
*
|
|
17416
|
-
* // Send prompt
|
|
17417
|
-
* const response = await session.prompts.send({ content: 'Hello!' });
|
|
17418
|
-
*
|
|
17419
|
-
* // Cleanup
|
|
17420
|
-
* session.disconnect();
|
|
17421
|
-
* ```
|
|
17422
|
-
*/
|
|
17423
|
-
var ActiveSessionImpl = class {
|
|
17424
17658
|
/**
|
|
17425
|
-
*
|
|
17659
|
+
* 获取已安装插件列表
|
|
17660
|
+
* GET /console/as/user/plugins/installed
|
|
17661
|
+
*/
|
|
17662
|
+
async getInstalledPlugins(forceRefresh) {
|
|
17663
|
+
try {
|
|
17664
|
+
const result = ((await httpService.get("/console/as/user/plugins/installed")).data?.plugins || []).map((p) => ({
|
|
17665
|
+
name: p.plugin_name,
|
|
17666
|
+
marketplaceName: p.marketplace_name,
|
|
17667
|
+
status: p.enabled ? "enabled" : "disabled",
|
|
17668
|
+
description: p.description,
|
|
17669
|
+
version: p.version,
|
|
17670
|
+
installScope: p.scope === "local" ? "project" : p.scope,
|
|
17671
|
+
installedScopes: [p.scope],
|
|
17672
|
+
installId: p.id
|
|
17673
|
+
}));
|
|
17674
|
+
result.forEach((plugin) => {
|
|
17675
|
+
this.pluginCache.set(plugin.name, plugin);
|
|
17676
|
+
});
|
|
17677
|
+
return result;
|
|
17678
|
+
} catch (error) {
|
|
17679
|
+
this.logger?.error("[CloudAgentProvider] getInstalledPlugins failed:", error);
|
|
17680
|
+
throw error;
|
|
17681
|
+
}
|
|
17682
|
+
}
|
|
17683
|
+
/**
|
|
17684
|
+
* 安装插件
|
|
17685
|
+
* POST /console/as/user/plugins/install
|
|
17426
17686
|
*
|
|
17427
|
-
* @param
|
|
17428
|
-
* @param
|
|
17429
|
-
* @param connection - Already connected AgentConnection
|
|
17430
|
-
* @param options - Additional options
|
|
17687
|
+
* @param pluginNames - 插件名称数组
|
|
17688
|
+
* @param marketplaceNameOrId - 市场名称或 ID
|
|
17431
17689
|
*/
|
|
17432
|
-
|
|
17433
|
-
|
|
17434
|
-
|
|
17435
|
-
|
|
17436
|
-
|
|
17690
|
+
async installPlugins(pluginNames, marketplaceNameOrId, installScope, marketplaceSource, workspacePath) {
|
|
17691
|
+
try {
|
|
17692
|
+
const marketplaceId = await this.findMarketplaceId(marketplaceNameOrId);
|
|
17693
|
+
if (!marketplaceId) return {
|
|
17694
|
+
success: false,
|
|
17695
|
+
error: `Marketplace not found: ${marketplaceNameOrId}`
|
|
17696
|
+
};
|
|
17697
|
+
const failed = (await Promise.allSettled(pluginNames.map((pluginName) => httpService.post("/console/as/user/plugins/install", {
|
|
17698
|
+
plugin_name: pluginName,
|
|
17699
|
+
marketplace_id: marketplaceId,
|
|
17700
|
+
version: "latest"
|
|
17701
|
+
})))).filter((r) => r.status === "rejected");
|
|
17702
|
+
if (failed.length > 0) {
|
|
17703
|
+
const errors = failed.map((r) => r.reason?.message || "Unknown error");
|
|
17704
|
+
return {
|
|
17705
|
+
success: false,
|
|
17706
|
+
error: `安装失败 ${failed.length} 个插件: ${errors.join(", ")}`
|
|
17707
|
+
};
|
|
17708
|
+
}
|
|
17709
|
+
return { success: true };
|
|
17710
|
+
} catch (error) {
|
|
17711
|
+
return {
|
|
17712
|
+
success: false,
|
|
17713
|
+
error: this.extractErrorMessage(error)
|
|
17714
|
+
};
|
|
17715
|
+
}
|
|
17716
|
+
}
|
|
17717
|
+
/**
|
|
17718
|
+
* 卸载插件
|
|
17719
|
+
* POST /console/as/user/plugins/installed/:id/uninstall
|
|
17720
|
+
*
|
|
17721
|
+
* 完整链路:
|
|
17722
|
+
* CloudAgentProvider.uninstallPlugin()
|
|
17723
|
+
* -> HTTP POST /console/as/user/plugins/installed/:id/uninstall
|
|
17724
|
+
* -> agentserver: PluginInstallService.Uninstall()
|
|
17725
|
+
* -> 软删除 DB + 异步同步到活跃沙箱
|
|
17726
|
+
*
|
|
17727
|
+
* @param pluginName - 插件名称
|
|
17728
|
+
* @param marketplaceName - 市场名称(用于标识唯一插件)
|
|
17729
|
+
* @param scope - 卸载范围 ('user' | 'project' | 'project-local')
|
|
17730
|
+
*/
|
|
17731
|
+
async uninstallPlugin(pluginName, marketplaceName, scope) {
|
|
17732
|
+
try {
|
|
17733
|
+
const installId = await this.findPluginInstallId(pluginName);
|
|
17734
|
+
if (!installId) return {
|
|
17735
|
+
success: false,
|
|
17736
|
+
error: `Plugin not found or not installed: ${pluginName}`
|
|
17737
|
+
};
|
|
17738
|
+
await httpService.post(`/console/as/user/plugins/installed/${installId}/uninstall`);
|
|
17739
|
+
return { success: true };
|
|
17740
|
+
} catch (error) {
|
|
17741
|
+
return {
|
|
17742
|
+
success: false,
|
|
17743
|
+
error: this.extractErrorMessage(error)
|
|
17744
|
+
};
|
|
17745
|
+
}
|
|
17746
|
+
}
|
|
17747
|
+
/**
|
|
17748
|
+
* 获取插件市场列表
|
|
17749
|
+
* GET /console/as/marketplace/sources
|
|
17750
|
+
*/
|
|
17751
|
+
async getPluginMarketplaces(forceRefresh) {
|
|
17752
|
+
try {
|
|
17753
|
+
const result = ((await httpService.get("/console/as/marketplace/sources")).data?.sources || []).map((src) => ({
|
|
17754
|
+
id: src.id,
|
|
17755
|
+
name: src.name,
|
|
17756
|
+
type: this.mapSourceType(src.source_type),
|
|
17757
|
+
source: { url: src.url },
|
|
17758
|
+
description: src.name,
|
|
17759
|
+
isBuiltin: src.is_default
|
|
17760
|
+
}));
|
|
17761
|
+
result.forEach((m) => {
|
|
17762
|
+
const marketplaceInfo = {
|
|
17763
|
+
id: m.id,
|
|
17764
|
+
name: m.name
|
|
17765
|
+
};
|
|
17766
|
+
this.marketplaceCache.set(m.name, marketplaceInfo);
|
|
17767
|
+
this.marketplaceCache.set(m.id, marketplaceInfo);
|
|
17768
|
+
});
|
|
17769
|
+
return result;
|
|
17770
|
+
} catch (error) {
|
|
17771
|
+
this.logger?.error("[CloudAgentProvider] getPluginMarketplaces failed:", error);
|
|
17772
|
+
throw error;
|
|
17773
|
+
}
|
|
17774
|
+
}
|
|
17775
|
+
/**
|
|
17776
|
+
* 获取市场下的插件列表
|
|
17777
|
+
* - 有 searchText: GET /console/as/marketplace/plugins/search (跨所有市场搜索)
|
|
17778
|
+
* - 无 searchText: GET /console/as/marketplace/plugins (指定市场)
|
|
17779
|
+
*
|
|
17780
|
+
* @param marketplaceNameOrId - 市场名称或 ID(优先使用 ID,如果是名称则从缓存查询 ID)
|
|
17781
|
+
* @param forceRefresh - 是否强制刷新
|
|
17782
|
+
* @param searchText - 搜索关键字(如果提供,则跨所有市场搜索)
|
|
17783
|
+
*/
|
|
17784
|
+
async getMarketplacePlugins(marketplaceNameOrId, forceRefresh, searchText) {
|
|
17785
|
+
try {
|
|
17786
|
+
if (searchText) return ((await httpService.get("/console/as/marketplace/plugins/search", { params: {
|
|
17787
|
+
q: searchText,
|
|
17788
|
+
page: 1,
|
|
17789
|
+
page_size: 100
|
|
17790
|
+
} })).data?.plugins || []).map((p) => this.mapPluginData(p));
|
|
17791
|
+
const sourceId = await this.findMarketplaceId(marketplaceNameOrId);
|
|
17792
|
+
if (!sourceId) {
|
|
17793
|
+
this.logger?.warn(`[CloudAgentProvider] Marketplace not found: ${marketplaceNameOrId}`);
|
|
17794
|
+
return [];
|
|
17795
|
+
}
|
|
17796
|
+
const params = {
|
|
17797
|
+
source_id: sourceId,
|
|
17798
|
+
page: 1,
|
|
17799
|
+
page_size: 100
|
|
17800
|
+
};
|
|
17801
|
+
return ((await httpService.get("/console/as/marketplace/plugins", { params })).data?.plugins || []).map((p) => this.mapPluginData(p));
|
|
17802
|
+
} catch (error) {
|
|
17803
|
+
this.logger?.error("[CloudAgentProvider] getMarketplacePlugins failed:", error);
|
|
17804
|
+
throw error;
|
|
17805
|
+
}
|
|
17806
|
+
}
|
|
17807
|
+
/**
|
|
17808
|
+
* 获取插件详情
|
|
17809
|
+
* GET /console/as/marketplace/plugins/:name/detail
|
|
17810
|
+
*
|
|
17811
|
+
* @param pluginName - 插件名称
|
|
17812
|
+
* @param marketplaceNameOrId - 市场名称或 ID(优先使用 ID,如果是名称则从缓存查询 ID)
|
|
17813
|
+
*/
|
|
17814
|
+
async getPluginDetail(pluginName, marketplaceNameOrId) {
|
|
17815
|
+
try {
|
|
17816
|
+
const sourceId = await this.findMarketplaceId(marketplaceNameOrId);
|
|
17817
|
+
if (!sourceId) {
|
|
17818
|
+
this.logger?.warn(`[CloudAgentProvider] Marketplace not found: ${marketplaceNameOrId}`);
|
|
17819
|
+
return null;
|
|
17820
|
+
}
|
|
17821
|
+
const p = (await httpService.get(`/console/as/marketplace/plugins/${pluginName}/detail`, { params: { source_id: sourceId } })).data?.plugin;
|
|
17822
|
+
if (!p) return null;
|
|
17823
|
+
const capabilities = p.capabilities ? this.parseCapabilities(p.capabilities) : {};
|
|
17824
|
+
const tags = p.tags ? JSON.parse(p.tags) : [];
|
|
17825
|
+
return {
|
|
17826
|
+
name: p.name,
|
|
17827
|
+
marketplaceName: p.marketplace_name,
|
|
17828
|
+
description: p.description,
|
|
17829
|
+
version: p.version,
|
|
17830
|
+
iconUrl: p.icon_url,
|
|
17831
|
+
tags,
|
|
17832
|
+
installed: p.installed,
|
|
17833
|
+
status: p.enabled ? "enabled" : p.installed ? "disabled" : "not-installed",
|
|
17834
|
+
readme: p.readme,
|
|
17835
|
+
author: p.author,
|
|
17836
|
+
homepage: p.homepage,
|
|
17837
|
+
repositoryUrl: p.repository_url,
|
|
17838
|
+
license: p.license,
|
|
17839
|
+
...capabilities
|
|
17840
|
+
};
|
|
17841
|
+
} catch (error) {
|
|
17842
|
+
this.logger?.error("[CloudAgentProvider] getPluginDetail failed:", error);
|
|
17843
|
+
throw error;
|
|
17844
|
+
}
|
|
17845
|
+
}
|
|
17846
|
+
/**
|
|
17847
|
+
* 添加插件市场
|
|
17848
|
+
* POST /console/as/marketplace/sources
|
|
17849
|
+
*/
|
|
17850
|
+
async addPluginMarketplace(sourceUrl, name) {
|
|
17851
|
+
try {
|
|
17852
|
+
const body = {
|
|
17853
|
+
source_type: sourceUrl.startsWith("http") ? "url" : "github",
|
|
17854
|
+
url: sourceUrl,
|
|
17855
|
+
name: name || sourceUrl
|
|
17856
|
+
};
|
|
17857
|
+
const sourceData = (await httpService.post("/console/as/marketplace/sources", body)).data?.source;
|
|
17858
|
+
if (!sourceData) throw new Error("Invalid response from server");
|
|
17859
|
+
const marketplaceInfo = {
|
|
17860
|
+
id: sourceData.id,
|
|
17861
|
+
name: sourceData.name
|
|
17862
|
+
};
|
|
17863
|
+
this.marketplaceCache.set(sourceData.name, marketplaceInfo);
|
|
17864
|
+
this.marketplaceCache.set(sourceData.id, marketplaceInfo);
|
|
17865
|
+
return {
|
|
17866
|
+
success: true,
|
|
17867
|
+
marketplace: {
|
|
17868
|
+
id: sourceData.id,
|
|
17869
|
+
name: sourceData.name,
|
|
17870
|
+
type: this.mapSourceType(sourceData.source_type),
|
|
17871
|
+
source: { url: sourceData.url },
|
|
17872
|
+
isBuiltin: sourceData.is_default
|
|
17873
|
+
}
|
|
17874
|
+
};
|
|
17875
|
+
} catch (error) {
|
|
17876
|
+
return {
|
|
17877
|
+
success: false,
|
|
17878
|
+
error: this.extractErrorMessage(error)
|
|
17879
|
+
};
|
|
17880
|
+
}
|
|
17881
|
+
}
|
|
17882
|
+
/**
|
|
17883
|
+
* 删除插件市场
|
|
17884
|
+
* POST /console/as/marketplace/sources/:id/delete
|
|
17885
|
+
*/
|
|
17886
|
+
async removePluginMarketplace(marketplaceNameOrId) {
|
|
17887
|
+
try {
|
|
17888
|
+
const marketplaceId = await this.findMarketplaceId(marketplaceNameOrId);
|
|
17889
|
+
if (!marketplaceId) return {
|
|
17890
|
+
success: false,
|
|
17891
|
+
error: `Marketplace not found: ${marketplaceNameOrId}`
|
|
17892
|
+
};
|
|
17893
|
+
await httpService.post(`/console/as/marketplace/sources/${marketplaceId}/delete`, {});
|
|
17894
|
+
return { success: true };
|
|
17895
|
+
} catch (error) {
|
|
17896
|
+
return {
|
|
17897
|
+
success: false,
|
|
17898
|
+
error: this.extractErrorMessage(error)
|
|
17899
|
+
};
|
|
17900
|
+
}
|
|
17901
|
+
}
|
|
17902
|
+
/**
|
|
17903
|
+
* 刷新插件市场
|
|
17904
|
+
* POST /console/as/marketplace/sources/:id/check-updates
|
|
17905
|
+
*/
|
|
17906
|
+
async refreshPluginMarketplace(marketplaceNameOrId) {
|
|
17907
|
+
try {
|
|
17908
|
+
const marketplaceId = await this.findMarketplaceId(marketplaceNameOrId);
|
|
17909
|
+
if (!marketplaceId) return {
|
|
17910
|
+
success: false,
|
|
17911
|
+
error: `Marketplace not found: ${marketplaceNameOrId}`
|
|
17912
|
+
};
|
|
17913
|
+
return {
|
|
17914
|
+
success: true,
|
|
17915
|
+
plugins: (await httpService.post(`/console/as/marketplace/sources/${marketplaceId}/check-updates`, {})).data?.updated_plugins || []
|
|
17916
|
+
};
|
|
17917
|
+
} catch (error) {
|
|
17918
|
+
return {
|
|
17919
|
+
success: false,
|
|
17920
|
+
error: this.extractErrorMessage(error)
|
|
17921
|
+
};
|
|
17922
|
+
}
|
|
17923
|
+
}
|
|
17924
|
+
/**
|
|
17925
|
+
* 批量切换插件启用/禁用状态
|
|
17926
|
+
* POST /console/as/user/plugins/installed/:id/toggle
|
|
17927
|
+
*/
|
|
17928
|
+
async batchTogglePlugins(request) {
|
|
17929
|
+
try {
|
|
17930
|
+
const results = await Promise.allSettled(request.items.map(async (item) => {
|
|
17931
|
+
const installId = await this.findPluginInstallId(item.pluginName);
|
|
17932
|
+
if (!installId) throw new Error(`Plugin not found or not installed: ${item.pluginName}`);
|
|
17933
|
+
const enabled = item.operation === "enable";
|
|
17934
|
+
await httpService.post(`/console/as/user/plugins/installed/${installId}/toggle`, { enabled });
|
|
17935
|
+
return item;
|
|
17936
|
+
}));
|
|
17937
|
+
const succeededPlugins = [];
|
|
17938
|
+
const failedPlugins = [];
|
|
17939
|
+
results.forEach((r, i) => {
|
|
17940
|
+
const item = request.items[i];
|
|
17941
|
+
if (r.status === "fulfilled") succeededPlugins.push(item);
|
|
17942
|
+
else failedPlugins.push({
|
|
17943
|
+
...item,
|
|
17944
|
+
error: r.reason?.message || "Unknown error"
|
|
17945
|
+
});
|
|
17946
|
+
});
|
|
17947
|
+
return {
|
|
17948
|
+
success: failedPlugins.length === 0,
|
|
17949
|
+
succeededPlugins,
|
|
17950
|
+
failedPlugins
|
|
17951
|
+
};
|
|
17952
|
+
} catch (error) {
|
|
17953
|
+
return {
|
|
17954
|
+
success: false,
|
|
17955
|
+
succeededPlugins: [],
|
|
17956
|
+
failedPlugins: request.items.map((item) => ({
|
|
17957
|
+
...item,
|
|
17958
|
+
error: this.extractErrorMessage(error)
|
|
17959
|
+
}))
|
|
17960
|
+
};
|
|
17961
|
+
}
|
|
17962
|
+
}
|
|
17963
|
+
/**
|
|
17964
|
+
* 将后端插件数据映射为前端格式
|
|
17965
|
+
*/
|
|
17966
|
+
mapPluginData(p) {
|
|
17967
|
+
const capabilities = p.capabilities ? this.parseCapabilities(p.capabilities) : {};
|
|
17968
|
+
let tags = [];
|
|
17969
|
+
if (p.tags) {
|
|
17970
|
+
if (Array.isArray(p.tags)) tags = p.tags;
|
|
17971
|
+
else if (typeof p.tags === "string") try {
|
|
17972
|
+
const parsed = JSON.parse(p.tags);
|
|
17973
|
+
tags = Array.isArray(parsed) ? parsed : [parsed];
|
|
17974
|
+
} catch {
|
|
17975
|
+
tags = p.tags.split(",").map((t) => t.trim()).filter((t) => t);
|
|
17976
|
+
}
|
|
17977
|
+
}
|
|
17978
|
+
return {
|
|
17979
|
+
name: p.name,
|
|
17980
|
+
marketplaceName: p.marketplace_name,
|
|
17981
|
+
description: p.description,
|
|
17982
|
+
version: p.version,
|
|
17983
|
+
iconUrl: p.icon_url,
|
|
17984
|
+
tags,
|
|
17985
|
+
installed: p.installed,
|
|
17986
|
+
status: p.enabled ? "enabled" : p.installed ? "disabled" : "not-installed",
|
|
17987
|
+
installedScopes: p.installed ? [p.installed_scope] : [],
|
|
17988
|
+
...capabilities
|
|
17989
|
+
};
|
|
17990
|
+
}
|
|
17991
|
+
/**
|
|
17992
|
+
* 从缓存中查找插件的 install_id
|
|
17993
|
+
* 如果缓存未命中,则调用 API 获取并缓存
|
|
17994
|
+
*
|
|
17995
|
+
* @param pluginName - 插件名称
|
|
17996
|
+
* @returns install_id 或 null
|
|
17997
|
+
*/
|
|
17998
|
+
async findPluginInstallId(pluginName) {
|
|
17999
|
+
const cached = this.pluginCache.get(pluginName);
|
|
18000
|
+
if (cached) return cached.installId;
|
|
18001
|
+
await this.getInstalledPlugins();
|
|
18002
|
+
return this.pluginCache.get(pluginName)?.installId || null;
|
|
18003
|
+
}
|
|
18004
|
+
/**
|
|
18005
|
+
* 从缓存中查找 marketplace ID
|
|
18006
|
+
* 如果缓存未命中,则调用 API 获取并缓存
|
|
18007
|
+
*/
|
|
18008
|
+
async findMarketplaceId(nameOrId) {
|
|
18009
|
+
const cached = this.marketplaceCache.get(nameOrId);
|
|
18010
|
+
if (cached) return cached.id;
|
|
18011
|
+
await this.getPluginMarketplaces();
|
|
18012
|
+
return this.marketplaceCache.get(nameOrId)?.id || null;
|
|
18013
|
+
}
|
|
18014
|
+
/**
|
|
18015
|
+
* 提取 API 错误信息
|
|
18016
|
+
* 从 AxiosError 中提取详细的错误信息,包括 HTTP 状态码、错误码和错误消息
|
|
18017
|
+
*/
|
|
18018
|
+
extractErrorMessage(error) {
|
|
18019
|
+
if (error instanceof AxiosError) {
|
|
18020
|
+
const status = error.response?.status;
|
|
18021
|
+
const apiResponse = error.response?.data;
|
|
18022
|
+
const parts = [];
|
|
18023
|
+
if (status) parts.push(`HTTP ${status}`);
|
|
18024
|
+
if (apiResponse?.code) parts.push(`Code ${apiResponse.code}`);
|
|
18025
|
+
if (apiResponse?.msg) parts.push(apiResponse.msg);
|
|
18026
|
+
else if (error.message) parts.push(error.message);
|
|
18027
|
+
const errorMessage = parts.join(" - ");
|
|
18028
|
+
this.logger?.error("[CloudAgentProvider] API Error:", {
|
|
18029
|
+
status,
|
|
18030
|
+
code: apiResponse?.code,
|
|
18031
|
+
msg: apiResponse?.msg,
|
|
18032
|
+
requestId: apiResponse?.requestId,
|
|
18033
|
+
url: error.config?.url,
|
|
18034
|
+
method: error.config?.method
|
|
18035
|
+
});
|
|
18036
|
+
return errorMessage;
|
|
18037
|
+
}
|
|
18038
|
+
if (error instanceof Error) return error.message;
|
|
18039
|
+
return "Unknown error";
|
|
18040
|
+
}
|
|
18041
|
+
/**
|
|
18042
|
+
* 映射后端 source_type 到前端类型
|
|
18043
|
+
*/
|
|
18044
|
+
mapSourceType(sourceType) {
|
|
18045
|
+
switch (sourceType) {
|
|
18046
|
+
case "github": return "github";
|
|
18047
|
+
case "official": return "custom";
|
|
18048
|
+
default: return "custom";
|
|
18049
|
+
}
|
|
18050
|
+
}
|
|
18051
|
+
/**
|
|
18052
|
+
* 解析 capabilities JSON 字符串
|
|
18053
|
+
*/
|
|
18054
|
+
parseCapabilities(capabilitiesStr) {
|
|
18055
|
+
try {
|
|
18056
|
+
const cap = JSON.parse(capabilitiesStr);
|
|
18057
|
+
return {
|
|
18058
|
+
commands: cap.commands,
|
|
18059
|
+
skills: cap.skills,
|
|
18060
|
+
mcpServers: cap.mcp,
|
|
18061
|
+
agents: cap.agents,
|
|
18062
|
+
hooks: cap.hooks,
|
|
18063
|
+
rules: cap.rules
|
|
18064
|
+
};
|
|
18065
|
+
} catch {
|
|
18066
|
+
return {};
|
|
18067
|
+
}
|
|
18068
|
+
}
|
|
18069
|
+
/**
|
|
18070
|
+
* 上报 telemetry 事件(Cloud 模式)
|
|
18071
|
+
* 通过 HTTP POST 发送到 /v2/report
|
|
18072
|
+
* 注入用户信息和浏览器环境等公共字段
|
|
18073
|
+
*/
|
|
18074
|
+
async reportTelemetry(eventName, payload) {
|
|
18075
|
+
try {
|
|
18076
|
+
const account = accountService.getAccount();
|
|
18077
|
+
const commonFields = {};
|
|
18078
|
+
if (account) {
|
|
18079
|
+
commonFields.userId = account.uid;
|
|
18080
|
+
commonFields.userNickname = account.nickname;
|
|
18081
|
+
if (account.enterpriseId) commonFields.enterpriseId = account.enterpriseId;
|
|
18082
|
+
if (account.enterpriseUserName) commonFields.username = account.enterpriseUserName;
|
|
18083
|
+
}
|
|
18084
|
+
if (typeof navigator !== "undefined") {
|
|
18085
|
+
commonFields.userAgent = navigator.userAgent;
|
|
18086
|
+
commonFields.os = navigator.platform;
|
|
18087
|
+
}
|
|
18088
|
+
const events = [{
|
|
18089
|
+
eventCode: eventName,
|
|
18090
|
+
timestamp: Date.now(),
|
|
18091
|
+
reportDelay: 0,
|
|
18092
|
+
...commonFields,
|
|
18093
|
+
...payload
|
|
18094
|
+
}];
|
|
18095
|
+
await httpService.post("/v2/report", events);
|
|
18096
|
+
} catch (error) {
|
|
18097
|
+
this.logger?.warn("reportTelemetry() failed:", error);
|
|
18098
|
+
}
|
|
18099
|
+
}
|
|
18100
|
+
};
|
|
18101
|
+
|
|
18102
|
+
//#endregion
|
|
18103
|
+
//#region ../agent-provider/src/common/providers/local-agent-provider/local-connection.ts
|
|
18104
|
+
/**
|
|
18105
|
+
* Local Agent Connection
|
|
18106
|
+
* Wraps AcpJsonRpcClient to implement AgentConnection interface
|
|
18107
|
+
*
|
|
18108
|
+
* Uses IWidgetChannel for IPC communication with ExtensionHost
|
|
18109
|
+
* Migrated from ipc-agent-provider for unified local agent access
|
|
18110
|
+
*/
|
|
18111
|
+
|
|
18112
|
+
//#endregion
|
|
18113
|
+
//#region ../agent-provider/src/common/client/session.ts
|
|
18114
|
+
/**
|
|
18115
|
+
* ActiveSessionImpl - Implements the ActiveSession interface
|
|
18116
|
+
*
|
|
18117
|
+
* This class wraps an AgentConnection and provides the session-centric API.
|
|
18118
|
+
* It is created by SessionManager when creating or loading sessions.
|
|
18119
|
+
*
|
|
18120
|
+
* @example
|
|
18121
|
+
* ```typescript
|
|
18122
|
+
* // Created by client.sessions.new() or client.sessions.load()
|
|
18123
|
+
* const session = await client.sessions.new({ cwd: '/workspace' });
|
|
18124
|
+
*
|
|
18125
|
+
* // Access agent state
|
|
18126
|
+
* console.log(session.agentState.status);
|
|
18127
|
+
*
|
|
18128
|
+
* // Send prompt
|
|
18129
|
+
* const response = await session.prompts.send({ content: 'Hello!' });
|
|
18130
|
+
*
|
|
18131
|
+
* // Cleanup
|
|
18132
|
+
* session.disconnect();
|
|
18133
|
+
* ```
|
|
18134
|
+
*/
|
|
18135
|
+
var ActiveSessionImpl = class {
|
|
18136
|
+
/**
|
|
18137
|
+
* Create an ActiveSessionImpl instance
|
|
18138
|
+
*
|
|
18139
|
+
* @param sessionId - Session ID
|
|
18140
|
+
* @param agentId - Agent ID
|
|
18141
|
+
* @param connection - Already connected AgentConnection
|
|
18142
|
+
* @param options - Additional options
|
|
18143
|
+
*/
|
|
18144
|
+
constructor(sessionId, agentId, connection, options = {}) {
|
|
18145
|
+
this._availableCommands = [];
|
|
18146
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
18147
|
+
this.onceListeners = /* @__PURE__ */ new Map();
|
|
18148
|
+
this.connectionListeners = [];
|
|
18149
|
+
this._id = sessionId;
|
|
17437
18150
|
this._agentId = agentId;
|
|
17438
18151
|
this.connection = connection;
|
|
17439
18152
|
this.logger = options.logger;
|
|
@@ -17458,6 +18171,18 @@ var ActiveSessionImpl = class {
|
|
|
17458
18171
|
return this._agentId;
|
|
17459
18172
|
}
|
|
17460
18173
|
/**
|
|
18174
|
+
* Actual workspace path (set from newSession response _meta)
|
|
18175
|
+
*/
|
|
18176
|
+
get cwd() {
|
|
18177
|
+
return this._cwd;
|
|
18178
|
+
}
|
|
18179
|
+
/**
|
|
18180
|
+
* Set actual workspace path (called by SessionManager after createSession)
|
|
18181
|
+
*/
|
|
18182
|
+
setCwd(cwd) {
|
|
18183
|
+
this._cwd = cwd;
|
|
18184
|
+
}
|
|
18185
|
+
/**
|
|
17461
18186
|
* Agent state (live connection state)
|
|
17462
18187
|
* Returns LocalAgentState or CloudAgentState based on transport type
|
|
17463
18188
|
*/
|
|
@@ -17651,10 +18376,10 @@ var ActiveSessionImpl = class {
|
|
|
17651
18376
|
return this.connection.cancelQuestion(toolCallId, reason);
|
|
17652
18377
|
}
|
|
17653
18378
|
/**
|
|
17654
|
-
* Callback for tool operations (skip
|
|
18379
|
+
* Callback for tool operations (approve / skip / cancel)
|
|
17655
18380
|
* @param toolCallId Tool call ID
|
|
17656
18381
|
* @param toolName Tool name
|
|
17657
|
-
* @param action Action to perform ('skip'
|
|
18382
|
+
* @param action Action to perform ('approve' / 'skip' / 'cancel')
|
|
17658
18383
|
*/
|
|
17659
18384
|
async toolCallback(toolCallId, toolName, action) {
|
|
17660
18385
|
return await this.getConnectionOrThrow().toolCallback(this._id, toolCallId, toolName, action);
|
|
@@ -17698,6 +18423,7 @@ var ActiveSessionImpl = class {
|
|
|
17698
18423
|
* ```
|
|
17699
18424
|
*/
|
|
17700
18425
|
async setSessionModel(modelId) {
|
|
18426
|
+
this._currentModelId = modelId;
|
|
17701
18427
|
await this.getConnectionOrThrow().setSessionModel(this._id, modelId);
|
|
17702
18428
|
}
|
|
17703
18429
|
/**
|
|
@@ -17775,11 +18501,23 @@ var ActiveSessionImpl = class {
|
|
|
17775
18501
|
* Disconnect from the session/agent
|
|
17776
18502
|
*/
|
|
17777
18503
|
disconnect() {
|
|
18504
|
+
this.removeConnectionListeners();
|
|
17778
18505
|
this.connection.disconnect();
|
|
17779
18506
|
this.removeAllListeners();
|
|
17780
18507
|
this.logger?.info(`Session ${this._id}: Disconnected`);
|
|
17781
18508
|
}
|
|
17782
18509
|
/**
|
|
18510
|
+
* Detach the session from connection events without disconnecting the connection.
|
|
18511
|
+
* This should be called when the session is being replaced but the connection is shared.
|
|
18512
|
+
* Unlike disconnect(), this only removes event listeners without closing the connection.
|
|
18513
|
+
*/
|
|
18514
|
+
detach() {
|
|
18515
|
+
this.logger?.info(`Session ${this._id}: Detaching from connection events`);
|
|
18516
|
+
this.removeConnectionListeners();
|
|
18517
|
+
this.removeAllListeners();
|
|
18518
|
+
this.logger?.info(`Session ${this._id}: Detached successfully`);
|
|
18519
|
+
}
|
|
18520
|
+
/**
|
|
17783
18521
|
* Symbol.dispose for 'using' keyword support
|
|
17784
18522
|
* Automatically disconnects and cleans up when session goes out of scope
|
|
17785
18523
|
*
|
|
@@ -17798,60 +18536,85 @@ var ActiveSessionImpl = class {
|
|
|
17798
18536
|
if (!this.connection.isInitialized) throw new Error(`Session ${this._id}: Connection not initialized.`);
|
|
17799
18537
|
return this.connection;
|
|
17800
18538
|
}
|
|
18539
|
+
/**
|
|
18540
|
+
* 在 connection 上注册 listener 并保存引用,便于 disconnect 时移除
|
|
18541
|
+
*/
|
|
18542
|
+
addConnectionListener(connection, event, listener) {
|
|
18543
|
+
connection.on(event, listener);
|
|
18544
|
+
this.connectionListeners.push({
|
|
18545
|
+
event,
|
|
18546
|
+
listener
|
|
18547
|
+
});
|
|
18548
|
+
}
|
|
18549
|
+
/**
|
|
18550
|
+
* 从 connection 上移除所有本 session 注册的 listener
|
|
18551
|
+
*/
|
|
18552
|
+
removeConnectionListeners() {
|
|
18553
|
+
for (const { event, listener } of this.connectionListeners) this.connection.off(event, listener);
|
|
18554
|
+
this.connectionListeners = [];
|
|
18555
|
+
}
|
|
17801
18556
|
setupConnectionEvents(connection) {
|
|
17802
|
-
|
|
18557
|
+
this.addConnectionListener(connection, "connected", () => {
|
|
17803
18558
|
this.emit("connected", void 0);
|
|
17804
18559
|
});
|
|
17805
|
-
|
|
18560
|
+
this.addConnectionListener(connection, "disconnected", () => {
|
|
17806
18561
|
this.emit("disconnected", void 0);
|
|
17807
18562
|
});
|
|
17808
|
-
|
|
18563
|
+
this.addConnectionListener(connection, "error", (error) => {
|
|
17809
18564
|
this.emit("error", error);
|
|
17810
18565
|
});
|
|
17811
|
-
|
|
18566
|
+
this.addConnectionListener(connection, "sessionUpdate", (update) => {
|
|
18567
|
+
const notificationSessionId = update?.sessionId;
|
|
18568
|
+
if (notificationSessionId && notificationSessionId !== this._id) {
|
|
18569
|
+
console.log(`[RT-DEBUG][AgentMgr:Session] sessionUpdate SKIPPED: notifSessionId mismatch, notif=${notificationSessionId?.substring(0, 8)}, my=${this._id?.substring(0, 8)}`);
|
|
18570
|
+
return;
|
|
18571
|
+
}
|
|
17812
18572
|
this.emit("sessionUpdate", update);
|
|
17813
18573
|
});
|
|
17814
|
-
|
|
17815
|
-
|
|
17816
|
-
artifactUri: artifact.uri,
|
|
17817
|
-
artifactType: artifact.type
|
|
17818
|
-
});
|
|
18574
|
+
this.addConnectionListener(connection, "artifactCreated", (artifact) => {
|
|
18575
|
+
if (!this.shouldForwardArtifact(artifact)) return;
|
|
17819
18576
|
this.emit("artifactCreated", artifact);
|
|
17820
18577
|
});
|
|
17821
|
-
|
|
17822
|
-
|
|
17823
|
-
artifactUri: artifact.uri,
|
|
17824
|
-
artifactType: artifact.type
|
|
17825
|
-
});
|
|
18578
|
+
this.addConnectionListener(connection, "artifactUpdated", (artifact) => {
|
|
18579
|
+
if (!this.shouldForwardArtifact(artifact)) return;
|
|
17826
18580
|
this.emit("artifactUpdated", artifact);
|
|
17827
18581
|
});
|
|
17828
|
-
|
|
17829
|
-
|
|
18582
|
+
this.addConnectionListener(connection, "artifactDeleted", (artifact) => {
|
|
18583
|
+
if (!this.shouldForwardArtifact(artifact)) return;
|
|
17830
18584
|
this.emit("artifactDeleted", artifact);
|
|
17831
18585
|
});
|
|
17832
|
-
|
|
18586
|
+
this.addConnectionListener(connection, "permissionRequest", (request) => {
|
|
17833
18587
|
this.emit("permissionRequest", request);
|
|
17834
18588
|
});
|
|
17835
|
-
|
|
18589
|
+
this.addConnectionListener(connection, "questionRequest", (request) => {
|
|
17836
18590
|
this.emit("questionRequest", request);
|
|
17837
18591
|
});
|
|
17838
|
-
|
|
18592
|
+
this.addConnectionListener(connection, "questionCancelled", () => {
|
|
17839
18593
|
this.prompts.cancel();
|
|
17840
18594
|
});
|
|
17841
|
-
|
|
18595
|
+
this.addConnectionListener(connection, "usageUpdate", (usage) => {
|
|
17842
18596
|
this.emit("usageUpdate", usage);
|
|
17843
18597
|
});
|
|
17844
|
-
|
|
18598
|
+
this.addConnectionListener(connection, "checkpointCreated", (checkpoint) => {
|
|
18599
|
+
const originSessionId = checkpoint.__sessionId;
|
|
18600
|
+
if (originSessionId && originSessionId !== this._id) return;
|
|
17845
18601
|
this.emit("checkpointCreated", checkpoint);
|
|
17846
18602
|
});
|
|
17847
|
-
|
|
18603
|
+
this.addConnectionListener(connection, "checkpointUpdated", (checkpoint) => {
|
|
18604
|
+
const originSessionId = checkpoint.__sessionId;
|
|
18605
|
+
if (originSessionId && originSessionId !== this._id) return;
|
|
17848
18606
|
this.emit("checkpointUpdated", checkpoint);
|
|
17849
18607
|
});
|
|
17850
|
-
|
|
17851
|
-
|
|
17852
|
-
|
|
17853
|
-
|
|
17854
|
-
|
|
18608
|
+
this.addConnectionListener(connection, "command", (command) => {
|
|
18609
|
+
const originSessionId = command.__sessionId;
|
|
18610
|
+
if (originSessionId && originSessionId !== this._id) {
|
|
18611
|
+
console.log("[Session] Command not forwarded:", {
|
|
18612
|
+
command,
|
|
18613
|
+
originSessionId,
|
|
18614
|
+
sessionId: this._id
|
|
18615
|
+
});
|
|
18616
|
+
return;
|
|
18617
|
+
}
|
|
17855
18618
|
this.emit("command", command);
|
|
17856
18619
|
});
|
|
17857
18620
|
}
|
|
@@ -17861,6 +18624,15 @@ var ActiveSessionImpl = class {
|
|
|
17861
18624
|
_meta: response._meta ?? void 0
|
|
17862
18625
|
};
|
|
17863
18626
|
}
|
|
18627
|
+
/**
|
|
18628
|
+
* 判断 artifact 是否应该转发给当前 session
|
|
18629
|
+
* 所有类型的 artifact 都按 __sessionId 严格隔离
|
|
18630
|
+
*/
|
|
18631
|
+
shouldForwardArtifact(artifact) {
|
|
18632
|
+
const originSessionId = artifact.__sessionId;
|
|
18633
|
+
if (!originSessionId || originSessionId !== this._id) return false;
|
|
18634
|
+
return true;
|
|
18635
|
+
}
|
|
17864
18636
|
};
|
|
17865
18637
|
|
|
17866
18638
|
//#endregion
|
|
@@ -17913,9 +18685,11 @@ var SessionManager = class {
|
|
|
17913
18685
|
name: agent.name,
|
|
17914
18686
|
status: agent.status,
|
|
17915
18687
|
createdAt: agent.createdAt,
|
|
18688
|
+
updatedAt: agent.updatedAt,
|
|
17916
18689
|
lastActivityAt: agent.updatedAt,
|
|
17917
18690
|
cwd: agent.type === "local" ? agent.cwd : void 0,
|
|
17918
|
-
isPlayground: agent.isPlayground
|
|
18691
|
+
isPlayground: agent.isPlayground,
|
|
18692
|
+
isUserDefinedTitle: agent.isUserDefinedTitle
|
|
17919
18693
|
}));
|
|
17920
18694
|
console.log("[SessionManager] Returning sessions:", {
|
|
17921
18695
|
count: sessions.length,
|
|
@@ -17942,13 +18716,26 @@ var SessionManager = class {
|
|
|
17942
18716
|
if (this.provider.create) {
|
|
17943
18717
|
agentId = await this.provider.create(params);
|
|
17944
18718
|
this.logger?.debug(`Created new agent: ${agentId}`);
|
|
18719
|
+
if (params.options?.onSessionPrepared) {
|
|
18720
|
+
const initialPrompt = params.options?.prompt;
|
|
18721
|
+
const initialTitle = initialPrompt?.slice(0, 50) || "";
|
|
18722
|
+
params.options.onSessionPrepared({
|
|
18723
|
+
id: agentId,
|
|
18724
|
+
agentId,
|
|
18725
|
+
name: initialTitle + (initialPrompt && initialPrompt.length > 50 ? "..." : ""),
|
|
18726
|
+
status: "connecting",
|
|
18727
|
+
cwd: params.cwd || "",
|
|
18728
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
18729
|
+
});
|
|
18730
|
+
this.logger?.debug(`Called onSessionPrepared for: ${agentId}`);
|
|
18731
|
+
}
|
|
17945
18732
|
} else throw new Error("Provider does not support creating agents. Use sessions.load() with an existing sessionId.");
|
|
17946
18733
|
const connection = await this.provider.connect(agentId);
|
|
17947
18734
|
this.logger?.debug(`Connected to agent: ${agentId}`);
|
|
17948
18735
|
const response = await connection.createSession({
|
|
17949
|
-
_meta: params._meta,
|
|
18736
|
+
_meta: params.options?._meta,
|
|
17950
18737
|
cwd: params.cwd,
|
|
17951
|
-
mcpServers: params.mcpServers
|
|
18738
|
+
mcpServers: params.options?.mcpServers
|
|
17952
18739
|
});
|
|
17953
18740
|
if (this.provider.registerSession) {
|
|
17954
18741
|
this.provider.registerSession(response.sessionId, agentId);
|
|
@@ -17963,6 +18750,8 @@ var SessionManager = class {
|
|
|
17963
18750
|
session.setModes(response.modes?.availableModes, response.modes?.currentModeId);
|
|
17964
18751
|
const availableModels = this.extractAvailableModels(response);
|
|
17965
18752
|
if (availableModels) session.setModels(availableModels, response.models?.currentModelId);
|
|
18753
|
+
const responseCwd = response._meta?.["codebuddy.ai"]?.cwd;
|
|
18754
|
+
if (responseCwd) session.setCwd(responseCwd);
|
|
17966
18755
|
this.logger?.info(`Session created: ${response.sessionId}`);
|
|
17967
18756
|
return session;
|
|
17968
18757
|
}
|
|
@@ -18129,6 +18918,26 @@ var AgentClient = class {
|
|
|
18129
18918
|
throw error;
|
|
18130
18919
|
}
|
|
18131
18920
|
},
|
|
18921
|
+
updateStatus: async (sessionId, status) => {
|
|
18922
|
+
this.logger?.debug("AgentClient.sessions.updateStatus called", {
|
|
18923
|
+
sessionId,
|
|
18924
|
+
status
|
|
18925
|
+
});
|
|
18926
|
+
try {
|
|
18927
|
+
if (this.provider.updateStatus) {
|
|
18928
|
+
const result = await this.provider.updateStatus(sessionId, status);
|
|
18929
|
+
this.logger?.info("Session status updated successfully", {
|
|
18930
|
+
sessionId,
|
|
18931
|
+
status
|
|
18932
|
+
});
|
|
18933
|
+
return result;
|
|
18934
|
+
}
|
|
18935
|
+
throw new Error("Provider does not support updateStatus method");
|
|
18936
|
+
} catch (error) {
|
|
18937
|
+
this.logger?.error("Failed to update session status", error);
|
|
18938
|
+
throw error;
|
|
18939
|
+
}
|
|
18940
|
+
},
|
|
18132
18941
|
move: async (sessionId) => {
|
|
18133
18942
|
this.logger?.debug("AgentClient.sessions.move called", { sessionId });
|
|
18134
18943
|
try {
|
|
@@ -18161,6 +18970,16 @@ var AgentClient = class {
|
|
|
18161
18970
|
};
|
|
18162
18971
|
}
|
|
18163
18972
|
},
|
|
18973
|
+
requestYieldAfterCurrentStep: async (sessionId) => {
|
|
18974
|
+
try {
|
|
18975
|
+
if (this.provider?.requestYieldAfterCurrentStep) return await this.provider.requestYieldAfterCurrentStep(sessionId);
|
|
18976
|
+
this.logger?.warn("Provider does not support requestYieldAfterCurrentStep");
|
|
18977
|
+
return false;
|
|
18978
|
+
} catch (error) {
|
|
18979
|
+
this.logger?.error("Failed to request yield after current step", error);
|
|
18980
|
+
return false;
|
|
18981
|
+
}
|
|
18982
|
+
},
|
|
18164
18983
|
getCurrentWorkspaces: async (filter) => {
|
|
18165
18984
|
this.logger?.debug("AgentClient.sessions.getCurrentWorkspaces called", filter);
|
|
18166
18985
|
try {
|
|
@@ -18176,15 +18995,109 @@ var AgentClient = class {
|
|
|
18176
18995
|
return [];
|
|
18177
18996
|
}
|
|
18178
18997
|
},
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18998
|
+
getAutomationSnapshot: async () => {
|
|
18999
|
+
try {
|
|
19000
|
+
if (this.provider?.getAutomationSnapshot) return await this.provider.getAutomationSnapshot();
|
|
19001
|
+
this.logger?.warn("Provider does not support getAutomationSnapshot");
|
|
19002
|
+
} catch (error) {
|
|
19003
|
+
this.logger?.error("Failed to get automation snapshot", error);
|
|
19004
|
+
}
|
|
19005
|
+
return {
|
|
19006
|
+
automations: [],
|
|
19007
|
+
inbox: [],
|
|
19008
|
+
runtimeState: {},
|
|
19009
|
+
updatedAt: Date.now()
|
|
19010
|
+
};
|
|
19011
|
+
},
|
|
19012
|
+
updateAutomation: async (payload) => {
|
|
19013
|
+
try {
|
|
19014
|
+
if (this.provider?.updateAutomation) return await this.provider.updateAutomation(payload);
|
|
19015
|
+
this.logger?.warn("Provider does not support updateAutomation");
|
|
19016
|
+
} catch (error) {
|
|
19017
|
+
this.logger?.error("Failed to update automation", error);
|
|
19018
|
+
return {
|
|
19019
|
+
success: false,
|
|
19020
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
19021
|
+
};
|
|
19022
|
+
}
|
|
19023
|
+
return {
|
|
19024
|
+
success: false,
|
|
19025
|
+
message: "Provider does not support updateAutomation"
|
|
19026
|
+
};
|
|
19027
|
+
},
|
|
19028
|
+
deleteAutomation: async (id) => {
|
|
19029
|
+
try {
|
|
19030
|
+
if (this.provider?.deleteAutomation) return await this.provider.deleteAutomation(id);
|
|
19031
|
+
this.logger?.warn("Provider does not support deleteAutomation");
|
|
19032
|
+
} catch (error) {
|
|
19033
|
+
this.logger?.error("Failed to delete automation", error);
|
|
19034
|
+
return {
|
|
19035
|
+
success: false,
|
|
19036
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
19037
|
+
};
|
|
19038
|
+
}
|
|
19039
|
+
return {
|
|
19040
|
+
success: false,
|
|
19041
|
+
message: "Provider does not support deleteAutomation"
|
|
19042
|
+
};
|
|
19043
|
+
},
|
|
19044
|
+
archiveAutomationInboxItem: async (itemId) => {
|
|
19045
|
+
try {
|
|
19046
|
+
if (this.provider?.archiveAutomationInboxItem) return await this.provider.archiveAutomationInboxItem(itemId);
|
|
19047
|
+
this.logger?.warn("Provider does not support archiveAutomationInboxItem");
|
|
19048
|
+
} catch (error) {
|
|
19049
|
+
this.logger?.error("Failed to archive automation inbox item", error);
|
|
19050
|
+
return {
|
|
19051
|
+
success: false,
|
|
19052
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
19053
|
+
};
|
|
19054
|
+
}
|
|
19055
|
+
return {
|
|
19056
|
+
success: false,
|
|
19057
|
+
message: "Provider does not support archiveAutomationInboxItem"
|
|
19058
|
+
};
|
|
19059
|
+
},
|
|
19060
|
+
deleteAutomationInboxItem: async (itemId) => {
|
|
19061
|
+
try {
|
|
19062
|
+
if (this.provider?.deleteAutomationInboxItem) return await this.provider.deleteAutomationInboxItem(itemId);
|
|
19063
|
+
this.logger?.warn("Provider does not support deleteAutomationInboxItem");
|
|
19064
|
+
} catch (error) {
|
|
19065
|
+
this.logger?.error("Failed to delete automation inbox item", error);
|
|
19066
|
+
return {
|
|
19067
|
+
success: false,
|
|
19068
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
19069
|
+
};
|
|
19070
|
+
}
|
|
19071
|
+
return {
|
|
19072
|
+
success: false,
|
|
19073
|
+
message: "Provider does not support deleteAutomationInboxItem"
|
|
19074
|
+
};
|
|
19075
|
+
},
|
|
19076
|
+
testAutomation: async (id) => {
|
|
19077
|
+
try {
|
|
19078
|
+
if (this.provider?.testAutomation) return await this.provider.testAutomation(id);
|
|
19079
|
+
this.logger?.warn("Provider does not support testAutomation");
|
|
19080
|
+
} catch (error) {
|
|
19081
|
+
this.logger?.error("Failed to test automation", error);
|
|
19082
|
+
return {
|
|
19083
|
+
success: false,
|
|
19084
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
19085
|
+
};
|
|
19086
|
+
}
|
|
19087
|
+
return {
|
|
19088
|
+
success: false,
|
|
19089
|
+
message: "Provider does not support testAutomation"
|
|
19090
|
+
};
|
|
19091
|
+
},
|
|
19092
|
+
on: (event, handler) => {
|
|
19093
|
+
if (this.provider.on) this.provider.on(event, handler);
|
|
19094
|
+
else this.logger?.warn(`Provider does not support event registration: ${String(event)}`);
|
|
19095
|
+
},
|
|
19096
|
+
off: (event, handler) => {
|
|
19097
|
+
if (this.provider.off) this.provider.off(event, handler);
|
|
19098
|
+
else this.logger?.warn(`Provider does not support event unregistration: ${String(event)}`);
|
|
19099
|
+
},
|
|
19100
|
+
openWorkspace: async (params) => {
|
|
18188
19101
|
try {
|
|
18189
19102
|
if (this.provider && this.provider.openWorkspace) {
|
|
18190
19103
|
const result = await this.provider.openWorkspace(params);
|
|
@@ -18317,6 +19230,167 @@ var AgentClient = class {
|
|
|
18317
19230
|
};
|
|
18318
19231
|
}
|
|
18319
19232
|
},
|
|
19233
|
+
getSkillList: async (params) => {
|
|
19234
|
+
try {
|
|
19235
|
+
if (this.provider && this.provider.getSkillList) {
|
|
19236
|
+
const result = await this.provider.getSkillList(params);
|
|
19237
|
+
this.logger?.info("Skill list retrieved", {
|
|
19238
|
+
resultCount: result.results.length,
|
|
19239
|
+
hasError: !!result.error
|
|
19240
|
+
});
|
|
19241
|
+
return result;
|
|
19242
|
+
}
|
|
19243
|
+
return {
|
|
19244
|
+
results: [],
|
|
19245
|
+
error: "Provider does not support getSkillList"
|
|
19246
|
+
};
|
|
19247
|
+
} catch (error) {
|
|
19248
|
+
this.logger?.error("Failed to get skill list", error);
|
|
19249
|
+
return {
|
|
19250
|
+
results: [],
|
|
19251
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19252
|
+
};
|
|
19253
|
+
}
|
|
19254
|
+
},
|
|
19255
|
+
importSkill: async (params) => {
|
|
19256
|
+
try {
|
|
19257
|
+
if (this.provider && this.provider.importSkill) {
|
|
19258
|
+
const result = await this.provider.importSkill(params);
|
|
19259
|
+
this.logger?.info("Import skill completed", {
|
|
19260
|
+
success: result.success,
|
|
19261
|
+
hasError: !!result.error
|
|
19262
|
+
});
|
|
19263
|
+
return result;
|
|
19264
|
+
}
|
|
19265
|
+
return {
|
|
19266
|
+
success: false,
|
|
19267
|
+
error: "Provider does not support importSkill"
|
|
19268
|
+
};
|
|
19269
|
+
} catch (error) {
|
|
19270
|
+
this.logger?.error("Failed to import skill", error);
|
|
19271
|
+
return {
|
|
19272
|
+
success: false,
|
|
19273
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19274
|
+
};
|
|
19275
|
+
}
|
|
19276
|
+
},
|
|
19277
|
+
toggleSkill: async (params) => {
|
|
19278
|
+
try {
|
|
19279
|
+
if (this.provider && this.provider.toggleSkill) {
|
|
19280
|
+
const result = await this.provider.toggleSkill(params);
|
|
19281
|
+
this.logger?.info("Toggle skill completed", {
|
|
19282
|
+
success: result.success,
|
|
19283
|
+
hasError: !!result.error
|
|
19284
|
+
});
|
|
19285
|
+
return result;
|
|
19286
|
+
}
|
|
19287
|
+
return {
|
|
19288
|
+
success: false,
|
|
19289
|
+
error: "Provider does not support toggleSkill"
|
|
19290
|
+
};
|
|
19291
|
+
} catch (error) {
|
|
19292
|
+
this.logger?.error("Failed to toggle skill", error);
|
|
19293
|
+
return {
|
|
19294
|
+
success: false,
|
|
19295
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19296
|
+
};
|
|
19297
|
+
}
|
|
19298
|
+
},
|
|
19299
|
+
deleteSkill: async (params) => {
|
|
19300
|
+
try {
|
|
19301
|
+
if (this.provider && this.provider.deleteSkill) {
|
|
19302
|
+
const result = await this.provider.deleteSkill(params);
|
|
19303
|
+
this.logger?.info("Delete skill completed", {
|
|
19304
|
+
success: result.success,
|
|
19305
|
+
hasError: !!result.error
|
|
19306
|
+
});
|
|
19307
|
+
return result;
|
|
19308
|
+
}
|
|
19309
|
+
return {
|
|
19310
|
+
success: false,
|
|
19311
|
+
error: "Provider does not support deleteSkill"
|
|
19312
|
+
};
|
|
19313
|
+
} catch (error) {
|
|
19314
|
+
this.logger?.error("Failed to delete skill", error);
|
|
19315
|
+
return {
|
|
19316
|
+
success: false,
|
|
19317
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19318
|
+
};
|
|
19319
|
+
}
|
|
19320
|
+
},
|
|
19321
|
+
getSkillContent: async (params) => {
|
|
19322
|
+
try {
|
|
19323
|
+
if (this.provider && this.provider.getSkillContent) {
|
|
19324
|
+
const result = await this.provider.getSkillContent(params);
|
|
19325
|
+
this.logger?.info("Get skill content completed", { hasError: !!result.error });
|
|
19326
|
+
return result;
|
|
19327
|
+
}
|
|
19328
|
+
return {
|
|
19329
|
+
content: "",
|
|
19330
|
+
error: "Provider does not support getSkillContent"
|
|
19331
|
+
};
|
|
19332
|
+
} catch (error) {
|
|
19333
|
+
this.logger?.error("Failed to get skill content", error);
|
|
19334
|
+
return {
|
|
19335
|
+
content: "",
|
|
19336
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19337
|
+
};
|
|
19338
|
+
}
|
|
19339
|
+
},
|
|
19340
|
+
getMarketplaceSkills: async () => {
|
|
19341
|
+
try {
|
|
19342
|
+
if (this.provider && this.provider.getMarketplaceSkills) {
|
|
19343
|
+
const result = await this.provider.getMarketplaceSkills();
|
|
19344
|
+
this.logger?.info("Marketplace skills retrieved", {
|
|
19345
|
+
resultCount: result.results.length,
|
|
19346
|
+
hasError: !!result.error
|
|
19347
|
+
});
|
|
19348
|
+
return result;
|
|
19349
|
+
}
|
|
19350
|
+
return {
|
|
19351
|
+
results: [],
|
|
19352
|
+
error: "Provider does not support getMarketplaceSkills"
|
|
19353
|
+
};
|
|
19354
|
+
} catch (error) {
|
|
19355
|
+
this.logger?.error("Failed to get marketplace skills", error);
|
|
19356
|
+
return {
|
|
19357
|
+
results: [],
|
|
19358
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19359
|
+
};
|
|
19360
|
+
}
|
|
19361
|
+
},
|
|
19362
|
+
getMarketplaceSkillContent: async (params) => {
|
|
19363
|
+
try {
|
|
19364
|
+
if (this.provider && this.provider.getMarketplaceSkillContent) return await this.provider.getMarketplaceSkillContent(params);
|
|
19365
|
+
return {
|
|
19366
|
+
content: "",
|
|
19367
|
+
error: "Provider does not support getMarketplaceSkillContent"
|
|
19368
|
+
};
|
|
19369
|
+
} catch (error) {
|
|
19370
|
+
this.logger?.error("Failed to get marketplace skill content", error);
|
|
19371
|
+
return {
|
|
19372
|
+
content: "",
|
|
19373
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19374
|
+
};
|
|
19375
|
+
}
|
|
19376
|
+
},
|
|
19377
|
+
installMarketplaceSkill: async (params) => {
|
|
19378
|
+
try {
|
|
19379
|
+
if (this.provider && this.provider.installMarketplaceSkill) return await this.provider.installMarketplaceSkill(params);
|
|
19380
|
+
return {
|
|
19381
|
+
success: false,
|
|
19382
|
+
skillName: params.skillName,
|
|
19383
|
+
errorMessage: "Provider does not support installMarketplaceSkill"
|
|
19384
|
+
};
|
|
19385
|
+
} catch (error) {
|
|
19386
|
+
this.logger?.error("Failed to install marketplace skill", error);
|
|
19387
|
+
return {
|
|
19388
|
+
success: false,
|
|
19389
|
+
skillName: params.skillName,
|
|
19390
|
+
errorMessage: error instanceof Error ? error.message : "Unknown error"
|
|
19391
|
+
};
|
|
19392
|
+
}
|
|
19393
|
+
},
|
|
18320
19394
|
batchTogglePlugins: async (request) => {
|
|
18321
19395
|
try {
|
|
18322
19396
|
if (this.provider && this.provider.batchTogglePlugins) {
|
|
@@ -18361,37 +19435,229 @@ var AgentClient = class {
|
|
|
18361
19435
|
return [];
|
|
18362
19436
|
}
|
|
18363
19437
|
},
|
|
18364
|
-
installPlugins: async (pluginNames, marketplaceName, installScope, marketplaceSource) => {
|
|
19438
|
+
installPlugins: async (pluginNames, marketplaceName, installScope, marketplaceSource, workspacePath) => {
|
|
19439
|
+
try {
|
|
19440
|
+
if (this.provider && "installPlugins" in this.provider && typeof this.provider.installPlugins === "function") {
|
|
19441
|
+
const result = await this.provider.installPlugins(pluginNames, marketplaceName, installScope, marketplaceSource, workspacePath);
|
|
19442
|
+
this.logger?.info("Install plugins", {
|
|
19443
|
+
pluginNames,
|
|
19444
|
+
marketplaceName,
|
|
19445
|
+
success: result.success
|
|
19446
|
+
});
|
|
19447
|
+
return result;
|
|
19448
|
+
}
|
|
19449
|
+
this.logger?.warn("Provider does not support installPlugins");
|
|
19450
|
+
return {
|
|
19451
|
+
success: false,
|
|
19452
|
+
error: "Provider does not support installPlugins"
|
|
19453
|
+
};
|
|
19454
|
+
} catch (error) {
|
|
19455
|
+
this.logger?.error("Failed to install plugins", error);
|
|
19456
|
+
return {
|
|
19457
|
+
success: false,
|
|
19458
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19459
|
+
};
|
|
19460
|
+
}
|
|
19461
|
+
},
|
|
19462
|
+
uninstallPlugin: async (pluginName, marketplaceName, scope) => {
|
|
19463
|
+
try {
|
|
19464
|
+
if (this.provider && "uninstallPlugin" in this.provider && typeof this.provider.uninstallPlugin === "function") {
|
|
19465
|
+
const result = await this.provider.uninstallPlugin(pluginName, marketplaceName, scope);
|
|
19466
|
+
this.logger?.info("Uninstall plugin", {
|
|
19467
|
+
pluginName,
|
|
19468
|
+
marketplaceName,
|
|
19469
|
+
scope,
|
|
19470
|
+
success: result.success
|
|
19471
|
+
});
|
|
19472
|
+
return result;
|
|
19473
|
+
}
|
|
19474
|
+
this.logger?.warn("Provider does not support uninstallPlugin");
|
|
19475
|
+
return {
|
|
19476
|
+
success: false,
|
|
19477
|
+
error: "Provider does not support uninstallPlugin"
|
|
19478
|
+
};
|
|
19479
|
+
} catch (error) {
|
|
19480
|
+
this.logger?.error("Failed to uninstall plugin", error);
|
|
19481
|
+
return {
|
|
19482
|
+
success: false,
|
|
19483
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19484
|
+
};
|
|
19485
|
+
}
|
|
19486
|
+
},
|
|
19487
|
+
updatePlugin: async (pluginName, marketplaceName) => {
|
|
19488
|
+
try {
|
|
19489
|
+
if (this.provider && "updatePlugin" in this.provider && typeof this.provider.updatePlugin === "function") {
|
|
19490
|
+
const result = await this.provider.updatePlugin(pluginName, marketplaceName);
|
|
19491
|
+
this.logger?.info("Update plugin", {
|
|
19492
|
+
pluginName,
|
|
19493
|
+
marketplaceName,
|
|
19494
|
+
success: result.success
|
|
19495
|
+
});
|
|
19496
|
+
return result;
|
|
19497
|
+
}
|
|
19498
|
+
this.logger?.warn("Provider does not support updatePlugin");
|
|
19499
|
+
return {
|
|
19500
|
+
success: false,
|
|
19501
|
+
error: "Provider does not support updatePlugin"
|
|
19502
|
+
};
|
|
19503
|
+
} catch (error) {
|
|
19504
|
+
this.logger?.error("Failed to update plugin", error);
|
|
19505
|
+
return {
|
|
19506
|
+
success: false,
|
|
19507
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19508
|
+
};
|
|
19509
|
+
}
|
|
19510
|
+
},
|
|
19511
|
+
getPluginMarketplaces: async (forceRefresh) => {
|
|
19512
|
+
try {
|
|
19513
|
+
if (this.provider && "getPluginMarketplaces" in this.provider && typeof this.provider.getPluginMarketplaces === "function") {
|
|
19514
|
+
const result = await this.provider.getPluginMarketplaces(forceRefresh);
|
|
19515
|
+
this.logger?.info("Got plugin marketplaces", { count: result?.length ?? 0 });
|
|
19516
|
+
return result;
|
|
19517
|
+
}
|
|
19518
|
+
this.logger?.warn("Provider does not support getPluginMarketplaces");
|
|
19519
|
+
return [];
|
|
19520
|
+
} catch (error) {
|
|
19521
|
+
this.logger?.error("Failed to get plugin marketplaces", error);
|
|
19522
|
+
return [];
|
|
19523
|
+
}
|
|
19524
|
+
},
|
|
19525
|
+
getMarketplacePlugins: async (marketplaceName, forceRefresh, searchText) => {
|
|
19526
|
+
try {
|
|
19527
|
+
if (this.provider && "getMarketplacePlugins" in this.provider && typeof this.provider.getMarketplacePlugins === "function") {
|
|
19528
|
+
const result = await this.provider.getMarketplacePlugins(marketplaceName, forceRefresh, searchText);
|
|
19529
|
+
this.logger?.info("Got marketplace plugins", {
|
|
19530
|
+
marketplaceName,
|
|
19531
|
+
count: result?.length ?? 0
|
|
19532
|
+
});
|
|
19533
|
+
return result;
|
|
19534
|
+
}
|
|
19535
|
+
this.logger?.warn("Provider does not support getMarketplacePlugins");
|
|
19536
|
+
return [];
|
|
19537
|
+
} catch (error) {
|
|
19538
|
+
this.logger?.error("Failed to get marketplace plugins", error);
|
|
19539
|
+
return [];
|
|
19540
|
+
}
|
|
19541
|
+
},
|
|
19542
|
+
getPluginDetail: async (pluginName, marketplaceName) => {
|
|
19543
|
+
try {
|
|
19544
|
+
if (this.provider && "getPluginDetail" in this.provider && typeof this.provider.getPluginDetail === "function") {
|
|
19545
|
+
const result = await this.provider.getPluginDetail(pluginName, marketplaceName);
|
|
19546
|
+
this.logger?.info("Got plugin detail", {
|
|
19547
|
+
pluginName,
|
|
19548
|
+
marketplaceName
|
|
19549
|
+
});
|
|
19550
|
+
return result;
|
|
19551
|
+
}
|
|
19552
|
+
this.logger?.warn("Provider does not support getPluginDetail");
|
|
19553
|
+
return null;
|
|
19554
|
+
} catch (error) {
|
|
19555
|
+
this.logger?.error("Failed to get plugin detail", error);
|
|
19556
|
+
return null;
|
|
19557
|
+
}
|
|
19558
|
+
},
|
|
19559
|
+
addPluginMarketplace: async (source, name) => {
|
|
19560
|
+
try {
|
|
19561
|
+
if (this.provider && "addPluginMarketplace" in this.provider && typeof this.provider.addPluginMarketplace === "function") {
|
|
19562
|
+
const result = await this.provider.addPluginMarketplace(source, name);
|
|
19563
|
+
this.logger?.info("Add plugin marketplace", {
|
|
19564
|
+
source,
|
|
19565
|
+
name,
|
|
19566
|
+
success: result.success
|
|
19567
|
+
});
|
|
19568
|
+
return result;
|
|
19569
|
+
}
|
|
19570
|
+
this.logger?.warn("Provider does not support addPluginMarketplace");
|
|
19571
|
+
return {
|
|
19572
|
+
success: false,
|
|
19573
|
+
error: "Provider does not support addPluginMarketplace"
|
|
19574
|
+
};
|
|
19575
|
+
} catch (error) {
|
|
19576
|
+
this.logger?.error("Failed to add plugin marketplace", error);
|
|
19577
|
+
return {
|
|
19578
|
+
success: false,
|
|
19579
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19580
|
+
};
|
|
19581
|
+
}
|
|
19582
|
+
},
|
|
19583
|
+
removePluginMarketplace: async (marketplaceName) => {
|
|
19584
|
+
try {
|
|
19585
|
+
if (this.provider && "removePluginMarketplace" in this.provider && typeof this.provider.removePluginMarketplace === "function") {
|
|
19586
|
+
const result = await this.provider.removePluginMarketplace(marketplaceName);
|
|
19587
|
+
this.logger?.info("Remove plugin marketplace", {
|
|
19588
|
+
marketplaceName,
|
|
19589
|
+
success: result.success
|
|
19590
|
+
});
|
|
19591
|
+
return result;
|
|
19592
|
+
}
|
|
19593
|
+
this.logger?.warn("Provider does not support removePluginMarketplace");
|
|
19594
|
+
return {
|
|
19595
|
+
success: false,
|
|
19596
|
+
error: "Provider does not support removePluginMarketplace"
|
|
19597
|
+
};
|
|
19598
|
+
} catch (error) {
|
|
19599
|
+
this.logger?.error("Failed to remove plugin marketplace", error);
|
|
19600
|
+
return {
|
|
19601
|
+
success: false,
|
|
19602
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
19603
|
+
};
|
|
19604
|
+
}
|
|
19605
|
+
},
|
|
19606
|
+
refreshPluginMarketplace: async (marketplaceName) => {
|
|
18365
19607
|
try {
|
|
18366
|
-
if (this.provider && "
|
|
18367
|
-
const result = await this.provider.
|
|
18368
|
-
this.logger?.info("
|
|
18369
|
-
pluginNames,
|
|
19608
|
+
if (this.provider && "refreshPluginMarketplace" in this.provider && typeof this.provider.refreshPluginMarketplace === "function") {
|
|
19609
|
+
const result = await this.provider.refreshPluginMarketplace(marketplaceName);
|
|
19610
|
+
this.logger?.info("Refresh plugin marketplace", {
|
|
18370
19611
|
marketplaceName,
|
|
18371
19612
|
success: result.success
|
|
18372
19613
|
});
|
|
18373
19614
|
return result;
|
|
18374
19615
|
}
|
|
18375
|
-
this.logger?.warn("Provider does not support
|
|
19616
|
+
this.logger?.warn("Provider does not support refreshPluginMarketplace");
|
|
18376
19617
|
return {
|
|
18377
19618
|
success: false,
|
|
18378
|
-
error: "Provider does not support
|
|
19619
|
+
error: "Provider does not support refreshPluginMarketplace"
|
|
18379
19620
|
};
|
|
18380
19621
|
} catch (error) {
|
|
18381
|
-
this.logger?.error("Failed to
|
|
19622
|
+
this.logger?.error("Failed to refresh plugin marketplace", error);
|
|
18382
19623
|
return {
|
|
18383
19624
|
success: false,
|
|
18384
19625
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
18385
19626
|
};
|
|
18386
19627
|
}
|
|
18387
19628
|
},
|
|
18388
|
-
|
|
19629
|
+
openFolderInNewWindow: async (folderPath) => {
|
|
19630
|
+
try {
|
|
19631
|
+
if (this.provider && "openFolderInNewWindow" in this.provider && typeof this.provider.openFolderInNewWindow === "function") {
|
|
19632
|
+
await this.provider.openFolderInNewWindow(folderPath);
|
|
19633
|
+
this.logger?.info("Opened folder in new window", { folderPath });
|
|
19634
|
+
} else {
|
|
19635
|
+
this.logger?.warn("Provider does not support openFolderInNewWindow");
|
|
19636
|
+
throw new Error("Provider does not support openFolderInNewWindow");
|
|
19637
|
+
}
|
|
19638
|
+
} catch (error) {
|
|
19639
|
+
this.logger?.error("Failed to open folder in new window", error);
|
|
19640
|
+
throw error;
|
|
19641
|
+
}
|
|
19642
|
+
},
|
|
19643
|
+
openFolder: async (folderPath) => {
|
|
18389
19644
|
try {
|
|
18390
|
-
if (this.provider && "
|
|
18391
|
-
const result = await this.provider.
|
|
18392
|
-
this.logger?.info("
|
|
19645
|
+
if (this.provider && "openFolder" in this.provider && typeof this.provider.openFolder === "function") {
|
|
19646
|
+
const result = await this.provider.openFolder(folderPath);
|
|
19647
|
+
this.logger?.info("Opened folder in system file manager", { folderPath });
|
|
18393
19648
|
return result;
|
|
19649
|
+
} else {
|
|
19650
|
+
this.logger?.warn("Provider does not support openFolder");
|
|
19651
|
+
throw new Error("Provider does not support openFolder");
|
|
18394
19652
|
}
|
|
19653
|
+
} catch (error) {
|
|
19654
|
+
this.logger?.error("Failed to open folder", error);
|
|
19655
|
+
throw error;
|
|
19656
|
+
}
|
|
19657
|
+
},
|
|
19658
|
+
getSupportScenes: async (locale) => {
|
|
19659
|
+
try {
|
|
19660
|
+
if (this.provider && "getSupportScenes" in this.provider && typeof this.provider.getSupportScenes === "function") return await this.provider.getSupportScenes(locale);
|
|
18395
19661
|
this.logger?.warn("Provider does not support getSupportScenes");
|
|
18396
19662
|
return [];
|
|
18397
19663
|
} catch (error) {
|
|
@@ -18399,23 +19665,193 @@ var AgentClient = class {
|
|
|
18399
19665
|
return [];
|
|
18400
19666
|
}
|
|
18401
19667
|
},
|
|
18402
|
-
|
|
19668
|
+
getProductScenes: async (locale) => {
|
|
19669
|
+
try {
|
|
19670
|
+
if (this.provider?.getProductScenes) {
|
|
19671
|
+
const result = await this.provider.getProductScenes(locale);
|
|
19672
|
+
this.logger?.info("Got product scenes", { count: result?.length ?? 0 });
|
|
19673
|
+
return result;
|
|
19674
|
+
}
|
|
19675
|
+
this.logger?.warn("Provider does not support getProductScenes");
|
|
19676
|
+
return [];
|
|
19677
|
+
} catch (error) {
|
|
19678
|
+
this.logger?.error("Failed to get product scenes", error);
|
|
19679
|
+
return [];
|
|
19680
|
+
}
|
|
19681
|
+
},
|
|
19682
|
+
getAvailableCommands: async (params) => {
|
|
18403
19683
|
try {
|
|
18404
19684
|
if (this.provider && "getAvailableCommands" in this.provider && typeof this.provider.getAvailableCommands === "function") {
|
|
18405
|
-
const result = await this.provider.getAvailableCommands(
|
|
19685
|
+
const result = await this.provider.getAvailableCommands(params);
|
|
18406
19686
|
this.logger?.info("Got available commands from provider", {
|
|
18407
|
-
sessionId: sessionId ?? "(default)",
|
|
19687
|
+
sessionId: params?.sessionId ?? "(default)",
|
|
18408
19688
|
count: result?.length ?? 0
|
|
18409
19689
|
});
|
|
18410
19690
|
return result;
|
|
18411
19691
|
}
|
|
18412
|
-
this.logger?.warn("Provider does not support getAvailableCommands", {
|
|
19692
|
+
this.logger?.warn("Provider does not support getAvailableCommands", { params });
|
|
18413
19693
|
return [];
|
|
18414
19694
|
} catch (error) {
|
|
18415
19695
|
this.logger?.error("Failed to get available commands", error);
|
|
18416
19696
|
return [];
|
|
18417
19697
|
}
|
|
18418
19698
|
},
|
|
19699
|
+
reportTelemetry: async (eventName, payload) => {
|
|
19700
|
+
try {
|
|
19701
|
+
if (this.provider?.reportTelemetry) await this.provider.reportTelemetry(eventName, payload);
|
|
19702
|
+
else this.logger?.warn("Provider does not support reportTelemetry");
|
|
19703
|
+
} catch (error) {
|
|
19704
|
+
this.logger?.error("Failed to report telemetry", error);
|
|
19705
|
+
}
|
|
19706
|
+
},
|
|
19707
|
+
getProductConfiguration: async () => {
|
|
19708
|
+
try {
|
|
19709
|
+
if (this.provider?.getProductConfiguration) return await this.provider.getProductConfiguration();
|
|
19710
|
+
this.logger?.warn("Provider does not support getProductConfiguration");
|
|
19711
|
+
return {};
|
|
19712
|
+
} catch (error) {
|
|
19713
|
+
this.logger?.error("Failed to get product configuration", error);
|
|
19714
|
+
return {};
|
|
19715
|
+
}
|
|
19716
|
+
},
|
|
19717
|
+
getUserInfo: async () => {
|
|
19718
|
+
this.logger?.info("[AgentClient.sessions] getUserInfo() called");
|
|
19719
|
+
try {
|
|
19720
|
+
if (this.provider?.getUserInfo) {
|
|
19721
|
+
const result = await this.provider.getUserInfo();
|
|
19722
|
+
this.logger?.info("[AgentClient.sessions] getUserInfo() result:", JSON.stringify(result));
|
|
19723
|
+
return result;
|
|
19724
|
+
}
|
|
19725
|
+
this.logger?.warn("Provider does not support getUserInfo");
|
|
19726
|
+
return {};
|
|
19727
|
+
} catch (error) {
|
|
19728
|
+
this.logger?.error("Failed to get user info", error);
|
|
19729
|
+
return {};
|
|
19730
|
+
}
|
|
19731
|
+
},
|
|
19732
|
+
respondToSampling: async (sessionId, response) => {
|
|
19733
|
+
try {
|
|
19734
|
+
if (this.provider?.respondToSampling) {
|
|
19735
|
+
await this.provider.respondToSampling(sessionId, response);
|
|
19736
|
+
this.logger?.info("Responded to sampling request", {
|
|
19737
|
+
sessionId,
|
|
19738
|
+
requestId: response.id,
|
|
19739
|
+
approved: response.approved
|
|
19740
|
+
});
|
|
19741
|
+
} else this.logger?.warn("Provider does not support respondToSampling");
|
|
19742
|
+
} catch (error) {
|
|
19743
|
+
this.logger?.error("Failed to respond to sampling request", error);
|
|
19744
|
+
throw error;
|
|
19745
|
+
}
|
|
19746
|
+
},
|
|
19747
|
+
respondToRoots: async (sessionId, response) => {
|
|
19748
|
+
try {
|
|
19749
|
+
if (this.provider?.respondToRoots) {
|
|
19750
|
+
await this.provider.respondToRoots(sessionId, response);
|
|
19751
|
+
this.logger?.info("Responded to roots request", {
|
|
19752
|
+
sessionId,
|
|
19753
|
+
requestId: response.id,
|
|
19754
|
+
approved: response.approved
|
|
19755
|
+
});
|
|
19756
|
+
} else this.logger?.warn("Provider does not support respondToRoots");
|
|
19757
|
+
} catch (error) {
|
|
19758
|
+
this.logger?.error("Failed to respond to roots request", error);
|
|
19759
|
+
throw error;
|
|
19760
|
+
}
|
|
19761
|
+
},
|
|
19762
|
+
subscribeSamplingRequests: (serverName, callback) => {
|
|
19763
|
+
if (this.provider?.subscribeSamplingRequests) {
|
|
19764
|
+
this.logger?.info("Subscribing to sampling requests", { serverName });
|
|
19765
|
+
return this.provider.subscribeSamplingRequests(serverName, callback);
|
|
19766
|
+
}
|
|
19767
|
+
this.logger?.warn("Provider does not support subscribeSamplingRequests");
|
|
19768
|
+
return () => {};
|
|
19769
|
+
},
|
|
19770
|
+
subscribeRootsRequests: (serverName, callback) => {
|
|
19771
|
+
if (this.provider?.subscribeRootsRequests) {
|
|
19772
|
+
this.logger?.info("Subscribing to roots requests", { serverName });
|
|
19773
|
+
return this.provider.subscribeRootsRequests(serverName, callback);
|
|
19774
|
+
}
|
|
19775
|
+
this.logger?.warn("Provider does not support subscribeRootsRequests");
|
|
19776
|
+
return () => {};
|
|
19777
|
+
},
|
|
19778
|
+
getMcpServers: async () => {
|
|
19779
|
+
if (this.provider?.getMcpServers) {
|
|
19780
|
+
this.logger?.info("Getting MCP servers list");
|
|
19781
|
+
return this.provider.getMcpServers();
|
|
19782
|
+
}
|
|
19783
|
+
this.logger?.warn("Provider does not support getMcpServers");
|
|
19784
|
+
return [];
|
|
19785
|
+
},
|
|
19786
|
+
toggleMcpServer: async (serverName, enabled) => {
|
|
19787
|
+
if (this.provider?.toggleMcpServer) {
|
|
19788
|
+
this.logger?.info("Toggling MCP server", {
|
|
19789
|
+
serverName,
|
|
19790
|
+
enabled
|
|
19791
|
+
});
|
|
19792
|
+
await this.provider.toggleMcpServer(serverName, enabled);
|
|
19793
|
+
} else {
|
|
19794
|
+
this.logger?.warn("Provider does not support toggleMcpServer");
|
|
19795
|
+
throw new Error("toggleMcpServer not supported by provider");
|
|
19796
|
+
}
|
|
19797
|
+
},
|
|
19798
|
+
reconnectMcpServer: async (serverName, forceHttpCallback) => {
|
|
19799
|
+
if (this.provider?.reconnectMcpServer) {
|
|
19800
|
+
this.logger?.info("Reconnecting MCP server", {
|
|
19801
|
+
serverName,
|
|
19802
|
+
forceHttpCallback
|
|
19803
|
+
});
|
|
19804
|
+
await this.provider.reconnectMcpServer(serverName, forceHttpCallback);
|
|
19805
|
+
} else {
|
|
19806
|
+
this.logger?.warn("Provider does not support reconnectMcpServer");
|
|
19807
|
+
throw new Error("reconnectMcpServer not supported by provider");
|
|
19808
|
+
}
|
|
19809
|
+
},
|
|
19810
|
+
deleteMcpServer: async (serverName) => {
|
|
19811
|
+
if (this.provider?.deleteMcpServer) {
|
|
19812
|
+
this.logger?.info("Deleting MCP server", { serverName });
|
|
19813
|
+
await this.provider.deleteMcpServer(serverName);
|
|
19814
|
+
} else {
|
|
19815
|
+
this.logger?.warn("Provider does not support deleteMcpServer");
|
|
19816
|
+
throw new Error("deleteMcpServer not supported by provider");
|
|
19817
|
+
}
|
|
19818
|
+
},
|
|
19819
|
+
openMcpConfig: async () => {
|
|
19820
|
+
if (this.provider?.openMcpConfig) {
|
|
19821
|
+
this.logger?.info("Opening MCP config");
|
|
19822
|
+
await this.provider.openMcpConfig();
|
|
19823
|
+
} else {
|
|
19824
|
+
this.logger?.warn("Provider does not support openMcpConfig");
|
|
19825
|
+
throw new Error("openMcpConfig not supported by provider");
|
|
19826
|
+
}
|
|
19827
|
+
},
|
|
19828
|
+
getMcpConfigContent: async () => {
|
|
19829
|
+
if (this.provider?.getMcpConfigContent) {
|
|
19830
|
+
this.logger?.info("Getting MCP config content");
|
|
19831
|
+
return await this.provider.getMcpConfigContent();
|
|
19832
|
+
} else {
|
|
19833
|
+
this.logger?.warn("Provider does not support getMcpConfigContent");
|
|
19834
|
+
throw new Error("getMcpConfigContent not supported by provider");
|
|
19835
|
+
}
|
|
19836
|
+
},
|
|
19837
|
+
saveMcpConfigContent: async (content) => {
|
|
19838
|
+
if (this.provider?.saveMcpConfigContent) {
|
|
19839
|
+
this.logger?.info("Saving MCP config content");
|
|
19840
|
+
await this.provider.saveMcpConfigContent(content);
|
|
19841
|
+
} else {
|
|
19842
|
+
this.logger?.warn("Provider does not support saveMcpConfigContent");
|
|
19843
|
+
throw new Error("saveMcpConfigContent not supported by provider");
|
|
19844
|
+
}
|
|
19845
|
+
},
|
|
19846
|
+
clipboardReadText: async () => {
|
|
19847
|
+
if (this.provider?.clipboardReadText) {
|
|
19848
|
+
this.logger?.info("Reading clipboard text");
|
|
19849
|
+
return await this.provider.clipboardReadText();
|
|
19850
|
+
} else {
|
|
19851
|
+
this.logger?.warn("Provider does not support clipboardReadText");
|
|
19852
|
+
throw new Error("clipboardReadText not supported by provider");
|
|
19853
|
+
}
|
|
19854
|
+
},
|
|
18419
19855
|
models: this.createModelsResource()
|
|
18420
19856
|
};
|
|
18421
19857
|
}
|
|
@@ -18641,10 +20077,6 @@ const oauthRepositoryService = new OAuthRepositoryService();
|
|
|
18641
20077
|
* 判断当前账号是否是 SSO 账号
|
|
18642
20078
|
* 通过 account.accountType === 'sso' 来判断,这种不行,因为未登录之前account 为空
|
|
18643
20079
|
*/
|
|
18644
|
-
const isSSODomain = () => {
|
|
18645
|
-
const { hostname } = window.location;
|
|
18646
|
-
return hostname.includes(".sso.copilot") || hostname.includes("sso.codebuddy.cn") || hostname.includes(".sso.copilot-staging") || hostname.includes(".staging-sso.codebuddy.cn");
|
|
18647
|
-
};
|
|
18648
20080
|
/**
|
|
18649
20081
|
* 根据路径获取完整 URL
|
|
18650
20082
|
* - SSO 账号需要跳转到对应的预发/生产域名
|
|
@@ -18652,16 +20084,7 @@ const isSSODomain = () => {
|
|
|
18652
20084
|
* @param path 路径,如 '/login'、'/logout'、'/home' 等
|
|
18653
20085
|
* @returns 完整的 URL 地址
|
|
18654
20086
|
*/
|
|
18655
|
-
const getFullUrl = (path) => {
|
|
18656
|
-
const { hostname, protocol } = window.location;
|
|
18657
|
-
if (isSSODomain()) {
|
|
18658
|
-
const isCodebuddy = hostname.includes("codebuddy.cn");
|
|
18659
|
-
const isStaging = hostname.includes("staging");
|
|
18660
|
-
if (isCodebuddy) return isStaging ? `${protocol}//staging.codebuddy.cn${path}` : `${protocol}//www.codebuddy.cn${path}`;
|
|
18661
|
-
else return isStaging ? `${protocol}//staging-copilot.tencent.com${path}` : `${protocol}//copilot.tencent.com${path}`;
|
|
18662
|
-
}
|
|
18663
|
-
return `${window.location.origin}${path}`;
|
|
18664
|
-
};
|
|
20087
|
+
const getFullUrl = (path) => `${window.location.origin}${path}`;
|
|
18665
20088
|
/** 获取当前域名的账号选择页面 URL */
|
|
18666
20089
|
const getSelectAccountUrl = () => `${window.location.origin}/login/select`;
|
|
18667
20090
|
/** localStorage 中存储选中账号 ID 的 key */
|
|
@@ -18694,16 +20117,34 @@ const getPackageName = (packageCode) => CommodityCodeText[packageCode] || "";
|
|
|
18694
20117
|
* 注意:getAgents 和 getModels 方法已废弃并移除,
|
|
18695
20118
|
* 请使用 IAgentAdapter 中的对应方法
|
|
18696
20119
|
*/
|
|
18697
|
-
var BackendProvider = class {
|
|
20120
|
+
var BackendProvider = class BackendProvider {
|
|
18698
20121
|
constructor(config) {
|
|
18699
20122
|
httpService.setBaseURL(config.baseUrl);
|
|
18700
20123
|
if (config.authToken) httpService.setAuthToken(config.authToken);
|
|
18701
|
-
httpService.onUnauthorized(() =>
|
|
18702
|
-
|
|
18703
|
-
|
|
18704
|
-
|
|
20124
|
+
httpService.onUnauthorized(() => this.handleUnauthorized());
|
|
20125
|
+
}
|
|
20126
|
+
/**
|
|
20127
|
+
* 处理 401 未授权错误
|
|
20128
|
+
* 先尝试刷新 token,失败后再执行登出流程
|
|
20129
|
+
*
|
|
20130
|
+
* @throws 如果 token 刷新失败,抛出错误通知 HttpService 不要重试
|
|
20131
|
+
*/
|
|
20132
|
+
async handleUnauthorized() {
|
|
20133
|
+
console.log("[BackendProvider] User unauthorized (401), attempting token refresh first");
|
|
20134
|
+
try {
|
|
20135
|
+
if (await this.refreshToken()) {
|
|
20136
|
+
console.log("[BackendProvider] Token refresh successful after 401, user still logged in");
|
|
20137
|
+
return;
|
|
20138
|
+
}
|
|
20139
|
+
throw new Error("Token refresh returned null");
|
|
20140
|
+
} catch (error) {
|
|
20141
|
+
console.error("[BackendProvider] Token refresh failed after 401:", error);
|
|
20142
|
+
console.log("[BackendProvider] Token refresh failed, triggering logout");
|
|
20143
|
+
this.logout().catch((logoutError) => {
|
|
20144
|
+
console.error("[BackendProvider] Logout failed in 401 handler:", logoutError);
|
|
18705
20145
|
});
|
|
18706
|
-
|
|
20146
|
+
throw error;
|
|
20147
|
+
}
|
|
18707
20148
|
}
|
|
18708
20149
|
/**
|
|
18709
20150
|
* 获取当前账号信息
|
|
@@ -18967,10 +20408,11 @@ var BackendProvider = class {
|
|
|
18967
20408
|
if (!time) return 0;
|
|
18968
20409
|
return new Date(time).getTime();
|
|
18969
20410
|
};
|
|
18970
|
-
const dailyCredits = [CommodityCode.free
|
|
20411
|
+
const dailyCredits = [CommodityCode.free];
|
|
18971
20412
|
const planResources = resources.map((r) => {
|
|
18972
20413
|
const isDaily = dailyCredits.includes(r.PackageCode);
|
|
18973
20414
|
const endTime = isDaily ? r.CycleEndTime : r.DeductionEndTime;
|
|
20415
|
+
const refreshAt = parseTime(r.CycleEndTime) + 1e3;
|
|
18974
20416
|
return {
|
|
18975
20417
|
id: r.ResourceId,
|
|
18976
20418
|
name: isDaily ? "plan.addonCredits" : getPackageName(r.PackageCode),
|
|
@@ -18980,7 +20422,7 @@ var BackendProvider = class {
|
|
|
18980
20422
|
used: Math.max(0, Number(r.CycleCapacitySizePrecise) - Number(r.CycleCapacityRemainPrecise)) || 0,
|
|
18981
20423
|
left: Number(r.CycleCapacityRemainPrecise) || 0,
|
|
18982
20424
|
expireAt: parseTime(endTime),
|
|
18983
|
-
refreshAt: isDaily ? void 0 :
|
|
20425
|
+
refreshAt: isDaily ? void 0 : refreshAt
|
|
18984
20426
|
};
|
|
18985
20427
|
}).sort((a, b) => {
|
|
18986
20428
|
const getPriority = (code) => {
|
|
@@ -18988,10 +20430,11 @@ var BackendProvider = class {
|
|
|
18988
20430
|
CommodityCode.proMon,
|
|
18989
20431
|
CommodityCode.proMonPlus,
|
|
18990
20432
|
CommodityCode.proYear,
|
|
20433
|
+
CommodityCode.freeMon,
|
|
18991
20434
|
CommodityCode.extra
|
|
18992
20435
|
].includes(code)) return 1;
|
|
18993
20436
|
if ([CommodityCode.gift, CommodityCode.activity].includes(code)) return 2;
|
|
18994
|
-
if ([CommodityCode.free
|
|
20437
|
+
if ([CommodityCode.free].includes(code)) return 3;
|
|
18995
20438
|
return 4;
|
|
18996
20439
|
};
|
|
18997
20440
|
return getPriority(a.packageCode) - getPriority(b.packageCode);
|
|
@@ -19116,34 +20559,65 @@ var BackendProvider = class {
|
|
|
19116
20559
|
}
|
|
19117
20560
|
/**
|
|
19118
20561
|
* 登出账号
|
|
19119
|
-
*
|
|
20562
|
+
*
|
|
20563
|
+
* 策略:
|
|
20564
|
+
* - IOA 企业:用 iframe 走 SSO/SAML SLO 登出链路(涉及跨域重定向),通过轮询 iframe URL 变化检测完成
|
|
20565
|
+
* - 非 IOA 企业:直接用 httpService 请求 /console/logout,速度快
|
|
19120
20566
|
*/
|
|
19121
20567
|
async logout() {
|
|
19122
|
-
const
|
|
20568
|
+
const account = accountService.getAccount();
|
|
20569
|
+
if (account?.enterpriseId && ["esoikz80kd8g", "etahzsqej0n4"].includes(account.enterpriseId)) await this.logoutViaIframe();
|
|
20570
|
+
else await this.logoutViaHttp();
|
|
20571
|
+
localStorage.removeItem(SELECTED_ACCOUNT_KEY);
|
|
20572
|
+
accountService.clearAccount();
|
|
20573
|
+
}
|
|
20574
|
+
/**
|
|
20575
|
+
* IOA 企业登出:通过 iframe 走 SSO/SAML SLO 登出链路
|
|
20576
|
+
* 轮询 iframe URL 变化检测完成,兜底超时 5 秒
|
|
20577
|
+
*/
|
|
20578
|
+
async logoutViaIframe() {
|
|
20579
|
+
const logoutUrl = `${httpService.getAxiosInstance().defaults.baseURL}/console/logout`;
|
|
19123
20580
|
try {
|
|
19124
20581
|
await new Promise((resolve) => {
|
|
19125
20582
|
const iframe = document.createElement("iframe");
|
|
19126
20583
|
iframe.style.cssText = "position:fixed;top:-9999px;left:-9999px;width:1px;height:1px;border:none;";
|
|
19127
|
-
iframe.src =
|
|
19128
|
-
|
|
19129
|
-
|
|
19130
|
-
|
|
19131
|
-
|
|
19132
|
-
|
|
20584
|
+
iframe.src = logoutUrl;
|
|
20585
|
+
let pollTimer;
|
|
20586
|
+
let settled = false;
|
|
20587
|
+
const done = () => {
|
|
20588
|
+
if (settled) return;
|
|
20589
|
+
settled = true;
|
|
20590
|
+
clearInterval(pollTimer);
|
|
19133
20591
|
clearTimeout(timeout);
|
|
19134
20592
|
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
|
|
19135
|
-
};
|
|
19136
|
-
iframe.onerror = () => {
|
|
19137
|
-
cleanup();
|
|
19138
20593
|
resolve();
|
|
19139
20594
|
};
|
|
20595
|
+
let wasRedirecting = false;
|
|
20596
|
+
pollTimer = setInterval(() => {
|
|
20597
|
+
try {
|
|
20598
|
+
const href = iframe.contentWindow?.location?.href;
|
|
20599
|
+
if (wasRedirecting && href) done();
|
|
20600
|
+
} catch {
|
|
20601
|
+
wasRedirecting = true;
|
|
20602
|
+
}
|
|
20603
|
+
}, 100);
|
|
20604
|
+
const timeout = setTimeout(done, 5e3);
|
|
20605
|
+
iframe.onerror = done;
|
|
19140
20606
|
document.body.appendChild(iframe);
|
|
19141
20607
|
});
|
|
19142
20608
|
} catch (error) {
|
|
19143
|
-
console.error("[BackendProvider] logout failed:", error);
|
|
20609
|
+
console.error("[BackendProvider] logout via iframe failed:", error);
|
|
20610
|
+
}
|
|
20611
|
+
}
|
|
20612
|
+
/**
|
|
20613
|
+
* 非 IOA 企业登出:直接 HTTP 请求 /console/logout
|
|
20614
|
+
*/
|
|
20615
|
+
async logoutViaHttp() {
|
|
20616
|
+
try {
|
|
20617
|
+
await httpService.get("/console/logout");
|
|
20618
|
+
} catch (error) {
|
|
20619
|
+
console.error("[BackendProvider] logout via http failed:", error);
|
|
19144
20620
|
}
|
|
19145
|
-
localStorage.removeItem(SELECTED_ACCOUNT_KEY);
|
|
19146
|
-
accountService.clearAccount();
|
|
19147
20621
|
}
|
|
19148
20622
|
/**
|
|
19149
20623
|
* 批量切换插件状态
|
|
@@ -19221,6 +20695,132 @@ var BackendProvider = class {
|
|
|
19221
20695
|
async getRepositories(connector, page = 0, perPage = 100) {
|
|
19222
20696
|
return oauthRepositoryService.getRepositories(connector, page, perPage);
|
|
19223
20697
|
}
|
|
20698
|
+
/**
|
|
20699
|
+
* 保存待发送的输入内容到后端
|
|
20700
|
+
* API 端点: POST /api/v1/code-id
|
|
20701
|
+
*/
|
|
20702
|
+
async savePendingInput(code) {
|
|
20703
|
+
try {
|
|
20704
|
+
const result = await httpService.post("/api/v1/code-id", { code });
|
|
20705
|
+
return result?.codeId || result?.data?.codeId || null;
|
|
20706
|
+
} catch (e) {
|
|
20707
|
+
console.warn("[BackendProvider] savePendingInput failed:", e);
|
|
20708
|
+
return null;
|
|
20709
|
+
}
|
|
20710
|
+
}
|
|
20711
|
+
/**
|
|
20712
|
+
* 从后端加载待发送的输入内容
|
|
20713
|
+
* API 端点: GET /api/v1/code?id=xxx
|
|
20714
|
+
*/
|
|
20715
|
+
async loadPendingInput(codeId) {
|
|
20716
|
+
try {
|
|
20717
|
+
const result = await httpService.get(`/api/v1/code?id=${encodeURIComponent(codeId)}`);
|
|
20718
|
+
return result?.code || result?.data?.code || null;
|
|
20719
|
+
} catch (e) {
|
|
20720
|
+
console.warn("[BackendProvider] loadPendingInput failed:", e);
|
|
20721
|
+
return null;
|
|
20722
|
+
}
|
|
20723
|
+
}
|
|
20724
|
+
/**
|
|
20725
|
+
* 获取每日签到状态
|
|
20726
|
+
* API 端点: POST /billing/meter/checkin-status
|
|
20727
|
+
*/
|
|
20728
|
+
async getCheckinStatus() {
|
|
20729
|
+
try {
|
|
20730
|
+
const result = await httpService.post("/billing/meter/checkin-status", {});
|
|
20731
|
+
if (result?.code === 0 && result?.data) return result.data;
|
|
20732
|
+
return null;
|
|
20733
|
+
} catch (error) {
|
|
20734
|
+
console.error("[BackendProvider] getCheckinStatus failed:", error);
|
|
20735
|
+
return null;
|
|
20736
|
+
}
|
|
20737
|
+
}
|
|
20738
|
+
/**
|
|
20739
|
+
* 执行每日签到
|
|
20740
|
+
* API 端点: POST /billing/meter/daily-checkin
|
|
20741
|
+
*/
|
|
20742
|
+
async claimDailyCheckin() {
|
|
20743
|
+
const result = await httpService.post("/billing/meter/daily-checkin", {});
|
|
20744
|
+
if (result?.code === 0 && result?.data) return result.data;
|
|
20745
|
+
throw new Error(result?.msg || "Checkin failed");
|
|
20746
|
+
}
|
|
20747
|
+
static {
|
|
20748
|
+
this.SKILLHUB_BASE_URL = "https://lightmake.site";
|
|
20749
|
+
}
|
|
20750
|
+
static {
|
|
20751
|
+
this.SKILLHUB_FETCH_TIMEOUT = 1e4;
|
|
20752
|
+
}
|
|
20753
|
+
async skillHubFetch(url, init) {
|
|
20754
|
+
const controller = new AbortController();
|
|
20755
|
+
const timer = setTimeout(() => controller.abort(), BackendProvider.SKILLHUB_FETCH_TIMEOUT);
|
|
20756
|
+
try {
|
|
20757
|
+
return await fetch(url, {
|
|
20758
|
+
...init,
|
|
20759
|
+
signal: controller.signal
|
|
20760
|
+
});
|
|
20761
|
+
} finally {
|
|
20762
|
+
clearTimeout(timer);
|
|
20763
|
+
}
|
|
20764
|
+
}
|
|
20765
|
+
async getSkillHubList(params = {}) {
|
|
20766
|
+
const qs = new URLSearchParams();
|
|
20767
|
+
if (params.page) qs.set("page", String(params.page));
|
|
20768
|
+
if (params.pageSize) qs.set("pageSize", String(params.pageSize));
|
|
20769
|
+
if (params.sortBy) qs.set("sortBy", params.sortBy);
|
|
20770
|
+
if (params.order) qs.set("order", params.order);
|
|
20771
|
+
if (params.keyword) qs.set("keyword", params.keyword);
|
|
20772
|
+
if (params.category) qs.set("category", params.category);
|
|
20773
|
+
const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/skills?${qs.toString()}`);
|
|
20774
|
+
if (!res.ok) throw new Error(`SkillHub list: ${res.status}`);
|
|
20775
|
+
return res.json();
|
|
20776
|
+
}
|
|
20777
|
+
async getSkillHubCategories() {
|
|
20778
|
+
const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/categories`);
|
|
20779
|
+
if (!res.ok) throw new Error(`SkillHub categories: ${res.status}`);
|
|
20780
|
+
return res.json();
|
|
20781
|
+
}
|
|
20782
|
+
async getSkillHubSearch(q, limit = 20) {
|
|
20783
|
+
const qs = new URLSearchParams({
|
|
20784
|
+
q,
|
|
20785
|
+
limit: String(limit)
|
|
20786
|
+
});
|
|
20787
|
+
const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/search?${qs.toString()}`);
|
|
20788
|
+
if (!res.ok) throw new Error(`SkillHub search: ${res.status}`);
|
|
20789
|
+
return res.json();
|
|
20790
|
+
}
|
|
20791
|
+
async getSkillHubDetail(slug) {
|
|
20792
|
+
const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/skills/${encodeURIComponent(slug)}`);
|
|
20793
|
+
if (!res.ok) throw new Error(`SkillHub detail: ${res.status}`);
|
|
20794
|
+
return res.json();
|
|
20795
|
+
}
|
|
20796
|
+
async getSkillHubExists(slugs) {
|
|
20797
|
+
const res = await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/skills/exists`, {
|
|
20798
|
+
method: "POST",
|
|
20799
|
+
headers: { "Content-Type": "application/json" },
|
|
20800
|
+
body: JSON.stringify({ slugs })
|
|
20801
|
+
});
|
|
20802
|
+
if (!res.ok) throw new Error(`SkillHub exists: ${res.status}`);
|
|
20803
|
+
return res.json();
|
|
20804
|
+
}
|
|
20805
|
+
async reportSkillHubStats(slug, inc) {
|
|
20806
|
+
try {
|
|
20807
|
+
await this.skillHubFetch(`${BackendProvider.SKILLHUB_BASE_URL}/api/v1/skills/${encodeURIComponent(slug)}/stats/inc`, {
|
|
20808
|
+
method: "POST",
|
|
20809
|
+
headers: { "Content-Type": "application/json" },
|
|
20810
|
+
body: JSON.stringify(inc)
|
|
20811
|
+
});
|
|
20812
|
+
} catch {}
|
|
20813
|
+
}
|
|
20814
|
+
async installSkillHubSkill(_slug, _version, _name) {
|
|
20815
|
+
return {
|
|
20816
|
+
success: false,
|
|
20817
|
+
skillName: _slug,
|
|
20818
|
+
errorMessage: "SkillHub install requires IDE mode (no IPC channel available)"
|
|
20819
|
+
};
|
|
20820
|
+
}
|
|
20821
|
+
async getSkillHubInstalledMetas() {
|
|
20822
|
+
return [];
|
|
20823
|
+
}
|
|
19224
20824
|
};
|
|
19225
20825
|
/**
|
|
19226
20826
|
* 创建 BackendProvider 实例
|
|
@@ -19259,10 +20859,21 @@ const BACKEND_REQUEST_TYPES = {
|
|
|
19259
20859
|
REVOKE_ALL: "backend:revoke-all",
|
|
19260
20860
|
GET_FILE: "backend:get-file",
|
|
19261
20861
|
RELOAD_WINDOW: "backend:reload-window",
|
|
20862
|
+
SAVE_LOCALE: "backend:save-locale",
|
|
19262
20863
|
CLOSE_AGENT_MANAGER: "backend:close-agent-manager",
|
|
19263
20864
|
OPEN_EXTERNAL: "backend:open-external",
|
|
19264
20865
|
BATCH_TOGGLE_PLUGINS: "backend:batch-toggle-plugins",
|
|
19265
|
-
GET_SUPPORT_SCENES: "backend:get-support-scenes"
|
|
20866
|
+
GET_SUPPORT_SCENES: "backend:get-support-scenes",
|
|
20867
|
+
GET_ACCOUNT_USAGE: "backend:get-account-usage",
|
|
20868
|
+
GET_CHECKIN_STATUS: "backend:get-checkin-status",
|
|
20869
|
+
CLAIM_DAILY_CHECKIN: "backend:claim-daily-checkin",
|
|
20870
|
+
SKILLHUB_LIST: "backend:skillhub-list",
|
|
20871
|
+
SKILLHUB_CATEGORIES: "backend:skillhub-categories",
|
|
20872
|
+
SKILLHUB_SEARCH: "backend:skillhub-search",
|
|
20873
|
+
SKILLHUB_DETAIL: "backend:skillhub-detail",
|
|
20874
|
+
SKILLHUB_DOWNLOAD_URL: "backend:skillhub-download-url",
|
|
20875
|
+
SKILLHUB_EXISTS: "backend:skillhub-exists",
|
|
20876
|
+
SKILLHUB_REPORT_STATS: "backend:skillhub-report-stats"
|
|
19266
20877
|
};
|
|
19267
20878
|
/**
|
|
19268
20879
|
* 生成唯一请求 ID
|
|
@@ -19309,12 +20920,14 @@ var IPCBackendProvider = class {
|
|
|
19309
20920
|
*/
|
|
19310
20921
|
async getAccount() {
|
|
19311
20922
|
this.log("Getting account via IPC");
|
|
20923
|
+
const startTime = performance.now();
|
|
19312
20924
|
try {
|
|
19313
20925
|
const account = await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_ACCOUNT);
|
|
20926
|
+
this.log(`getAccount IPC completed in ${(performance.now() - startTime).toFixed(0)}ms`);
|
|
19314
20927
|
accountService.setAccount(account);
|
|
19315
20928
|
return account;
|
|
19316
20929
|
} catch (error) {
|
|
19317
|
-
this.log(
|
|
20930
|
+
this.log(`getAccount IPC failed after ${(performance.now() - startTime).toFixed(0)}ms:`, error);
|
|
19318
20931
|
accountService.setAccount(null);
|
|
19319
20932
|
return null;
|
|
19320
20933
|
}
|
|
@@ -19543,6 +21156,20 @@ var IPCBackendProvider = class {
|
|
|
19543
21156
|
}
|
|
19544
21157
|
}
|
|
19545
21158
|
/**
|
|
21159
|
+
* Save locale to argv.json without restarting the app.
|
|
21160
|
+
* The change takes effect on next manual restart.
|
|
21161
|
+
* @param params locale to save
|
|
21162
|
+
*/
|
|
21163
|
+
async saveLocale(params) {
|
|
21164
|
+
this.log("Saving locale to argv.json via IPC", params);
|
|
21165
|
+
try {
|
|
21166
|
+
await this.sendBackendRequest(BACKEND_REQUEST_TYPES.SAVE_LOCALE, params);
|
|
21167
|
+
} catch (error) {
|
|
21168
|
+
this.log("Save locale request failed:", error);
|
|
21169
|
+
throw error;
|
|
21170
|
+
}
|
|
21171
|
+
}
|
|
21172
|
+
/**
|
|
19546
21173
|
* 关闭 Agent Manager 面板
|
|
19547
21174
|
* IDE 环境: 通过 IPC 通知 IDE 关闭 Agent Manager(用于返回 IDE)
|
|
19548
21175
|
*/
|
|
@@ -19603,6 +21230,174 @@ var IPCBackendProvider = class {
|
|
|
19603
21230
|
}
|
|
19604
21231
|
}
|
|
19605
21232
|
/**
|
|
21233
|
+
* 获取账号用量信息(积分/Credits)
|
|
21234
|
+
* IDE 环境: 通过 IPC 实时获取用量信息,每次打开菜单时调用
|
|
21235
|
+
*
|
|
21236
|
+
* 调用链:
|
|
21237
|
+
* 1. agent-ui: IPCBackendProvider.getAccountUsage()
|
|
21238
|
+
* 2. Agent Manager renderer: BackendService.getAccountUsage()
|
|
21239
|
+
* 3. Main Process: codebuddy:getAccountUsage IPC handler
|
|
21240
|
+
* 4. 返回 { usageLeft, usageTotal, editionType, refreshAt } 等字段
|
|
21241
|
+
*/
|
|
21242
|
+
async getAccountUsage() {
|
|
21243
|
+
this.log("Getting account usage via IPC");
|
|
21244
|
+
try {
|
|
21245
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_ACCOUNT_USAGE);
|
|
21246
|
+
} catch (error) {
|
|
21247
|
+
this.log("Get account usage failed:", error);
|
|
21248
|
+
return null;
|
|
21249
|
+
}
|
|
21250
|
+
}
|
|
21251
|
+
/**
|
|
21252
|
+
* 获取每日签到状态
|
|
21253
|
+
* IDE 环境: 通过 IPC 获取签到状态
|
|
21254
|
+
*/
|
|
21255
|
+
async getCheckinStatus() {
|
|
21256
|
+
this.log("Getting checkin status via IPC");
|
|
21257
|
+
try {
|
|
21258
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_CHECKIN_STATUS);
|
|
21259
|
+
} catch (error) {
|
|
21260
|
+
this.log("Get checkin status failed:", error);
|
|
21261
|
+
return null;
|
|
21262
|
+
}
|
|
21263
|
+
}
|
|
21264
|
+
/**
|
|
21265
|
+
* 执行每日签到
|
|
21266
|
+
* IDE 环境: 通过 IPC 执行签到
|
|
21267
|
+
*/
|
|
21268
|
+
async claimDailyCheckin() {
|
|
21269
|
+
this.log("Claiming daily checkin via IPC");
|
|
21270
|
+
try {
|
|
21271
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.CLAIM_DAILY_CHECKIN);
|
|
21272
|
+
} catch (error) {
|
|
21273
|
+
this.log("Claim daily checkin failed:", error);
|
|
21274
|
+
throw error;
|
|
21275
|
+
}
|
|
21276
|
+
}
|
|
21277
|
+
/**
|
|
21278
|
+
* 获取 SkillHub 技能列表
|
|
21279
|
+
* IDE 环境: 通过 IPC 获取技能列表
|
|
21280
|
+
*/
|
|
21281
|
+
async getSkillHubList(params) {
|
|
21282
|
+
this.log("Getting SkillHub list via IPC", params);
|
|
21283
|
+
try {
|
|
21284
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.SKILLHUB_LIST, params);
|
|
21285
|
+
} catch (error) {
|
|
21286
|
+
this.log("Get SkillHub list failed:", error);
|
|
21287
|
+
throw error;
|
|
21288
|
+
}
|
|
21289
|
+
}
|
|
21290
|
+
/**
|
|
21291
|
+
* 获取 SkillHub 分类列表
|
|
21292
|
+
* IDE 环境: 通过 IPC 获取分类列表
|
|
21293
|
+
*/
|
|
21294
|
+
async getSkillHubCategories() {
|
|
21295
|
+
this.log("Getting SkillHub categories via IPC");
|
|
21296
|
+
try {
|
|
21297
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.SKILLHUB_CATEGORIES);
|
|
21298
|
+
} catch (error) {
|
|
21299
|
+
this.log("Get SkillHub categories failed:", error);
|
|
21300
|
+
throw error;
|
|
21301
|
+
}
|
|
21302
|
+
}
|
|
21303
|
+
/**
|
|
21304
|
+
* 搜索 SkillHub 技能
|
|
21305
|
+
* IDE 环境: 通过 IPC 搜索技能
|
|
21306
|
+
*/
|
|
21307
|
+
async getSkillHubSearch(q, limit = 20) {
|
|
21308
|
+
this.log("Searching SkillHub via IPC", {
|
|
21309
|
+
q,
|
|
21310
|
+
limit
|
|
21311
|
+
});
|
|
21312
|
+
try {
|
|
21313
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.SKILLHUB_SEARCH, {
|
|
21314
|
+
q,
|
|
21315
|
+
limit
|
|
21316
|
+
});
|
|
21317
|
+
} catch (error) {
|
|
21318
|
+
this.log("SkillHub search failed:", error);
|
|
21319
|
+
throw error;
|
|
21320
|
+
}
|
|
21321
|
+
}
|
|
21322
|
+
/**
|
|
21323
|
+
* 获取 SkillHub 技能详情
|
|
21324
|
+
* IDE 环境: 通过 IPC 获取技能详情
|
|
21325
|
+
*/
|
|
21326
|
+
async getSkillHubDetail(slug) {
|
|
21327
|
+
this.log("Getting SkillHub detail via IPC", { slug });
|
|
21328
|
+
try {
|
|
21329
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.SKILLHUB_DETAIL, { slug });
|
|
21330
|
+
} catch (error) {
|
|
21331
|
+
this.log("Get SkillHub detail failed:", error);
|
|
21332
|
+
throw error;
|
|
21333
|
+
}
|
|
21334
|
+
}
|
|
21335
|
+
/**
|
|
21336
|
+
* 批量检查 SkillHub 技能是否存在
|
|
21337
|
+
* IDE 环境: 通过 IPC 检查技能是否存在
|
|
21338
|
+
*/
|
|
21339
|
+
async getSkillHubExists(slugs) {
|
|
21340
|
+
this.log("Checking SkillHub exists via IPC", { slugs });
|
|
21341
|
+
try {
|
|
21342
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.SKILLHUB_EXISTS, { slugs });
|
|
21343
|
+
} catch (error) {
|
|
21344
|
+
this.log("SkillHub exists check failed:", error);
|
|
21345
|
+
throw error;
|
|
21346
|
+
}
|
|
21347
|
+
}
|
|
21348
|
+
/**
|
|
21349
|
+
* 上报 SkillHub 技能统计
|
|
21350
|
+
* IDE 环境: 通过 IPC 上报统计
|
|
21351
|
+
*/
|
|
21352
|
+
async reportSkillHubStats(slug, inc) {
|
|
21353
|
+
this.log("Reporting SkillHub stats via IPC", {
|
|
21354
|
+
slug,
|
|
21355
|
+
inc
|
|
21356
|
+
});
|
|
21357
|
+
try {
|
|
21358
|
+
await this.sendBackendRequest(BACKEND_REQUEST_TYPES.SKILLHUB_REPORT_STATS, {
|
|
21359
|
+
slug,
|
|
21360
|
+
inc
|
|
21361
|
+
});
|
|
21362
|
+
} catch (error) {
|
|
21363
|
+
this.log("Report SkillHub stats failed:", error);
|
|
21364
|
+
}
|
|
21365
|
+
}
|
|
21366
|
+
/**
|
|
21367
|
+
* 安装 SkillHub 技能
|
|
21368
|
+
* IDE 环境: 通过 IPC 安装技能(下载 zip → 解压到本地)
|
|
21369
|
+
*/
|
|
21370
|
+
async installSkillHubSkill(slug, version, name) {
|
|
21371
|
+
this.log("Installing SkillHub skill via IPC", {
|
|
21372
|
+
slug,
|
|
21373
|
+
version,
|
|
21374
|
+
name
|
|
21375
|
+
});
|
|
21376
|
+
try {
|
|
21377
|
+
return await this.sendBackendRequest("backend:skillhub-install", {
|
|
21378
|
+
slug,
|
|
21379
|
+
version,
|
|
21380
|
+
name
|
|
21381
|
+
});
|
|
21382
|
+
} catch (error) {
|
|
21383
|
+
this.log("Install SkillHub skill failed:", error);
|
|
21384
|
+
throw error;
|
|
21385
|
+
}
|
|
21386
|
+
}
|
|
21387
|
+
/**
|
|
21388
|
+
* 获取本地已安装的 SkillHub 技能元信息
|
|
21389
|
+
* IDE 环境: 通过 IPC 获取元信息
|
|
21390
|
+
*/
|
|
21391
|
+
async getSkillHubInstalledMetas() {
|
|
21392
|
+
this.log("Getting SkillHub installed metas via IPC");
|
|
21393
|
+
try {
|
|
21394
|
+
return await this.sendBackendRequest("backend:skillhub-installed-metas");
|
|
21395
|
+
} catch (error) {
|
|
21396
|
+
this.log("Get SkillHub installed metas failed:", error);
|
|
21397
|
+
return [];
|
|
21398
|
+
}
|
|
21399
|
+
}
|
|
21400
|
+
/**
|
|
19606
21401
|
* 调试日志
|
|
19607
21402
|
*/
|
|
19608
21403
|
log(...args) {
|
|
@@ -19622,10 +21417,11 @@ exports.AgentClient = AgentClient;
|
|
|
19622
21417
|
exports.BackendProvider = BackendProvider;
|
|
19623
21418
|
exports.CloudAgentConnection = CloudAgentConnection;
|
|
19624
21419
|
exports.CloudAgentProvider = CloudAgentProvider;
|
|
19625
|
-
exports.E2BFilesystem = E2BFilesystem;
|
|
21420
|
+
exports.E2BFilesystem = require_e2b_filesystem.E2BFilesystem;
|
|
19626
21421
|
exports.HttpService = HttpService;
|
|
19627
21422
|
exports.IPCBackendProvider = IPCBackendProvider;
|
|
19628
21423
|
exports.SessionManager = SessionManager;
|
|
21424
|
+
exports.__toESM = __toESM;
|
|
19629
21425
|
exports.createBackendProvider = createBackendProvider;
|
|
19630
21426
|
exports.createIPCBackendProvider = createIPCBackendProvider;
|
|
19631
21427
|
exports.httpService = httpService;
|