@tencent-ai/cloud-agent-sdk 0.2.6 → 0.2.7-next.4a35c5d.20260128
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/index.cjs +1507 -194
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2099 -1565
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2099 -1565
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1507 -194
- package/dist/index.mjs.map +1 -1
- package/dist/tencent-ai-cloud-agent-sdk-0.2.7-next.4a35c5d.20260128.tgz +0 -0
- package/package.json +4 -3
- package/dist/MockAgentProvider-4e4oOusg.cjs +0 -3
- package/dist/MockAgentProvider-D-basTXz.cjs +0 -3219
- package/dist/MockAgentProvider-D-basTXz.cjs.map +0 -1
- package/dist/MockAgentProvider-TNsV559x.mjs +0 -3202
- package/dist/MockAgentProvider-TNsV559x.mjs.map +0 -1
- package/dist/MockAgentProvider-tNdtAJCv.mjs +0 -3
- package/dist/tencent-ai-cloud-agent-sdk-0.2.6.tgz +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,633 @@
|
|
|
1
|
-
import "
|
|
1
|
+
import { z } from "zod";
|
|
2
2
|
import { ClientSideConnection, PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
|
|
3
3
|
import "@connectrpc/connect";
|
|
4
4
|
import "@connectrpc/connect-web";
|
|
5
5
|
import "@bufbuild/protobuf";
|
|
6
6
|
import { Sandbox } from "e2b";
|
|
7
7
|
|
|
8
|
+
//#region ../agent-provider/src/common/_legacy/tool-schemas.ts
|
|
9
|
+
/**
|
|
10
|
+
* ACP Tool Input/Output Schema 定义
|
|
11
|
+
*
|
|
12
|
+
* 用于约束 ACP 协议中 ToolCallUpdate 的 rawInput 和 rawOutput 字段
|
|
13
|
+
* 基于 getCraftToolProvider 使用的工具定义
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* 工具输入 Schema 定义
|
|
17
|
+
* 用于验证和约束 rawInput
|
|
18
|
+
*/
|
|
19
|
+
const ToolInputSchemas = {
|
|
20
|
+
list_dir: z.object({
|
|
21
|
+
target_directory: z.string().describe("要列出内容的目录路径"),
|
|
22
|
+
ignore_globs: z.string().optional().describe("可选的 glob 模式数组,用于忽略特定文件")
|
|
23
|
+
}),
|
|
24
|
+
search_file: z.object({
|
|
25
|
+
target_directory: z.string().describe("搜索的目录绝对路径"),
|
|
26
|
+
pattern: z.string().describe("文件模式(如 \"*.js\"),支持通配符"),
|
|
27
|
+
recursive: z.boolean().describe("是否递归搜索子目录"),
|
|
28
|
+
caseSensitive: z.boolean().describe("是否区分大小写")
|
|
29
|
+
}),
|
|
30
|
+
read_file: z.object({
|
|
31
|
+
filePath: z.string().describe("要读取的文件的绝对路径"),
|
|
32
|
+
offset: z.number().optional().describe("开始读取的行号"),
|
|
33
|
+
limit: z.number().optional().describe("要读取的行数")
|
|
34
|
+
}),
|
|
35
|
+
read_lints: z.object({ paths: z.string().optional().describe("要读取 lint 错误的文件或目录路径") }),
|
|
36
|
+
rag_search: z.object({
|
|
37
|
+
queryString: z.string().describe("用户的实际问题或搜索查询"),
|
|
38
|
+
knowledgeBaseNames: z.string().describe("知识库名称,多个用逗号分隔")
|
|
39
|
+
}),
|
|
40
|
+
read_rules: z.object({ ruleNames: z.string().describe("要读取的规则关键词,用逗号分隔,格式:{ruleName}_{ruleId}") }),
|
|
41
|
+
mcp_get_tool_description: z.object({ toolRequests: z.string().describe("JSON 字符串,二维数组格式:[[\"server1\", \"tool1\"], [\"server2\", \"tool2\"]]") }),
|
|
42
|
+
mcp_call_tool: z.object({
|
|
43
|
+
serverName: z.string().describe("MCP 服务器名称"),
|
|
44
|
+
toolName: z.string().describe("要调用的工具名称"),
|
|
45
|
+
arguments: z.string().describe("目标 MCP 工具的参数,JSON 格式字符串"),
|
|
46
|
+
maxOutputLength: z.number().optional().describe("控制工具输出的最大长度,默认 200000")
|
|
47
|
+
}),
|
|
48
|
+
fetch_mcp_resource: z.object({
|
|
49
|
+
server: z.string().describe("MCP 服务器标识符"),
|
|
50
|
+
uri: z.string().describe("要读取的资源 URI"),
|
|
51
|
+
arguments: z.record(z.unknown()).optional().describe("资源模板的参数"),
|
|
52
|
+
downloadPath: z.string().optional().describe("可选的绝对路径,用于保存资源到磁盘")
|
|
53
|
+
}),
|
|
54
|
+
create_rule: z.object({
|
|
55
|
+
ruleScope: z.string().describe("规则范围,project rule 或 user rule"),
|
|
56
|
+
ruleName: z.string().describe("规则文件名,不带扩展名"),
|
|
57
|
+
ruleType: z.string().describe("规则类型,always、manual 或 requested"),
|
|
58
|
+
ruleContent: z.string().describe("规则内容,使用 Markdown 格式"),
|
|
59
|
+
ruleDescription: z.string().optional().describe("规则描述,使用 Markdown 格式")
|
|
60
|
+
}),
|
|
61
|
+
update_memory: z.object({
|
|
62
|
+
action: z.enum([
|
|
63
|
+
"create",
|
|
64
|
+
"update",
|
|
65
|
+
"delete"
|
|
66
|
+
]).optional().describe("执行的操作"),
|
|
67
|
+
existing_knowledge_id: z.string().optional().describe("更新或删除时必需,现有记忆的 ID"),
|
|
68
|
+
knowledge_to_store: z.string().optional().describe("要存储的特定记忆"),
|
|
69
|
+
title: z.string().optional().describe("记忆的标题")
|
|
70
|
+
}),
|
|
71
|
+
search_content: z.object({
|
|
72
|
+
pattern: z.string().describe("要搜索的关键字或正则表达式模式"),
|
|
73
|
+
directory: z.string().describe("要搜索的目录的绝对路径"),
|
|
74
|
+
fileTypes: z.string().optional().describe("可选的逗号分隔文件扩展名"),
|
|
75
|
+
contextBefore: z.number().optional().describe("每个匹配前显示的行数"),
|
|
76
|
+
contextAfter: z.number().optional().describe("每个匹配后显示的行数"),
|
|
77
|
+
contextAround: z.number().optional().describe("每个匹配前后显示的行数"),
|
|
78
|
+
outputMode: z.string().optional().describe("输出模式:content、files_with_matches 或 count"),
|
|
79
|
+
caseSensitive: z.boolean().optional().describe("是否区分大小写")
|
|
80
|
+
}),
|
|
81
|
+
write_to_file: z.object({
|
|
82
|
+
filePath: z.string().describe("目标文件的绝对路径"),
|
|
83
|
+
content: z.string().describe("要写入的内容")
|
|
84
|
+
}),
|
|
85
|
+
replace_in_file: z.object({
|
|
86
|
+
filePath: z.string().describe("要修改的文件的绝对路径"),
|
|
87
|
+
old_str: z.string().describe("要替换的文本"),
|
|
88
|
+
new_str: z.string().describe("替换后的文本")
|
|
89
|
+
}),
|
|
90
|
+
delete_file: z.object({
|
|
91
|
+
target_file: z.string().describe("要删除的文件的绝对路径"),
|
|
92
|
+
explanation: z.string().optional().describe("为什么使用此工具的一句话解释")
|
|
93
|
+
}),
|
|
94
|
+
execute_command: z.object({
|
|
95
|
+
command: z.string().describe("要执行的 CLI 命令"),
|
|
96
|
+
requires_approval: z.boolean().describe("命令是否需要用户批准")
|
|
97
|
+
}),
|
|
98
|
+
preview_url: z.object({ url: z.string().describe("要打开的完整、有效的 HTTP/HTTPS URL") }),
|
|
99
|
+
ask_followup_question: z.object({ questions: z.array(z.object({
|
|
100
|
+
question: z.string(),
|
|
101
|
+
header: z.string().max(12),
|
|
102
|
+
options: z.array(z.object({
|
|
103
|
+
label: z.string().max(50),
|
|
104
|
+
description: z.string()
|
|
105
|
+
})).min(2).max(4),
|
|
106
|
+
multiSelect: z.boolean().optional()
|
|
107
|
+
})).min(1).max(4) }),
|
|
108
|
+
invoke_integration: z.object({}).passthrough(),
|
|
109
|
+
call_integration: z.object({}).passthrough(),
|
|
110
|
+
search_integration_tool: z.object({}).passthrough(),
|
|
111
|
+
supabase_get_logs: z.object({}).passthrough(),
|
|
112
|
+
supabase_execute_sql: z.object({}).passthrough(),
|
|
113
|
+
supabase_apply_migration: z.object({}).passthrough(),
|
|
114
|
+
supabase_list_migration: z.object({}).passthrough(),
|
|
115
|
+
supabase_list_tables: z.object({}).passthrough(),
|
|
116
|
+
cloud_studio_fetch_log: z.object({}).passthrough(),
|
|
117
|
+
cloud_studio_execute_command: z.object({}).passthrough(),
|
|
118
|
+
cloud_studio_deploy_sandbox: z.object({}).passthrough(),
|
|
119
|
+
component_get_prompt: z.object({}).passthrough(),
|
|
120
|
+
web_fetch: z.object({
|
|
121
|
+
url: z.string().describe("要获取内容的 URL"),
|
|
122
|
+
fetchInfo: z.string().describe("用户想要获取的信息描述")
|
|
123
|
+
}),
|
|
124
|
+
use_skill: z.object({ command: z.string().describe("技能名称(不含参数),如 \"pdf\" 或 \"xlsx\"") }),
|
|
125
|
+
web_search: z.object({
|
|
126
|
+
explanation: z.string().describe("为什么使用此工具的一句话解释"),
|
|
127
|
+
searchTerm: z.string().describe("要在网络上搜索的搜索词")
|
|
128
|
+
}),
|
|
129
|
+
task: z.object({
|
|
130
|
+
subagent_name: z.string().describe("要调用的子代理名称"),
|
|
131
|
+
description: z.string().describe("任务的简短描述(3-5 个词)"),
|
|
132
|
+
prompt: z.string().describe("子代理要执行的任务"),
|
|
133
|
+
subagent_path: z.string().optional().describe("子代理定义文件的路径")
|
|
134
|
+
}),
|
|
135
|
+
codebase_search: z.object({
|
|
136
|
+
query: z.string().describe("关于你想理解的内容的完整问题"),
|
|
137
|
+
path: z.string().describe("限制搜索范围的目录路径前缀"),
|
|
138
|
+
limit: z.number().max(100).optional().describe("返回的最大结果数,默认 10")
|
|
139
|
+
}),
|
|
140
|
+
lsp: z.object({}).passthrough(),
|
|
141
|
+
spec_create: z.object({
|
|
142
|
+
name: z.string().describe("Plan 名称,用作稳定标识符/文件名"),
|
|
143
|
+
overview: z.string().describe("用一两句话精确概括本次 plan 的主要内容"),
|
|
144
|
+
relative_history: z.string().describe("准备阶段的上下文,包含用户需求、代码位置、额外上下文等")
|
|
145
|
+
}),
|
|
146
|
+
spec_update: z.object({ status: z.enum([
|
|
147
|
+
"prepare",
|
|
148
|
+
"ready",
|
|
149
|
+
"building",
|
|
150
|
+
"finished"
|
|
151
|
+
]).optional().describe("Plan 状态") })
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* 工具输出 Schema 定义
|
|
155
|
+
* 用于验证和约束 rawOutput
|
|
156
|
+
*/
|
|
157
|
+
const ToolOutputSchemas = {
|
|
158
|
+
list_dir: z.object({
|
|
159
|
+
type: z.literal("list_files_result"),
|
|
160
|
+
files: z.array(z.object({
|
|
161
|
+
filePath: z.string(),
|
|
162
|
+
size: z.string(),
|
|
163
|
+
modifyTime: z.string()
|
|
164
|
+
})),
|
|
165
|
+
root: z.string(),
|
|
166
|
+
listing: z.string().optional()
|
|
167
|
+
}),
|
|
168
|
+
search_file: z.object({
|
|
169
|
+
type: z.literal("search_file_result"),
|
|
170
|
+
path: z.string(),
|
|
171
|
+
pattern: z.string(),
|
|
172
|
+
recursive: z.boolean().optional(),
|
|
173
|
+
caseSensitive: z.boolean().optional(),
|
|
174
|
+
results: z.array(z.object({
|
|
175
|
+
filePath: z.string(),
|
|
176
|
+
size: z.string(),
|
|
177
|
+
modifyTime: z.string()
|
|
178
|
+
}))
|
|
179
|
+
}),
|
|
180
|
+
read_file: z.object({
|
|
181
|
+
type: z.literal("read_file_result"),
|
|
182
|
+
path: z.string(),
|
|
183
|
+
content: z.string(),
|
|
184
|
+
totalLineCount: z.number(),
|
|
185
|
+
hasMore: z.boolean(),
|
|
186
|
+
diagnostic: z.string().optional(),
|
|
187
|
+
hint: z.string().optional(),
|
|
188
|
+
image: z.object({
|
|
189
|
+
data: z.string(),
|
|
190
|
+
mimeType: z.string()
|
|
191
|
+
}).optional()
|
|
192
|
+
}),
|
|
193
|
+
read_lints: z.object({
|
|
194
|
+
type: z.literal("read_lints_result"),
|
|
195
|
+
diagnostics: z.array(z.string()),
|
|
196
|
+
totalCount: z.number().optional(),
|
|
197
|
+
hint: z.string().optional(),
|
|
198
|
+
isTruncated: z.boolean().optional()
|
|
199
|
+
}),
|
|
200
|
+
rag_search: z.object({
|
|
201
|
+
type: z.literal("knowledge_base_result"),
|
|
202
|
+
selectedKnowledgeBases: z.string(),
|
|
203
|
+
queryInput: z.string()
|
|
204
|
+
}),
|
|
205
|
+
read_rules: z.object({
|
|
206
|
+
type: z.literal("rule_match_result"),
|
|
207
|
+
ruleDescription: z.string(),
|
|
208
|
+
filePaths: z.array(z.string())
|
|
209
|
+
}),
|
|
210
|
+
mcp_get_tool_description: z.object({}).passthrough(),
|
|
211
|
+
mcp_call_tool: z.object({
|
|
212
|
+
type: z.literal("mcp_call_tool_result"),
|
|
213
|
+
serverName: z.string(),
|
|
214
|
+
toolName: z.string(),
|
|
215
|
+
data: z.array(z.union([
|
|
216
|
+
z.object({
|
|
217
|
+
type: z.literal("text"),
|
|
218
|
+
text: z.string()
|
|
219
|
+
}),
|
|
220
|
+
z.object({
|
|
221
|
+
type: z.literal("image"),
|
|
222
|
+
data: z.string(),
|
|
223
|
+
mimeType: z.string()
|
|
224
|
+
}),
|
|
225
|
+
z.object({
|
|
226
|
+
type: z.literal("resource"),
|
|
227
|
+
resource: z.object({
|
|
228
|
+
uri: z.string(),
|
|
229
|
+
mimeType: z.string().optional(),
|
|
230
|
+
text: z.string().optional(),
|
|
231
|
+
blob: z.string().optional()
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
])),
|
|
235
|
+
isError: z.boolean().optional(),
|
|
236
|
+
error: z.unknown().optional(),
|
|
237
|
+
hint: z.string().optional()
|
|
238
|
+
}),
|
|
239
|
+
fetch_mcp_resource: z.object({
|
|
240
|
+
type: z.literal("fetch_mcp_resource_result"),
|
|
241
|
+
server: z.string(),
|
|
242
|
+
uri: z.string(),
|
|
243
|
+
content: z.string(),
|
|
244
|
+
downloadPath: z.string().optional()
|
|
245
|
+
}),
|
|
246
|
+
create_rule: z.object({
|
|
247
|
+
type: z.literal("rule_create_result"),
|
|
248
|
+
ruleName: z.string(),
|
|
249
|
+
createState: z.enum([
|
|
250
|
+
"success",
|
|
251
|
+
"invoke",
|
|
252
|
+
"cancelled"
|
|
253
|
+
]),
|
|
254
|
+
hint: z.string().optional(),
|
|
255
|
+
filePath: z.string().optional()
|
|
256
|
+
}),
|
|
257
|
+
update_memory: z.object({
|
|
258
|
+
type: z.literal("update_memory_result"),
|
|
259
|
+
success: z.boolean(),
|
|
260
|
+
message: z.string(),
|
|
261
|
+
action: z.enum([
|
|
262
|
+
"create",
|
|
263
|
+
"update",
|
|
264
|
+
"delete"
|
|
265
|
+
]),
|
|
266
|
+
knowledge_id: z.string().optional()
|
|
267
|
+
}),
|
|
268
|
+
search_content: z.object({
|
|
269
|
+
type: z.literal("search_content_result"),
|
|
270
|
+
directory: z.string(),
|
|
271
|
+
pattern: z.string(),
|
|
272
|
+
fileTypes: z.string(),
|
|
273
|
+
matches: z.array(z.object({
|
|
274
|
+
filePath: z.string(),
|
|
275
|
+
content: z.string(),
|
|
276
|
+
startLine: z.number(),
|
|
277
|
+
endLine: z.number(),
|
|
278
|
+
size: z.string(),
|
|
279
|
+
modifyTime: z.string()
|
|
280
|
+
})),
|
|
281
|
+
totalCount: z.number(),
|
|
282
|
+
hasMore: z.boolean(),
|
|
283
|
+
offset: z.number(),
|
|
284
|
+
limit: z.number(),
|
|
285
|
+
contextBefore: z.number(),
|
|
286
|
+
contextAfter: z.number(),
|
|
287
|
+
contextAround: z.number().optional(),
|
|
288
|
+
outputMode: z.string(),
|
|
289
|
+
caseSensitive: z.boolean(),
|
|
290
|
+
hint: z.string().optional()
|
|
291
|
+
}),
|
|
292
|
+
write_to_file: z.object({
|
|
293
|
+
type: z.literal("write_to_file_result"),
|
|
294
|
+
path: z.string(),
|
|
295
|
+
addLineCount: z.number(),
|
|
296
|
+
removedLines: z.number(),
|
|
297
|
+
addedChars: z.number().optional(),
|
|
298
|
+
removedChars: z.number().optional(),
|
|
299
|
+
bytesWritten: z.number(),
|
|
300
|
+
isNewFile: z.boolean(),
|
|
301
|
+
oldContent: z.string().optional(),
|
|
302
|
+
diagnostic: z.string().optional()
|
|
303
|
+
}),
|
|
304
|
+
replace_in_file: z.object({
|
|
305
|
+
type: z.literal("replace_in_file_result"),
|
|
306
|
+
path: z.string(),
|
|
307
|
+
addLineCount: z.number().optional(),
|
|
308
|
+
removedLines: z.number().optional(),
|
|
309
|
+
addedChars: z.number().optional(),
|
|
310
|
+
removedChars: z.number().optional(),
|
|
311
|
+
matchCount: z.number().optional(),
|
|
312
|
+
hint: z.string().optional(),
|
|
313
|
+
diagnosticChange: z.object({
|
|
314
|
+
added: z.string(),
|
|
315
|
+
removed: z.string(),
|
|
316
|
+
unchanged: z.string()
|
|
317
|
+
}).optional()
|
|
318
|
+
}),
|
|
319
|
+
delete_file: z.object({
|
|
320
|
+
type: z.literal("delete_file_result"),
|
|
321
|
+
path: z.string(),
|
|
322
|
+
recursive: z.boolean(),
|
|
323
|
+
hint: z.string().optional()
|
|
324
|
+
}),
|
|
325
|
+
execute_command: z.object({
|
|
326
|
+
type: z.literal("execute_command_result"),
|
|
327
|
+
stdout: z.string(),
|
|
328
|
+
stderr: z.string(),
|
|
329
|
+
exitCode: z.number(),
|
|
330
|
+
hint: z.string().optional(),
|
|
331
|
+
serviceInfo: z.object({
|
|
332
|
+
isWatchCommand: z.boolean(),
|
|
333
|
+
isServiceOutput: z.boolean(),
|
|
334
|
+
serviceReady: z.boolean(),
|
|
335
|
+
message: z.string()
|
|
336
|
+
}).optional(),
|
|
337
|
+
use_standalone_terminal: z.boolean().optional()
|
|
338
|
+
}),
|
|
339
|
+
preview_url: z.object({
|
|
340
|
+
type: z.literal("preview_tool_result"),
|
|
341
|
+
url: z.string(),
|
|
342
|
+
message: z.string()
|
|
343
|
+
}),
|
|
344
|
+
ask_followup_question: z.object({
|
|
345
|
+
type: z.literal("multi_question_result"),
|
|
346
|
+
questions: z.array(z.object({
|
|
347
|
+
id: z.string(),
|
|
348
|
+
question: z.string(),
|
|
349
|
+
options: z.array(z.string()),
|
|
350
|
+
multiSelect: z.boolean().optional(),
|
|
351
|
+
title: z.string().optional()
|
|
352
|
+
})),
|
|
353
|
+
answers: z.record(z.union([z.string(), z.array(z.string())])),
|
|
354
|
+
message: z.string()
|
|
355
|
+
}),
|
|
356
|
+
invoke_integration: z.object({
|
|
357
|
+
type: z.literal("invoke_integration_tool_result"),
|
|
358
|
+
recommend: z.object({
|
|
359
|
+
id: z.string(),
|
|
360
|
+
type: z.string(),
|
|
361
|
+
status: z.enum(["connected", "disconnected"])
|
|
362
|
+
}),
|
|
363
|
+
message: z.string()
|
|
364
|
+
}),
|
|
365
|
+
call_integration: z.object({
|
|
366
|
+
type: z.literal("call_integration_tool_result"),
|
|
367
|
+
integrationId: z.string(),
|
|
368
|
+
toolName: z.string(),
|
|
369
|
+
data: z.object({
|
|
370
|
+
type: z.literal("text"),
|
|
371
|
+
text: z.string()
|
|
372
|
+
}),
|
|
373
|
+
isError: z.boolean().optional(),
|
|
374
|
+
error: z.unknown().optional()
|
|
375
|
+
}),
|
|
376
|
+
search_integration_tool: z.object({
|
|
377
|
+
type: z.literal("search_integration_tool_result"),
|
|
378
|
+
data: z.array(z.object({
|
|
379
|
+
integrationId: z.string(),
|
|
380
|
+
integrationName: z.string(),
|
|
381
|
+
toolName: z.string(),
|
|
382
|
+
description: z.string(),
|
|
383
|
+
inputSchema: z.record(z.unknown())
|
|
384
|
+
})),
|
|
385
|
+
hint: z.string().optional()
|
|
386
|
+
}),
|
|
387
|
+
supabase_get_logs: z.object({
|
|
388
|
+
type: z.enum([
|
|
389
|
+
"supabase_get_logs_result",
|
|
390
|
+
"supabase_execute_sql_result",
|
|
391
|
+
"supabase_apply_migration_result",
|
|
392
|
+
"supabase_list_migration_result",
|
|
393
|
+
"supabase_list_tables_result"
|
|
394
|
+
]),
|
|
395
|
+
message: z.string()
|
|
396
|
+
}),
|
|
397
|
+
supabase_execute_sql: z.object({
|
|
398
|
+
type: z.enum([
|
|
399
|
+
"supabase_get_logs_result",
|
|
400
|
+
"supabase_execute_sql_result",
|
|
401
|
+
"supabase_apply_migration_result",
|
|
402
|
+
"supabase_list_migration_result",
|
|
403
|
+
"supabase_list_tables_result"
|
|
404
|
+
]),
|
|
405
|
+
message: z.string()
|
|
406
|
+
}),
|
|
407
|
+
supabase_apply_migration: z.object({
|
|
408
|
+
type: z.enum([
|
|
409
|
+
"supabase_get_logs_result",
|
|
410
|
+
"supabase_execute_sql_result",
|
|
411
|
+
"supabase_apply_migration_result",
|
|
412
|
+
"supabase_list_migration_result",
|
|
413
|
+
"supabase_list_tables_result"
|
|
414
|
+
]),
|
|
415
|
+
message: z.string()
|
|
416
|
+
}),
|
|
417
|
+
supabase_list_migration: z.object({
|
|
418
|
+
type: z.enum([
|
|
419
|
+
"supabase_get_logs_result",
|
|
420
|
+
"supabase_execute_sql_result",
|
|
421
|
+
"supabase_apply_migration_result",
|
|
422
|
+
"supabase_list_migration_result",
|
|
423
|
+
"supabase_list_tables_result"
|
|
424
|
+
]),
|
|
425
|
+
message: z.string()
|
|
426
|
+
}),
|
|
427
|
+
supabase_list_tables: z.object({
|
|
428
|
+
type: z.enum([
|
|
429
|
+
"supabase_get_logs_result",
|
|
430
|
+
"supabase_execute_sql_result",
|
|
431
|
+
"supabase_apply_migration_result",
|
|
432
|
+
"supabase_list_migration_result",
|
|
433
|
+
"supabase_list_tables_result"
|
|
434
|
+
]),
|
|
435
|
+
message: z.string()
|
|
436
|
+
}),
|
|
437
|
+
cloud_studio_fetch_log: z.object({
|
|
438
|
+
type: z.literal("cloud_studio_fetch_log_result"),
|
|
439
|
+
success: z.boolean(),
|
|
440
|
+
logs: z.record(z.string())
|
|
441
|
+
}),
|
|
442
|
+
cloud_studio_execute_command: z.object({
|
|
443
|
+
type: z.literal("cloud_studio_execute_command_result"),
|
|
444
|
+
success: z.boolean(),
|
|
445
|
+
message: z.string()
|
|
446
|
+
}),
|
|
447
|
+
cloud_studio_deploy_sandbox: z.object({
|
|
448
|
+
type: z.literal("cloud_studio_integration_result"),
|
|
449
|
+
previewUrl: z.string().optional(),
|
|
450
|
+
steps: z.array(z.object({
|
|
451
|
+
status: z.enum([
|
|
452
|
+
"idle",
|
|
453
|
+
"success",
|
|
454
|
+
"running",
|
|
455
|
+
"error"
|
|
456
|
+
]),
|
|
457
|
+
name: z.enum([
|
|
458
|
+
"createSandbox",
|
|
459
|
+
"uploadProject",
|
|
460
|
+
"installDependencies",
|
|
461
|
+
"startService",
|
|
462
|
+
"preview"
|
|
463
|
+
]),
|
|
464
|
+
error: z.object({
|
|
465
|
+
code: z.number().optional(),
|
|
466
|
+
message: z.string().optional()
|
|
467
|
+
}).optional()
|
|
468
|
+
}))
|
|
469
|
+
}),
|
|
470
|
+
component_get_prompt: z.object({
|
|
471
|
+
type: z.literal("component_get_prompt_result"),
|
|
472
|
+
componentType: z.string(),
|
|
473
|
+
webFramework: z.string(),
|
|
474
|
+
data: z.object({
|
|
475
|
+
type: z.literal("text"),
|
|
476
|
+
text: z.string()
|
|
477
|
+
})
|
|
478
|
+
}),
|
|
479
|
+
web_fetch: z.object({
|
|
480
|
+
type: z.literal("web_fetch_tool_result"),
|
|
481
|
+
message: z.string(),
|
|
482
|
+
data: z.string(),
|
|
483
|
+
loading: z.string().optional(),
|
|
484
|
+
title: z.string().optional(),
|
|
485
|
+
favicon: z.string().optional()
|
|
486
|
+
}),
|
|
487
|
+
use_skill: z.object({
|
|
488
|
+
type: z.literal("use_skill_tool_result"),
|
|
489
|
+
commandMessage: z.string(),
|
|
490
|
+
message: z.string()
|
|
491
|
+
}),
|
|
492
|
+
web_search: z.object({
|
|
493
|
+
type: z.literal("web_search_tool_result"),
|
|
494
|
+
data: z.array(z.object({
|
|
495
|
+
passage: z.string(),
|
|
496
|
+
uri: z.string(),
|
|
497
|
+
site: z.string(),
|
|
498
|
+
title: z.string(),
|
|
499
|
+
snippets: z.array(z.string()).optional(),
|
|
500
|
+
content: z.string().optional()
|
|
501
|
+
})),
|
|
502
|
+
searchInput: z.string().optional()
|
|
503
|
+
}),
|
|
504
|
+
task: z.object({
|
|
505
|
+
type: z.literal("task_tool_result"),
|
|
506
|
+
toolInfo: z.array(z.object({
|
|
507
|
+
name: z.string(),
|
|
508
|
+
info: z.string(),
|
|
509
|
+
needApprove: z.boolean().optional(),
|
|
510
|
+
toolCallId: z.string().optional(),
|
|
511
|
+
executeStatus: z.enum([
|
|
512
|
+
"ing",
|
|
513
|
+
"completed",
|
|
514
|
+
"cancel",
|
|
515
|
+
"fail"
|
|
516
|
+
]).optional()
|
|
517
|
+
})).optional(),
|
|
518
|
+
startCallTool: z.boolean().optional(),
|
|
519
|
+
finalResult: z.string().optional(),
|
|
520
|
+
toolCallBrief: z.string().optional()
|
|
521
|
+
}),
|
|
522
|
+
codebase_search: z.object({
|
|
523
|
+
type: z.literal("codebase_search_result"),
|
|
524
|
+
query: z.string(),
|
|
525
|
+
path: z.string(),
|
|
526
|
+
content: z.string()
|
|
527
|
+
}),
|
|
528
|
+
lsp: z.object({
|
|
529
|
+
type: z.literal("lsp_tool_result"),
|
|
530
|
+
operation: z.string(),
|
|
531
|
+
result: z.string(),
|
|
532
|
+
resultCount: z.number().optional(),
|
|
533
|
+
fileCount: z.number().optional(),
|
|
534
|
+
character: z.number().optional()
|
|
535
|
+
}),
|
|
536
|
+
spec_create: z.object({
|
|
537
|
+
type: z.literal("plan_create_tool_result"),
|
|
538
|
+
message: z.string(),
|
|
539
|
+
data: z.string()
|
|
540
|
+
}),
|
|
541
|
+
spec_update: z.object({
|
|
542
|
+
type: z.literal("plan_update_tool_result"),
|
|
543
|
+
status: z.enum([
|
|
544
|
+
"prepare",
|
|
545
|
+
"ready",
|
|
546
|
+
"building",
|
|
547
|
+
"finished"
|
|
548
|
+
]),
|
|
549
|
+
data: z.string(),
|
|
550
|
+
reminder: z.string()
|
|
551
|
+
})
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
//#endregion
|
|
555
|
+
//#region ../agent-provider/src/common/_legacy/MockAgentProvider.ts
|
|
556
|
+
/**
|
|
557
|
+
* Mock 会话数据存储
|
|
558
|
+
* 每个会话都有对应的模拟历史消息
|
|
559
|
+
*/
|
|
560
|
+
const mockSessionHistories = /* @__PURE__ */ new Map();
|
|
561
|
+
mockSessionHistories.set("1", [
|
|
562
|
+
{
|
|
563
|
+
type: "user",
|
|
564
|
+
content: "帮我开发一个五子棋游戏,需要包含以下功能:\n1. 双人对战模式\n2. 悔棋功能\n3. 计时器",
|
|
565
|
+
timestamp: Date.now() - 18e5 - 6e4
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
type: "assistant",
|
|
569
|
+
content: "好的,我来帮你开发一个五子棋游戏。我会创建以下文件结构:\n\n- `index.html` - 主页面\n- `game.js` - 游戏逻辑\n- `style.css` - 样式文件\n\n让我开始创建这些文件...",
|
|
570
|
+
timestamp: Date.now() - 18e5 - 5e4
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
type: "assistant",
|
|
574
|
+
content: "我已经完成了所有文件的创建和修改。游戏支持双人对战、悔棋和计时功能。你可以直接在浏览器中打开 index.html 开始游戏。",
|
|
575
|
+
timestamp: Date.now() - 18e5
|
|
576
|
+
}
|
|
577
|
+
]);
|
|
578
|
+
mockSessionHistories.set("2", [
|
|
579
|
+
{
|
|
580
|
+
type: "user",
|
|
581
|
+
content: "登录页面的样式有问题,按钮颜色不对齐,帮我修复一下",
|
|
582
|
+
timestamp: Date.now() - 72e5 - 12e4
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
type: "assistant",
|
|
586
|
+
content: "我来检查登录页面的样式。让我先看看相关的 CSS 文件...",
|
|
587
|
+
timestamp: Date.now() - 72e5 - 1e5
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
type: "assistant",
|
|
591
|
+
content: "样式问题已修复,请查看效果。主要修改了按钮的 flex 布局和颜色变量。",
|
|
592
|
+
timestamp: Date.now() - 72e5
|
|
593
|
+
}
|
|
594
|
+
]);
|
|
595
|
+
mockSessionHistories.set("3", [
|
|
596
|
+
{
|
|
597
|
+
type: "user",
|
|
598
|
+
content: "API 接口响应太慢了,需要添加缓存和错误重试机制",
|
|
599
|
+
timestamp: Date.now() - 144e5 - 18e4
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
type: "assistant",
|
|
603
|
+
content: "好的,我来优化 API 接口。我会实现:\n1. Redis 缓存层\n2. 指数退避重试策略\n3. 请求去重",
|
|
604
|
+
timestamp: Date.now() - 144e5 - 15e4
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
type: "assistant",
|
|
608
|
+
content: "已添加缓存和错误重试机制。性能提升了约 60%。",
|
|
609
|
+
timestamp: Date.now() - 144e5
|
|
610
|
+
}
|
|
611
|
+
]);
|
|
612
|
+
mockSessionHistories.set("4", [
|
|
613
|
+
{
|
|
614
|
+
type: "user",
|
|
615
|
+
content: "帮我为核心模块添加单元测试,覆盖率要达到 80% 以上",
|
|
616
|
+
timestamp: Date.now() - 864e5 - 3e5
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
type: "assistant",
|
|
620
|
+
content: "好的,我会使用 Jest 来编写单元测试。让我先看看核心模块的代码结构...",
|
|
621
|
+
timestamp: Date.now() - 864e5 - 25e4
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
type: "assistant",
|
|
625
|
+
content: "测试覆盖率已达到 85%,超过了目标。主要测试了:\n- 用户认证逻辑\n- 数据验证\n- 错误处理",
|
|
626
|
+
timestamp: Date.now() - 864e5
|
|
627
|
+
}
|
|
628
|
+
]);
|
|
629
|
+
|
|
630
|
+
//#endregion
|
|
8
631
|
//#region ../agent-client-protocol/src/common/types.ts
|
|
9
632
|
/**
|
|
10
633
|
* Protocol Extension Types for Agent Client Protocol
|
|
@@ -19,7 +642,8 @@ const ExtensionMethod = {
|
|
|
19
642
|
ARTIFACT: "_codebuddy.ai/artifact",
|
|
20
643
|
QUESTION: "_codebuddy.ai/question",
|
|
21
644
|
CHECKPOINT: "_codebuddy.ai/checkpoint",
|
|
22
|
-
USAGE: "_codebuddy.ai/usage"
|
|
645
|
+
USAGE: "_codebuddy.ai/usage",
|
|
646
|
+
COMMAND: "_codebuddy.ai/command"
|
|
23
647
|
};
|
|
24
648
|
/**
|
|
25
649
|
* All known extension methods
|
|
@@ -28,7 +652,8 @@ const KNOWN_EXTENSIONS = [
|
|
|
28
652
|
ExtensionMethod.ARTIFACT,
|
|
29
653
|
ExtensionMethod.QUESTION,
|
|
30
654
|
ExtensionMethod.CHECKPOINT,
|
|
31
|
-
ExtensionMethod.USAGE
|
|
655
|
+
ExtensionMethod.USAGE,
|
|
656
|
+
ExtensionMethod.COMMAND
|
|
32
657
|
];
|
|
33
658
|
|
|
34
659
|
//#endregion
|
|
@@ -81,7 +706,7 @@ function parseSSELine(line, currentEvent) {
|
|
|
81
706
|
function streamableHttp(options) {
|
|
82
707
|
const { endpoint, authToken, headers: customHeaders = {}, reconnect = {}, signal: externalSignal, fetch: customFetch = globalThis.fetch, onConnect, onDisconnect, onError, heartbeatTimeout = 6e4, postTimeout = 3e4, backpressure = {} } = options;
|
|
83
708
|
const { enabled: reconnectEnabled = true, initialDelay = 1e3, maxDelay = 3e4, maxRetries = Infinity, jitter: jitterEnabled = true } = reconnect;
|
|
84
|
-
const { highWaterMark = 100, lowWaterMark = 50 } = backpressure;
|
|
709
|
+
const { highWaterMark = 100, lowWaterMark = 50, pauseTimeout = 5e3 } = backpressure;
|
|
85
710
|
let connectionId;
|
|
86
711
|
let lastEventId;
|
|
87
712
|
let reconnectAttempts = 0;
|
|
@@ -110,6 +735,7 @@ function streamableHttp(options) {
|
|
|
110
735
|
let streamError = null;
|
|
111
736
|
let isPaused = false;
|
|
112
737
|
let resumeReading = null;
|
|
738
|
+
let backgroundSSEProcessors = /* @__PURE__ */ new Set();
|
|
113
739
|
let lastActivity = Date.now();
|
|
114
740
|
let heartbeatCheckTimer;
|
|
115
741
|
function enqueueMessage(message) {
|
|
@@ -132,7 +758,8 @@ function streamableHttp(options) {
|
|
|
132
758
|
const message = messageQueue.shift();
|
|
133
759
|
if (isPaused && messageQueue.length <= lowWaterMark) {
|
|
134
760
|
isPaused = false;
|
|
135
|
-
resumeReading
|
|
761
|
+
const resume = resumeReading;
|
|
762
|
+
if (resume) queueMicrotask(() => resume());
|
|
136
763
|
}
|
|
137
764
|
return Promise.resolve(message);
|
|
138
765
|
}
|
|
@@ -186,6 +813,7 @@ function streamableHttp(options) {
|
|
|
186
813
|
resumeReading();
|
|
187
814
|
resumeReading = null;
|
|
188
815
|
}
|
|
816
|
+
backgroundSSEProcessors.clear();
|
|
189
817
|
while (messageResolvers.length > 0) messageResolvers.shift()(null);
|
|
190
818
|
}
|
|
191
819
|
async function sendDelete() {
|
|
@@ -218,7 +846,21 @@ function streamableHttp(options) {
|
|
|
218
846
|
while (true) {
|
|
219
847
|
if (isPaused) {
|
|
220
848
|
await new Promise((resolve) => {
|
|
221
|
-
|
|
849
|
+
let resolved = false;
|
|
850
|
+
const timeoutId = setTimeout(() => {
|
|
851
|
+
if (!resolved) {
|
|
852
|
+
resolved = true;
|
|
853
|
+
console.warn("[StreamableHTTP] Backpressure pause timeout, forcing resume");
|
|
854
|
+
resolve();
|
|
855
|
+
}
|
|
856
|
+
}, pauseTimeout);
|
|
857
|
+
resumeReading = () => {
|
|
858
|
+
if (!resolved) {
|
|
859
|
+
resolved = true;
|
|
860
|
+
clearTimeout(timeoutId);
|
|
861
|
+
resolve();
|
|
862
|
+
}
|
|
863
|
+
};
|
|
222
864
|
});
|
|
223
865
|
resumeReading = null;
|
|
224
866
|
}
|
|
@@ -251,6 +893,19 @@ function streamableHttp(options) {
|
|
|
251
893
|
reader.releaseLock();
|
|
252
894
|
}
|
|
253
895
|
}
|
|
896
|
+
/**
|
|
897
|
+
* Process SSE stream in background without blocking the caller.
|
|
898
|
+
* This prevents deadlock when POST responses return SSE streams.
|
|
899
|
+
*/
|
|
900
|
+
function processSSEStreamBackground(reader) {
|
|
901
|
+
const promise = processSSEStream(reader).catch((error) => {
|
|
902
|
+
console.error("[StreamableHTTP] Background SSE processing error:", error);
|
|
903
|
+
onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
904
|
+
}).finally(() => {
|
|
905
|
+
backgroundSSEProcessors.delete(promise);
|
|
906
|
+
});
|
|
907
|
+
backgroundSSEProcessors.add(promise);
|
|
908
|
+
}
|
|
254
909
|
async function startSSEConnection() {
|
|
255
910
|
let currentReader = null;
|
|
256
911
|
const triggerReconnect = () => {
|
|
@@ -286,14 +941,14 @@ function streamableHttp(options) {
|
|
|
286
941
|
stopHeartbeatCheck();
|
|
287
942
|
const endedConnectionId = connectionId;
|
|
288
943
|
connectionId = void 0;
|
|
289
|
-
if (
|
|
290
|
-
|
|
291
|
-
break;
|
|
292
|
-
}
|
|
944
|
+
if (endedConnectionId) onDisconnect?.(endedConnectionId);
|
|
945
|
+
if (!reconnectEnabled || closed) break;
|
|
293
946
|
connectionReady = new Promise((resolve, reject) => {
|
|
294
947
|
resolveConnection = resolve;
|
|
295
948
|
rejectConnection = reject;
|
|
296
949
|
});
|
|
950
|
+
const reconnectDelay = calculateDelay(1);
|
|
951
|
+
await new Promise((resolve) => setTimeout(resolve, reconnectDelay));
|
|
297
952
|
} catch (error) {
|
|
298
953
|
stopHeartbeatCheck();
|
|
299
954
|
currentReader = null;
|
|
@@ -310,14 +965,21 @@ function streamableHttp(options) {
|
|
|
310
965
|
}
|
|
311
966
|
async function sendMessage(message) {
|
|
312
967
|
if (closed) throw new Error("Connection is closed");
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
968
|
+
const maxWaitAttempts = 5;
|
|
969
|
+
let currentConnectionId;
|
|
970
|
+
for (let attempt = 0; attempt < maxWaitAttempts; attempt++) {
|
|
971
|
+
const versionBeforeWait = connectionVersion;
|
|
972
|
+
await connectionReady;
|
|
973
|
+
if (versionBeforeWait !== connectionVersion && versionBeforeWait > 0) await connectionReady;
|
|
974
|
+
currentConnectionId = connectionId;
|
|
975
|
+
if (currentConnectionId) break;
|
|
976
|
+
if (attempt < maxWaitAttempts - 1) await new Promise((resolve) => setTimeout(resolve, 100));
|
|
977
|
+
}
|
|
978
|
+
if (!currentConnectionId) throw new Error("No connection ID available after multiple attempts");
|
|
317
979
|
const headers = buildHeaders();
|
|
318
980
|
headers["Content-Type"] = "application/json";
|
|
319
981
|
headers["Accept"] = "application/json, text/event-stream";
|
|
320
|
-
headers["Acp-Connection-Id"] =
|
|
982
|
+
headers["Acp-Connection-Id"] = currentConnectionId;
|
|
321
983
|
const postController = new AbortController();
|
|
322
984
|
let timeoutId;
|
|
323
985
|
const postSignal = postTimeout > 0 ? postController.signal : combinedSignal;
|
|
@@ -340,7 +1002,7 @@ function streamableHttp(options) {
|
|
|
340
1002
|
const contentType = response.headers.get("Content-Type") || "";
|
|
341
1003
|
if (contentType.includes("text/event-stream")) {
|
|
342
1004
|
const reader = response.body?.getReader();
|
|
343
|
-
if (reader)
|
|
1005
|
+
if (reader) processSSEStreamBackground(reader);
|
|
344
1006
|
} else if (contentType.includes("application/json")) {
|
|
345
1007
|
const data = await response.json();
|
|
346
1008
|
if (data && typeof data === "object" && "jsonrpc" in data) enqueueMessage(data);
|
|
@@ -2155,12 +2817,13 @@ var AccountService = class {
|
|
|
2155
2817
|
*/
|
|
2156
2818
|
setAccount(account) {
|
|
2157
2819
|
const prev = this.account;
|
|
2820
|
+
const wasInitialized = this.initialized;
|
|
2158
2821
|
this.account = account;
|
|
2159
2822
|
if (!this.initialized) {
|
|
2160
2823
|
this.initialized = true;
|
|
2161
2824
|
this.initResolve?.(account);
|
|
2162
2825
|
}
|
|
2163
|
-
if (prev?.uid !== account?.uid) this.notifyListeners();
|
|
2826
|
+
if (!wasInitialized || prev?.uid !== account?.uid) this.notifyListeners();
|
|
2164
2827
|
}
|
|
2165
2828
|
/**
|
|
2166
2829
|
* 清除账号(登出)
|
|
@@ -2467,7 +3130,6 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
2467
3130
|
*/
|
|
2468
3131
|
async list(options) {
|
|
2469
3132
|
try {
|
|
2470
|
-
console.log("[CloudAgentProvider] list called with options:", JSON.stringify(options, null, 2));
|
|
2471
3133
|
const params = {
|
|
2472
3134
|
page: 1,
|
|
2473
3135
|
size: 30,
|
|
@@ -2484,7 +3146,6 @@ var CloudAgentProvider = class CloudAgentProvider {
|
|
|
2484
3146
|
...options.title !== void 0 && { title: options.title }
|
|
2485
3147
|
}
|
|
2486
3148
|
};
|
|
2487
|
-
console.log("[CloudAgentProvider] API request params:", JSON.stringify(params, null, 2));
|
|
2488
3149
|
const response = await this.request("GET", "/console/cloudagent/agentmgmt/agents", params);
|
|
2489
3150
|
if (!response.ok) throw new Error(`Failed to list agents: ${response.statusText}`);
|
|
2490
3151
|
const apiResponse = await response.json();
|
|
@@ -3038,6 +3699,13 @@ var ActiveSessionImpl = class {
|
|
|
3038
3699
|
return this._availableCommands;
|
|
3039
3700
|
}
|
|
3040
3701
|
/**
|
|
3702
|
+
* Set available commands (called when available_commands_update is received)
|
|
3703
|
+
*/
|
|
3704
|
+
setAvailableCommands(commands) {
|
|
3705
|
+
this._availableCommands = commands;
|
|
3706
|
+
this.logger?.info(`Session ${this._id}: Available commands updated, count: ${commands.length}`);
|
|
3707
|
+
}
|
|
3708
|
+
/**
|
|
3041
3709
|
* Check if the session is active
|
|
3042
3710
|
*/
|
|
3043
3711
|
get isActive() {
|
|
@@ -3349,6 +4017,9 @@ var ActiveSessionImpl = class {
|
|
|
3349
4017
|
connection.on("questionRequest", (request) => {
|
|
3350
4018
|
this.emit("questionRequest", request);
|
|
3351
4019
|
});
|
|
4020
|
+
connection.on("questionCancelled", () => {
|
|
4021
|
+
this.prompts.cancel();
|
|
4022
|
+
});
|
|
3352
4023
|
connection.on("usageUpdate", (usage) => {
|
|
3353
4024
|
this.emit("usageUpdate", usage);
|
|
3354
4025
|
});
|
|
@@ -3358,6 +4029,13 @@ var ActiveSessionImpl = class {
|
|
|
3358
4029
|
connection.on("checkpointUpdated", (checkpoint) => {
|
|
3359
4030
|
this.emit("checkpointUpdated", checkpoint);
|
|
3360
4031
|
});
|
|
4032
|
+
connection.on("command", (command) => {
|
|
4033
|
+
console.log("[Session] Forwarding command:", {
|
|
4034
|
+
action: command.action,
|
|
4035
|
+
paramsKeys: command.params ? Object.keys(command.params) : []
|
|
4036
|
+
});
|
|
4037
|
+
this.emit("command", command);
|
|
4038
|
+
});
|
|
3361
4039
|
}
|
|
3362
4040
|
mapPromptResponse(response) {
|
|
3363
4041
|
return {
|
|
@@ -3410,12 +4088,7 @@ var SessionManager = class {
|
|
|
3410
4088
|
* @param options - Optional query parameters for filtering, sorting, and pagination
|
|
3411
4089
|
*/
|
|
3412
4090
|
async listSessions(options) {
|
|
3413
|
-
console.log("[SessionManager] listSessions called with options:", JSON.stringify(options, null, 2));
|
|
3414
4091
|
const result = await this.provider.list(options);
|
|
3415
|
-
console.log("[SessionManager] provider.list returned:", {
|
|
3416
|
-
agentsCount: result.agents.length,
|
|
3417
|
-
pagination: result.pagination
|
|
3418
|
-
});
|
|
3419
4092
|
const sessions = result.agents.map((agent) => ({
|
|
3420
4093
|
id: agent.id,
|
|
3421
4094
|
agentId: agent.id,
|
|
@@ -3454,6 +4127,7 @@ var SessionManager = class {
|
|
|
3454
4127
|
const connection = await this.provider.connect(agentId);
|
|
3455
4128
|
this.logger?.debug(`Connected to agent: ${agentId}`);
|
|
3456
4129
|
const response = await connection.createSession({
|
|
4130
|
+
_meta: params._meta,
|
|
3457
4131
|
cwd: params.cwd,
|
|
3458
4132
|
mcpServers: params.mcpServers
|
|
3459
4133
|
});
|
|
@@ -3613,6 +4287,20 @@ var AgentClient = class {
|
|
|
3613
4287
|
throw error;
|
|
3614
4288
|
}
|
|
3615
4289
|
},
|
|
4290
|
+
move: async (sessionId) => {
|
|
4291
|
+
this.logger?.debug("AgentClient.sessions.move called", { sessionId });
|
|
4292
|
+
try {
|
|
4293
|
+
if (this.provider.move) {
|
|
4294
|
+
const result = await this.provider.move(sessionId);
|
|
4295
|
+
this.logger?.info("Session moved successfully", { sessionId });
|
|
4296
|
+
return result;
|
|
4297
|
+
}
|
|
4298
|
+
throw new Error("Provider does not support move method");
|
|
4299
|
+
} catch (error) {
|
|
4300
|
+
this.logger?.error("Failed to move session", error);
|
|
4301
|
+
throw error;
|
|
4302
|
+
}
|
|
4303
|
+
},
|
|
3616
4304
|
initializeWorkspace: async (params) => {
|
|
3617
4305
|
this.logger?.debug("AgentClient.sessions.initializeWorkspace called", params);
|
|
3618
4306
|
try {
|
|
@@ -3765,6 +4453,36 @@ var AgentClient = class {
|
|
|
3765
4453
|
};
|
|
3766
4454
|
}
|
|
3767
4455
|
},
|
|
4456
|
+
batchTogglePlugins: async (request) => {
|
|
4457
|
+
try {
|
|
4458
|
+
if (this.provider && this.provider.batchTogglePlugins) {
|
|
4459
|
+
const result = await this.provider.batchTogglePlugins(request);
|
|
4460
|
+
this.logger?.info("Batch toggle plugins completed", {
|
|
4461
|
+
succeededCount: result.succeededPlugins.length,
|
|
4462
|
+
failedCount: result.failedPlugins.length
|
|
4463
|
+
});
|
|
4464
|
+
return result;
|
|
4465
|
+
}
|
|
4466
|
+
return {
|
|
4467
|
+
success: false,
|
|
4468
|
+
succeededPlugins: [],
|
|
4469
|
+
failedPlugins: request.items.map((item) => ({
|
|
4470
|
+
...item,
|
|
4471
|
+
error: "Provider does not support batchTogglePlugins"
|
|
4472
|
+
}))
|
|
4473
|
+
};
|
|
4474
|
+
} catch (error) {
|
|
4475
|
+
this.logger?.error("Failed to batch toggle plugins", error);
|
|
4476
|
+
return {
|
|
4477
|
+
success: false,
|
|
4478
|
+
succeededPlugins: [],
|
|
4479
|
+
failedPlugins: request.items.map((item) => ({
|
|
4480
|
+
...item,
|
|
4481
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
4482
|
+
}))
|
|
4483
|
+
};
|
|
4484
|
+
}
|
|
4485
|
+
},
|
|
3768
4486
|
models: this.createModelsResource()
|
|
3769
4487
|
};
|
|
3770
4488
|
}
|
|
@@ -3845,12 +4563,33 @@ const getSelectAccountUrl = () => `${window.location.origin}/login/select`;
|
|
|
3845
4563
|
/** localStorage 中存储选中账号 ID 的 key */
|
|
3846
4564
|
const SELECTED_ACCOUNT_KEY = "CODEBUDDY_IDE_SELECTED_ACCOUNT_ID";
|
|
3847
4565
|
/**
|
|
4566
|
+
* 套餐代码对应的 i18n key 映射
|
|
4567
|
+
*/
|
|
4568
|
+
const CommodityCodeText = {
|
|
4569
|
+
[CommodityCode.free]: "plan.codebuddyFreePlan",
|
|
4570
|
+
[CommodityCode.proMon]: "plan.codebuddyProPlanMonthly",
|
|
4571
|
+
[CommodityCode.proMonPlus]: "plan.codebuddyProPlanMonthly",
|
|
4572
|
+
[CommodityCode.gift]: "plan.codebuddyProPlanTrial",
|
|
4573
|
+
[CommodityCode.activity]: "plan.codebuddyGrowthPlan",
|
|
4574
|
+
[CommodityCode.proYear]: "plan.codebuddyProPlanYearly",
|
|
4575
|
+
[CommodityCode.freeMon]: "plan.codebuddyProPlanDaily",
|
|
4576
|
+
[CommodityCode.extra]: "plan.codebuddyCreditPackage"
|
|
4577
|
+
};
|
|
4578
|
+
/**
|
|
4579
|
+
* 获取套餐名称的 i18n key
|
|
4580
|
+
*/
|
|
4581
|
+
const getPackageName = (packageCode) => {
|
|
4582
|
+
return CommodityCodeText[packageCode] || "";
|
|
4583
|
+
};
|
|
4584
|
+
/**
|
|
3848
4585
|
* Backend Provider 实现类
|
|
3849
4586
|
*
|
|
3850
4587
|
* 职责:
|
|
3851
|
-
* - 与后端 API 通信(getAgents, getModels, getAccount 等)
|
|
3852
4588
|
* - 触发登录/登出流程
|
|
3853
4589
|
* - 获取 account 后自动同步到 accountService
|
|
4590
|
+
*
|
|
4591
|
+
* 注意:getAgents 和 getModels 方法已废弃并移除,
|
|
4592
|
+
* 请使用 IAgentAdapter 中的对应方法
|
|
3854
4593
|
*/
|
|
3855
4594
|
var BackendProvider = class {
|
|
3856
4595
|
constructor(config) {
|
|
@@ -3858,98 +4597,6 @@ var BackendProvider = class {
|
|
|
3858
4597
|
this.authToken = config.authToken;
|
|
3859
4598
|
}
|
|
3860
4599
|
/**
|
|
3861
|
-
* 获取 Agent 列表
|
|
3862
|
-
* API 端点: GET /v2/cloudagent/agentmgmt/agents
|
|
3863
|
-
*/
|
|
3864
|
-
async getAgents(request = {}) {
|
|
3865
|
-
const { MockAgentProvider } = await import("./MockAgentProvider-tNdtAJCv.mjs");
|
|
3866
|
-
const sessions = new MockAgentProvider().getAllSessions();
|
|
3867
|
-
const mockTitles = {
|
|
3868
|
-
"1": "开发五子棋游戏",
|
|
3869
|
-
"2": "修复登录页面样式",
|
|
3870
|
-
"3": "API 接口优化"
|
|
3871
|
-
};
|
|
3872
|
-
const agents = sessions.map((session, index) => ({
|
|
3873
|
-
id: session.sessionId,
|
|
3874
|
-
name: mockTitles[session.sessionId] || `Agent ${session.sessionId}`,
|
|
3875
|
-
status: "RUNNING",
|
|
3876
|
-
visibility: "PRIVATE",
|
|
3877
|
-
createdAt: new Date(session.createdAt).toISOString(),
|
|
3878
|
-
summary: `Session created at ${new Date(session.createdAt).toLocaleString()}`,
|
|
3879
|
-
source: {
|
|
3880
|
-
provider: "github",
|
|
3881
|
-
ref: "refs/heads/main",
|
|
3882
|
-
repository: session.cwd
|
|
3883
|
-
},
|
|
3884
|
-
target: {
|
|
3885
|
-
autoCreatePr: false,
|
|
3886
|
-
branchName: "feature/mock",
|
|
3887
|
-
prUrl: void 0,
|
|
3888
|
-
url: void 0
|
|
3889
|
-
}
|
|
3890
|
-
}));
|
|
3891
|
-
return {
|
|
3892
|
-
agents,
|
|
3893
|
-
pagination: {
|
|
3894
|
-
hasNext: false,
|
|
3895
|
-
hasPrev: false,
|
|
3896
|
-
page: 1,
|
|
3897
|
-
size: agents.length,
|
|
3898
|
-
total: agents.length,
|
|
3899
|
-
totalPages: 1
|
|
3900
|
-
}
|
|
3901
|
-
};
|
|
3902
|
-
}
|
|
3903
|
-
/**
|
|
3904
|
-
* 获取可用模型列表
|
|
3905
|
-
* API 端点: GET /v2/cloudagent/models (假设)
|
|
3906
|
-
*
|
|
3907
|
-
* 当前实现: 返回 Mock 数据
|
|
3908
|
-
*/
|
|
3909
|
-
async getModels(request) {
|
|
3910
|
-
const mockModels = [{
|
|
3911
|
-
id: "glm-4.7",
|
|
3912
|
-
name: "GLM-4.7",
|
|
3913
|
-
vendor: "f",
|
|
3914
|
-
maxOutputTokens: 48e3,
|
|
3915
|
-
maxInputTokens: 2e5,
|
|
3916
|
-
supportsToolCall: true,
|
|
3917
|
-
supportsImages: false,
|
|
3918
|
-
disabledMultimodal: true,
|
|
3919
|
-
maxAllowedSize: 2e5,
|
|
3920
|
-
supportsReasoning: true,
|
|
3921
|
-
onlyReasoning: true,
|
|
3922
|
-
temperature: 1,
|
|
3923
|
-
reasoning: {
|
|
3924
|
-
effort: "medium",
|
|
3925
|
-
summary: "auto"
|
|
3926
|
-
},
|
|
3927
|
-
descriptionEn: "GLM-4.7 model, Well-rounded model for everyday use",
|
|
3928
|
-
descriptionZh: "GLM-4.7 大模型,能力均衡,适合日常使用"
|
|
3929
|
-
}, {
|
|
3930
|
-
id: "glm-4.7-flash",
|
|
3931
|
-
name: "GLM-4.7 Flash",
|
|
3932
|
-
vendor: "f",
|
|
3933
|
-
maxOutputTokens: 4e4,
|
|
3934
|
-
maxInputTokens: 128e3,
|
|
3935
|
-
supportsToolCall: true,
|
|
3936
|
-
supportsImages: false,
|
|
3937
|
-
disabledMultimodal: false,
|
|
3938
|
-
maxAllowedSize: 128e3,
|
|
3939
|
-
supportsReasoning: false,
|
|
3940
|
-
onlyReasoning: false,
|
|
3941
|
-
temperature: .7,
|
|
3942
|
-
reasoning: {
|
|
3943
|
-
effort: "low",
|
|
3944
|
-
summary: "never"
|
|
3945
|
-
},
|
|
3946
|
-
descriptionEn: "GLM-4.7 Flash, Fast and efficient model",
|
|
3947
|
-
descriptionZh: "GLM-4.7 Flash,快速高效的模型"
|
|
3948
|
-
}];
|
|
3949
|
-
console.log("[BackendProvider] getModels called for repository:", request.repository);
|
|
3950
|
-
return { models: mockModels };
|
|
3951
|
-
}
|
|
3952
|
-
/**
|
|
3953
4600
|
* 获取当前账号信息
|
|
3954
4601
|
* API 端点: GET /console/accounts (返回账号列表)
|
|
3955
4602
|
*
|
|
@@ -4000,53 +4647,335 @@ var BackendProvider = class {
|
|
|
4000
4647
|
if (account.type === "personal") return account.uid === selectedAccountId;
|
|
4001
4648
|
return account.enterpriseId === selectedAccountId;
|
|
4002
4649
|
});
|
|
4003
|
-
if (selectedAccount)
|
|
4004
|
-
const
|
|
4005
|
-
const editionType = this.getEditionDisplayType(selectedAccount.type, plan.isPro);
|
|
4006
|
-
console.log("account", {
|
|
4007
|
-
...selectedAccount,
|
|
4008
|
-
...plan,
|
|
4009
|
-
editionType
|
|
4010
|
-
});
|
|
4011
|
-
const account = {
|
|
4012
|
-
...selectedAccount,
|
|
4013
|
-
...plan,
|
|
4014
|
-
editionType
|
|
4015
|
-
};
|
|
4650
|
+
if (selectedAccount) {
|
|
4651
|
+
const account = await this.enrichAccountWithUsage(selectedAccount);
|
|
4016
4652
|
accountService.setAccount(account);
|
|
4017
4653
|
return account;
|
|
4018
|
-
} catch (error) {
|
|
4019
|
-
accountService.setAccount(selectedAccount);
|
|
4020
|
-
return { ...selectedAccount };
|
|
4021
4654
|
}
|
|
4022
4655
|
}
|
|
4023
4656
|
if (accounts.length === 1) {
|
|
4024
4657
|
selectedAccount = accounts[0];
|
|
4025
4658
|
const accountId = selectedAccount.type === "personal" ? selectedAccount.uid : selectedAccount.enterpriseId;
|
|
4026
4659
|
if (accountId) localStorage.setItem(SELECTED_ACCOUNT_KEY, accountId);
|
|
4660
|
+
const account = await this.enrichAccountWithUsage(selectedAccount);
|
|
4661
|
+
console.log("account (auto-selected)", account);
|
|
4662
|
+
accountService.setAccount(account);
|
|
4663
|
+
return account;
|
|
4664
|
+
}
|
|
4665
|
+
const redirectUrl = encodeURIComponent(window.location.href);
|
|
4666
|
+
window.location.href = `${getSelectAccountUrl()}?platform=website&state=0&redirect_uri=${redirectUrl}`;
|
|
4667
|
+
accountService.setAccount(null);
|
|
4668
|
+
return null;
|
|
4669
|
+
} catch (error) {
|
|
4670
|
+
console.error("[BackendProvider] getAccount failed:", error);
|
|
4671
|
+
accountService.setAccount(null);
|
|
4672
|
+
return null;
|
|
4673
|
+
}
|
|
4674
|
+
}
|
|
4675
|
+
/**
|
|
4676
|
+
* 获取用户连接器列表
|
|
4677
|
+
* API 端点: GET /console/as/connector/user/
|
|
4678
|
+
*/
|
|
4679
|
+
async getUserConnector() {
|
|
4680
|
+
const url = `${this.baseUrl}/console/as/connector/user/`;
|
|
4681
|
+
const headers = {
|
|
4682
|
+
"Content-Type": "application/json",
|
|
4683
|
+
"Accept": "application/json"
|
|
4684
|
+
};
|
|
4685
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4686
|
+
try {
|
|
4687
|
+
const result = await (await fetch(url, {
|
|
4688
|
+
method: "GET",
|
|
4689
|
+
headers,
|
|
4690
|
+
credentials: "include"
|
|
4691
|
+
})).json();
|
|
4692
|
+
if (result.code === 0) {
|
|
4693
|
+
const { connectors } = result.data;
|
|
4694
|
+
return { connectors: connectors.map((connector) => ({
|
|
4695
|
+
...connector,
|
|
4696
|
+
connectStatus: connector.connect_status,
|
|
4697
|
+
activeStatus: connector.active_status,
|
|
4698
|
+
displayName: connector.display_name,
|
|
4699
|
+
oauthClientId: connector.oauth_client_id,
|
|
4700
|
+
oauthRedirectUrl: connector.oauth_redirect_url
|
|
4701
|
+
})) };
|
|
4702
|
+
}
|
|
4703
|
+
throw result;
|
|
4704
|
+
} catch (error) {
|
|
4705
|
+
throw error;
|
|
4706
|
+
}
|
|
4707
|
+
}
|
|
4708
|
+
/**
|
|
4709
|
+
* 修改用户连接器连接状态
|
|
4710
|
+
* API 端点: PATCH /console/as/connector/user/:name/connect_status
|
|
4711
|
+
*/
|
|
4712
|
+
async modifyUserConnectorConnectStatus(request) {
|
|
4713
|
+
const url = `${this.baseUrl}/console/as/connector/user/${request.name}/connect_status`;
|
|
4714
|
+
const headers = {
|
|
4715
|
+
"Content-Type": "application/json",
|
|
4716
|
+
"Accept": "application/json"
|
|
4717
|
+
};
|
|
4718
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4719
|
+
const body = {
|
|
4720
|
+
name: request.name,
|
|
4721
|
+
connect_status: request.connectStatus
|
|
4722
|
+
};
|
|
4723
|
+
if (request.activeStatus !== void 0) body.active_status = request.activeStatus;
|
|
4724
|
+
if (request.repos !== void 0) body.repos = request.repos;
|
|
4725
|
+
try {
|
|
4726
|
+
const result = await (await fetch(url, {
|
|
4727
|
+
method: "PATCH",
|
|
4728
|
+
headers,
|
|
4729
|
+
credentials: "include",
|
|
4730
|
+
body: JSON.stringify(body)
|
|
4731
|
+
})).json();
|
|
4732
|
+
if (result.code === 0) return;
|
|
4733
|
+
throw result;
|
|
4734
|
+
} catch (error) {
|
|
4735
|
+
throw error;
|
|
4736
|
+
}
|
|
4737
|
+
}
|
|
4738
|
+
/**
|
|
4739
|
+
* 修改用户连接器仓库
|
|
4740
|
+
* API 端点: PATCH /console/as/connector/user/:name/repo/
|
|
4741
|
+
*/
|
|
4742
|
+
async modifyUserConnectorRepo(request) {
|
|
4743
|
+
const url = `${this.baseUrl}/console/as/connector/user/${request.name}/repo`;
|
|
4744
|
+
const headers = {
|
|
4745
|
+
"Content-Type": "application/json",
|
|
4746
|
+
"Accept": "application/json"
|
|
4747
|
+
};
|
|
4748
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4749
|
+
const body = { name: request.name };
|
|
4750
|
+
if (request.repo !== void 0) body.repo = request.repo;
|
|
4751
|
+
try {
|
|
4752
|
+
const result = await (await fetch(url, {
|
|
4753
|
+
method: "PATCH",
|
|
4754
|
+
headers,
|
|
4755
|
+
credentials: "include",
|
|
4756
|
+
body: JSON.stringify(body)
|
|
4757
|
+
})).json();
|
|
4758
|
+
if (result.code === 0) return;
|
|
4759
|
+
throw result;
|
|
4760
|
+
} catch (error) {
|
|
4761
|
+
throw error;
|
|
4762
|
+
}
|
|
4763
|
+
}
|
|
4764
|
+
/**
|
|
4765
|
+
* 修改用户连接器激活状态
|
|
4766
|
+
* API 端点: PATCH /console/as/connector/user/:name/active_status
|
|
4767
|
+
*/
|
|
4768
|
+
async modifyUserConnectorActiveStatus(request) {
|
|
4769
|
+
const url = `${this.baseUrl}/console/as/connector/user/${request.name}/active_status`;
|
|
4770
|
+
const headers = {
|
|
4771
|
+
"Content-Type": "application/json",
|
|
4772
|
+
"Accept": "application/json"
|
|
4773
|
+
};
|
|
4774
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4775
|
+
const body = {
|
|
4776
|
+
name: request.name,
|
|
4777
|
+
active_status: request.activeStatus
|
|
4778
|
+
};
|
|
4779
|
+
try {
|
|
4780
|
+
const result = await (await fetch(url, {
|
|
4781
|
+
method: "PATCH",
|
|
4782
|
+
headers,
|
|
4783
|
+
credentials: "include",
|
|
4784
|
+
body: JSON.stringify(body)
|
|
4785
|
+
})).json();
|
|
4786
|
+
if (result.code === 0) return;
|
|
4787
|
+
throw result;
|
|
4788
|
+
} catch (error) {
|
|
4789
|
+
throw error;
|
|
4790
|
+
}
|
|
4791
|
+
}
|
|
4792
|
+
/**
|
|
4793
|
+
* 删除用户连接器
|
|
4794
|
+
* API 端点: DELETE /console/as/connector/user/:name/
|
|
4795
|
+
*/
|
|
4796
|
+
async deleteUserConnector(name) {
|
|
4797
|
+
const url = `${this.baseUrl}/console/as/connector/user/${name}/`;
|
|
4798
|
+
const headers = {
|
|
4799
|
+
"Content-Type": "application/json",
|
|
4800
|
+
"Accept": "application/json"
|
|
4801
|
+
};
|
|
4802
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4803
|
+
try {
|
|
4804
|
+
const result = await (await fetch(url, {
|
|
4805
|
+
method: "DELETE",
|
|
4806
|
+
headers,
|
|
4807
|
+
credentials: "include"
|
|
4808
|
+
})).json();
|
|
4809
|
+
if (result.code === 0) return;
|
|
4810
|
+
throw result;
|
|
4811
|
+
} catch (error) {
|
|
4812
|
+
throw error;
|
|
4813
|
+
}
|
|
4814
|
+
}
|
|
4815
|
+
/**
|
|
4816
|
+
* 添加任务
|
|
4817
|
+
* API 端点: POST /console/as/connector/task/
|
|
4818
|
+
*/
|
|
4819
|
+
async addConnectorTask(request) {
|
|
4820
|
+
const url = `${this.baseUrl}/console/as/connector/task/`;
|
|
4821
|
+
const headers = {
|
|
4822
|
+
"Content-Type": "application/json",
|
|
4823
|
+
"Accept": "application/json"
|
|
4824
|
+
};
|
|
4825
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4826
|
+
const body = { task_id: request.taskId };
|
|
4827
|
+
if (request.connectors !== void 0) body.connectors = request.connectors.map((c) => ({
|
|
4828
|
+
name: c.name,
|
|
4829
|
+
repos: c.repos,
|
|
4830
|
+
active_status: c.activeStatus
|
|
4831
|
+
}));
|
|
4832
|
+
try {
|
|
4833
|
+
const result = await (await fetch(url, {
|
|
4834
|
+
method: "POST",
|
|
4835
|
+
headers,
|
|
4836
|
+
credentials: "include",
|
|
4837
|
+
body: JSON.stringify(body)
|
|
4838
|
+
})).json();
|
|
4839
|
+
if (result.code === 0) return { taskId: result.data?.task_id || request.taskId };
|
|
4840
|
+
throw result;
|
|
4841
|
+
} catch (error) {
|
|
4842
|
+
throw error;
|
|
4843
|
+
}
|
|
4844
|
+
}
|
|
4845
|
+
/**
|
|
4846
|
+
* 获取任务连接器列表
|
|
4847
|
+
* API 端点: GET /console/as/connector/task/:taskid
|
|
4848
|
+
*/
|
|
4849
|
+
async getTaskConnector(taskId) {
|
|
4850
|
+
const url = `${this.baseUrl}/console/as/connector/task/${taskId}`;
|
|
4851
|
+
const headers = {
|
|
4852
|
+
"Content-Type": "application/json",
|
|
4853
|
+
"Accept": "application/json"
|
|
4854
|
+
};
|
|
4855
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4856
|
+
try {
|
|
4857
|
+
const result = await (await fetch(url, {
|
|
4858
|
+
method: "GET",
|
|
4859
|
+
headers,
|
|
4860
|
+
credentials: "include"
|
|
4861
|
+
})).json();
|
|
4862
|
+
if (result.code === 0) {
|
|
4863
|
+
const { connectors } = result.data;
|
|
4864
|
+
return { connectors: (connectors || []).map((connector) => ({
|
|
4865
|
+
...connector,
|
|
4866
|
+
activeStatus: connector.active_status,
|
|
4867
|
+
connectStatus: connector.connect_status,
|
|
4868
|
+
displayName: connector.display_name,
|
|
4869
|
+
oauthClientId: connector.oauth_client_id,
|
|
4870
|
+
oauthRedirectUrl: connector.oauth_redirect_url
|
|
4871
|
+
})) };
|
|
4872
|
+
}
|
|
4873
|
+
throw result;
|
|
4874
|
+
} catch (error) {
|
|
4875
|
+
throw error;
|
|
4876
|
+
}
|
|
4877
|
+
}
|
|
4878
|
+
/**
|
|
4879
|
+
* 修改任务连接器激活状态
|
|
4880
|
+
* API 端点: PATCH /console/as/connector/task/:taskid/active_status
|
|
4881
|
+
*/
|
|
4882
|
+
async modifyTaskConnectorActiveStatus(request) {
|
|
4883
|
+
const url = `${this.baseUrl}/console/as/connector/task/${request.taskId}/active_status`;
|
|
4884
|
+
const headers = {
|
|
4885
|
+
"Content-Type": "application/json",
|
|
4886
|
+
"Accept": "application/json"
|
|
4887
|
+
};
|
|
4888
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4889
|
+
const body = {
|
|
4890
|
+
task_id: request.taskId,
|
|
4891
|
+
name: request.name,
|
|
4892
|
+
active_status: request.activeStatus
|
|
4893
|
+
};
|
|
4894
|
+
try {
|
|
4895
|
+
const result = await (await fetch(url, {
|
|
4896
|
+
method: "PATCH",
|
|
4897
|
+
headers,
|
|
4898
|
+
credentials: "include",
|
|
4899
|
+
body: JSON.stringify(body)
|
|
4900
|
+
})).json();
|
|
4901
|
+
if (result.code === 0) return { taskId: result.data?.task_id || request.taskId };
|
|
4902
|
+
throw result;
|
|
4903
|
+
} catch (error) {
|
|
4904
|
+
throw error;
|
|
4905
|
+
}
|
|
4906
|
+
}
|
|
4907
|
+
/**
|
|
4908
|
+
* 修改任务连接器仓库
|
|
4909
|
+
* API 端点: PATCH /console/as/connector/task/:taskid/repo
|
|
4910
|
+
*/
|
|
4911
|
+
async modifyTaskConnectorRepo(request) {
|
|
4912
|
+
const url = `${this.baseUrl}/console/as/connector/task/${request.taskId}/repo`;
|
|
4913
|
+
const headers = {
|
|
4914
|
+
"Content-Type": "application/json",
|
|
4915
|
+
"Accept": "application/json"
|
|
4916
|
+
};
|
|
4917
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4918
|
+
const body = {
|
|
4919
|
+
task_id: request.taskId,
|
|
4920
|
+
name: request.name,
|
|
4921
|
+
repo: request.repo
|
|
4922
|
+
};
|
|
4923
|
+
try {
|
|
4924
|
+
const result = await (await fetch(url, {
|
|
4925
|
+
method: "PATCH",
|
|
4926
|
+
headers,
|
|
4927
|
+
credentials: "include",
|
|
4928
|
+
body: JSON.stringify(body)
|
|
4929
|
+
})).json();
|
|
4930
|
+
if (result.code === 0) return { taskId: result.data?.task_id || request.taskId };
|
|
4931
|
+
throw result;
|
|
4932
|
+
} catch (error) {
|
|
4933
|
+
throw error;
|
|
4934
|
+
}
|
|
4935
|
+
}
|
|
4936
|
+
/**
|
|
4937
|
+
* 根据账号类型获取用量信息并合并到账号中
|
|
4938
|
+
* - 企业用户:调用 getEnterpriseUsage 获取月度限额
|
|
4939
|
+
* - 个人用户:调用 getCurrentPlan 获取套餐信息
|
|
4940
|
+
*/
|
|
4941
|
+
async enrichAccountWithUsage(selectedAccount) {
|
|
4942
|
+
const isEnterpriseUser = !!(selectedAccount.enterpriseId && selectedAccount.enterpriseId !== "");
|
|
4943
|
+
try {
|
|
4944
|
+
if (isEnterpriseUser) {
|
|
4945
|
+
const enterpriseUsage = await this.getEnterpriseUsage(selectedAccount.enterpriseId);
|
|
4946
|
+
const editionType = this.getEditionDisplayType(selectedAccount.type, false);
|
|
4947
|
+
if (enterpriseUsage) {
|
|
4948
|
+
const usageLeft = (enterpriseUsage.limitNum - enterpriseUsage.credit).toString();
|
|
4949
|
+
const usageTotal = enterpriseUsage.limitNum.toString();
|
|
4950
|
+
return {
|
|
4951
|
+
...selectedAccount,
|
|
4952
|
+
editionType,
|
|
4953
|
+
usageLeft,
|
|
4954
|
+
usageTotal,
|
|
4955
|
+
refreshAt: enterpriseUsage.cycleResetTime ? new Date(enterpriseUsage.cycleResetTime).getTime() : void 0
|
|
4956
|
+
};
|
|
4957
|
+
}
|
|
4958
|
+
return {
|
|
4959
|
+
...selectedAccount,
|
|
4960
|
+
editionType
|
|
4961
|
+
};
|
|
4962
|
+
} else {
|
|
4027
4963
|
const plan = await this.getCurrentPlan();
|
|
4028
4964
|
const editionType = this.getEditionDisplayType(selectedAccount.type, plan.isPro);
|
|
4029
|
-
console.log("account
|
|
4965
|
+
console.log("account", {
|
|
4030
4966
|
...selectedAccount,
|
|
4031
4967
|
...plan,
|
|
4032
4968
|
editionType
|
|
4033
4969
|
});
|
|
4034
|
-
|
|
4970
|
+
return {
|
|
4035
4971
|
...selectedAccount,
|
|
4036
4972
|
...plan,
|
|
4037
4973
|
editionType
|
|
4038
4974
|
};
|
|
4039
|
-
accountService.setAccount(account);
|
|
4040
|
-
return account;
|
|
4041
4975
|
}
|
|
4042
|
-
const redirectUrl = encodeURIComponent(window.location.href);
|
|
4043
|
-
window.location.href = `${getSelectAccountUrl()}?platform=website&state=0&redirect_uri=${redirectUrl}`;
|
|
4044
|
-
accountService.setAccount(null);
|
|
4045
|
-
return null;
|
|
4046
4976
|
} catch (error) {
|
|
4047
|
-
console.error("[BackendProvider]
|
|
4048
|
-
|
|
4049
|
-
return null;
|
|
4977
|
+
console.error("[BackendProvider] enrichAccountWithUsage failed:", error);
|
|
4978
|
+
return { ...selectedAccount };
|
|
4050
4979
|
}
|
|
4051
4980
|
}
|
|
4052
4981
|
/**
|
|
@@ -4068,7 +4997,6 @@ var BackendProvider = class {
|
|
|
4068
4997
|
"Content-Type": "application/json",
|
|
4069
4998
|
"Accept": "application/json"
|
|
4070
4999
|
};
|
|
4071
|
-
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
4072
5000
|
const now = /* @__PURE__ */ new Date();
|
|
4073
5001
|
const futureDate = new Date(now.getTime() + 101 * 365 * 24 * 60 * 60 * 1e3);
|
|
4074
5002
|
const formatDate = (d) => {
|
|
@@ -4095,34 +5023,174 @@ var BackendProvider = class {
|
|
|
4095
5023
|
}
|
|
4096
5024
|
const resources = (await response.json())?.data?.Response?.Data?.Accounts || [];
|
|
4097
5025
|
if (!resources || resources.length === 0) return defaultPlan;
|
|
5026
|
+
const parseTime = (time) => {
|
|
5027
|
+
if (!time) return 0;
|
|
5028
|
+
return new Date(time).getTime();
|
|
5029
|
+
};
|
|
5030
|
+
const dailyCredits = [CommodityCode.free, CommodityCode.freeMon];
|
|
5031
|
+
const planResources = resources.map((r) => {
|
|
5032
|
+
const isDaily = dailyCredits.includes(r.PackageCode);
|
|
5033
|
+
const endTime = isDaily ? r.CycleEndTime : r.DeductionEndTime;
|
|
5034
|
+
return {
|
|
5035
|
+
id: r.ResourceId,
|
|
5036
|
+
name: isDaily ? "plan.addonCredits" : getPackageName(r.PackageCode),
|
|
5037
|
+
packageCode: r.PackageCode,
|
|
5038
|
+
isDaily,
|
|
5039
|
+
total: Number(r.CycleCapacitySizePrecise) || 0,
|
|
5040
|
+
used: Math.max(0, Number(r.CycleCapacitySizePrecise) - Number(r.CycleCapacityRemainPrecise)) || 0,
|
|
5041
|
+
left: Number(r.CycleCapacityRemainPrecise) || 0,
|
|
5042
|
+
expireAt: parseTime(endTime),
|
|
5043
|
+
refreshAt: isDaily ? void 0 : parseTime(r.CycleEndTime)
|
|
5044
|
+
};
|
|
5045
|
+
}).sort((a, b) => {
|
|
5046
|
+
const getPriority = (code) => {
|
|
5047
|
+
if ([
|
|
5048
|
+
CommodityCode.proMon,
|
|
5049
|
+
CommodityCode.proMonPlus,
|
|
5050
|
+
CommodityCode.proYear,
|
|
5051
|
+
CommodityCode.extra
|
|
5052
|
+
].includes(code)) return 1;
|
|
5053
|
+
if ([CommodityCode.gift, CommodityCode.activity].includes(code)) return 2;
|
|
5054
|
+
if ([CommodityCode.free, CommodityCode.freeMon].includes(code)) return 3;
|
|
5055
|
+
return 4;
|
|
5056
|
+
};
|
|
5057
|
+
return getPriority(a.packageCode) - getPriority(b.packageCode);
|
|
5058
|
+
});
|
|
4098
5059
|
const proPlan = resources.find((r) => r.PackageCode === CommodityCode.proYear || r.PackageCode === CommodityCode.proMon || r.PackageCode === CommodityCode.proMonPlus);
|
|
4099
5060
|
const trialPlan = resources.find((r) => r.PackageCode === CommodityCode.gift || r.PackageCode === CommodityCode.freeMon);
|
|
4100
5061
|
const activePlan = proPlan || trialPlan;
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
5062
|
+
const totalUsageLeft = planResources.reduce((sum, r) => sum + r.left, 0);
|
|
5063
|
+
const totalUsageTotal = planResources.reduce((sum, r) => sum + r.total, 0);
|
|
5064
|
+
const totalUsageUsed = planResources.reduce((sum, r) => sum + r.used, 0);
|
|
5065
|
+
if (activePlan) return {
|
|
5066
|
+
isPro: !!proPlan,
|
|
5067
|
+
isTria: trialPlan ? [AccountStatus.valid, AccountStatus.usedUp].includes(trialPlan.Status) : false,
|
|
5068
|
+
expireAt: parseTime(activePlan.DeductionEndTime || activePlan.ExpiredTime || activePlan.CycleEndTime),
|
|
5069
|
+
refreshAt: parseTime(activePlan.CycleEndTime),
|
|
5070
|
+
renewFlag: Number(activePlan.AutoRenewFlag) === 1 ? 1 : 0,
|
|
5071
|
+
PackageCode: activePlan.PackageCode,
|
|
5072
|
+
name: getPackageName(activePlan.PackageCode),
|
|
5073
|
+
usageTotal: String(totalUsageTotal),
|
|
5074
|
+
usageUsed: String(totalUsageUsed),
|
|
5075
|
+
usageLeft: String(totalUsageLeft),
|
|
5076
|
+
resources: planResources
|
|
5077
|
+
};
|
|
5078
|
+
return {
|
|
5079
|
+
...defaultPlan,
|
|
5080
|
+
usageTotal: String(totalUsageTotal),
|
|
5081
|
+
usageUsed: String(totalUsageUsed),
|
|
5082
|
+
usageLeft: String(totalUsageLeft),
|
|
5083
|
+
resources: planResources
|
|
5084
|
+
};
|
|
4120
5085
|
} catch (error) {
|
|
4121
5086
|
console.error("[BackendProvider] getCurrentPlan error:", error);
|
|
4122
5087
|
return defaultPlan;
|
|
4123
5088
|
}
|
|
4124
5089
|
}
|
|
4125
5090
|
/**
|
|
5091
|
+
* 通过回调code,换token
|
|
5092
|
+
* @param request
|
|
5093
|
+
* @returns
|
|
5094
|
+
*/
|
|
5095
|
+
async saveOauthToken(request) {
|
|
5096
|
+
const url = `${this.baseUrl}/console/as/connector/oauth/${request.name}/connect`;
|
|
5097
|
+
const headers = {
|
|
5098
|
+
"Content-Type": "application/json",
|
|
5099
|
+
"Accept": "application/json"
|
|
5100
|
+
};
|
|
5101
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
5102
|
+
const body = { authorization_code: request.authorizationCode };
|
|
5103
|
+
try {
|
|
5104
|
+
const result = await (await fetch(url, {
|
|
5105
|
+
method: "POST",
|
|
5106
|
+
headers,
|
|
5107
|
+
credentials: "include",
|
|
5108
|
+
body: JSON.stringify(body)
|
|
5109
|
+
})).json();
|
|
5110
|
+
if (result.code === 0) return;
|
|
5111
|
+
throw result;
|
|
5112
|
+
} catch (error) {
|
|
5113
|
+
throw error;
|
|
5114
|
+
}
|
|
5115
|
+
}
|
|
5116
|
+
/**
|
|
5117
|
+
* 获取OAuth连接器的仓库列表
|
|
5118
|
+
*/
|
|
5119
|
+
async getRepoList(request) {
|
|
5120
|
+
const url = `${this.baseUrl}/console/as/connector/oauth/${request.name}/repos`;
|
|
5121
|
+
const headers = {
|
|
5122
|
+
"Content-Type": "application/json",
|
|
5123
|
+
"Accept": "application/json"
|
|
5124
|
+
};
|
|
5125
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
5126
|
+
try {
|
|
5127
|
+
const result = await (await fetch(url, {
|
|
5128
|
+
method: "GET",
|
|
5129
|
+
headers,
|
|
5130
|
+
credentials: "include"
|
|
5131
|
+
})).json();
|
|
5132
|
+
if (result.code === 0) return result.data;
|
|
5133
|
+
throw result;
|
|
5134
|
+
} catch (error) {
|
|
5135
|
+
throw error;
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
/**
|
|
5139
|
+
* 撤销OAuth连接器的所有连接
|
|
5140
|
+
*/
|
|
5141
|
+
async revokeAll(request) {
|
|
5142
|
+
const url = `${this.baseUrl}/console/as/connector/oauth/${request.name}/revokeall`;
|
|
5143
|
+
const installationIds = request?.installationIds ?? [];
|
|
5144
|
+
const headers = {
|
|
5145
|
+
"Content-Type": "application/json",
|
|
5146
|
+
"Accept": "application/json"
|
|
5147
|
+
};
|
|
5148
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
5149
|
+
const body = { name: request.name };
|
|
5150
|
+
if (installationIds) body.installation_ids = installationIds;
|
|
5151
|
+
try {
|
|
5152
|
+
const result = await (await fetch(url, {
|
|
5153
|
+
method: "POST",
|
|
5154
|
+
headers,
|
|
5155
|
+
credentials: "include",
|
|
5156
|
+
body: JSON.stringify(body)
|
|
5157
|
+
})).json();
|
|
5158
|
+
if (result.code === 0) return;
|
|
5159
|
+
throw result;
|
|
5160
|
+
} catch (error) {
|
|
5161
|
+
throw error;
|
|
5162
|
+
}
|
|
5163
|
+
}
|
|
5164
|
+
/**
|
|
5165
|
+
* 获取 OAuth 用户信息
|
|
5166
|
+
* API 端点: GET /console/as/connector/oauth/:name/oauthuser
|
|
5167
|
+
*/
|
|
5168
|
+
async getOauthUser(request) {
|
|
5169
|
+
const url = `${this.baseUrl}/console/as/connector/oauth/${request.name}/oauthuser`;
|
|
5170
|
+
const headers = {
|
|
5171
|
+
"Content-Type": "application/json",
|
|
5172
|
+
"Accept": "application/json"
|
|
5173
|
+
};
|
|
5174
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
5175
|
+
try {
|
|
5176
|
+
const result = await (await fetch(url, {
|
|
5177
|
+
method: "GET",
|
|
5178
|
+
headers,
|
|
5179
|
+
credentials: "include"
|
|
5180
|
+
})).json();
|
|
5181
|
+
if (result.code === 0) {
|
|
5182
|
+
const data = result.data || {};
|
|
5183
|
+
return { user: {
|
|
5184
|
+
avatarUrl: data.user?.avatar_url || "",
|
|
5185
|
+
name: data.user?.name || ""
|
|
5186
|
+
} };
|
|
5187
|
+
}
|
|
5188
|
+
throw result;
|
|
5189
|
+
} catch (error) {
|
|
5190
|
+
throw error;
|
|
5191
|
+
}
|
|
5192
|
+
}
|
|
5193
|
+
/**
|
|
4126
5194
|
* 根据账号类型和 Pro 状态计算版本展示类型
|
|
4127
5195
|
* - personal + isPro = 'pro'
|
|
4128
5196
|
* - personal + !isPro = 'free'
|
|
@@ -4145,14 +5213,28 @@ var BackendProvider = class {
|
|
|
4145
5213
|
}
|
|
4146
5214
|
/**
|
|
4147
5215
|
* 登出账号
|
|
4148
|
-
* Web 环境:
|
|
5216
|
+
* Web 环境: 通过 iframe 访问登出 URL 清除 cookie
|
|
4149
5217
|
*/
|
|
4150
5218
|
async logout() {
|
|
4151
5219
|
const url = `${this.baseUrl}/console/logout`;
|
|
4152
5220
|
try {
|
|
4153
|
-
await
|
|
4154
|
-
|
|
4155
|
-
|
|
5221
|
+
await new Promise((resolve) => {
|
|
5222
|
+
const iframe = document.createElement("iframe");
|
|
5223
|
+
iframe.style.cssText = "position:fixed;top:-9999px;left:-9999px;width:1px;height:1px;border:none;";
|
|
5224
|
+
iframe.src = url;
|
|
5225
|
+
const timeout = setTimeout(() => {
|
|
5226
|
+
cleanup();
|
|
5227
|
+
resolve();
|
|
5228
|
+
}, 5e3);
|
|
5229
|
+
const cleanup = () => {
|
|
5230
|
+
clearTimeout(timeout);
|
|
5231
|
+
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
|
|
5232
|
+
};
|
|
5233
|
+
iframe.onerror = () => {
|
|
5234
|
+
cleanup();
|
|
5235
|
+
resolve();
|
|
5236
|
+
};
|
|
5237
|
+
document.body.appendChild(iframe);
|
|
4156
5238
|
});
|
|
4157
5239
|
} catch (error) {
|
|
4158
5240
|
console.error("[BackendProvider] logout failed:", error);
|
|
@@ -4160,6 +5242,54 @@ var BackendProvider = class {
|
|
|
4160
5242
|
localStorage.removeItem(SELECTED_ACCOUNT_KEY);
|
|
4161
5243
|
accountService.clearAccount();
|
|
4162
5244
|
}
|
|
5245
|
+
/**
|
|
5246
|
+
* 批量切换插件状态
|
|
5247
|
+
* Web 环境不支持此功能
|
|
5248
|
+
*/
|
|
5249
|
+
async batchTogglePlugins(request) {
|
|
5250
|
+
console.warn("[BackendProvider] batchTogglePlugins is not supported in web environment");
|
|
5251
|
+
return {
|
|
5252
|
+
success: false,
|
|
5253
|
+
succeededPlugins: [],
|
|
5254
|
+
failedPlugins: request.items.map((item) => ({
|
|
5255
|
+
...item,
|
|
5256
|
+
error: "Plugin batch toggle is not supported in web environment"
|
|
5257
|
+
}))
|
|
5258
|
+
};
|
|
5259
|
+
}
|
|
5260
|
+
/**
|
|
5261
|
+
* 获取企业用户用量信息
|
|
5262
|
+
* API: POST /billing/meter/get-enterprise-user-usage
|
|
5263
|
+
* 构建查询参数字符串
|
|
5264
|
+
*/
|
|
5265
|
+
async getEnterpriseUsage(enterpriseId) {
|
|
5266
|
+
try {
|
|
5267
|
+
const url = `${this.baseUrl}/billing/meter/get-enterprise-user-usage`;
|
|
5268
|
+
const headers = {
|
|
5269
|
+
"Content-Type": "application/json",
|
|
5270
|
+
"Accept": "application/json",
|
|
5271
|
+
"X-Enterprise-Id": enterpriseId
|
|
5272
|
+
};
|
|
5273
|
+
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
5274
|
+
const response = await fetch(url, {
|
|
5275
|
+
method: "POST",
|
|
5276
|
+
headers,
|
|
5277
|
+
credentials: "include",
|
|
5278
|
+
body: JSON.stringify({})
|
|
5279
|
+
});
|
|
5280
|
+
if (!response.ok) {
|
|
5281
|
+
console.warn("[BackendProvider] getEnterpriseUsage failed:", response.status);
|
|
5282
|
+
return null;
|
|
5283
|
+
}
|
|
5284
|
+
const result = await response.json();
|
|
5285
|
+
const usageData = result?.data?.data || result?.data || result;
|
|
5286
|
+
if (usageData && typeof usageData.limitNum === "number") return usageData;
|
|
5287
|
+
return null;
|
|
5288
|
+
} catch (error) {
|
|
5289
|
+
console.error("[BackendProvider] getEnterpriseUsage error:", error);
|
|
5290
|
+
return null;
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
4163
5293
|
};
|
|
4164
5294
|
/**
|
|
4165
5295
|
* 创建 BackendProvider 实例
|
|
@@ -4174,11 +5304,24 @@ function createBackendProvider(config) {
|
|
|
4174
5304
|
* Backend 请求类型常量
|
|
4175
5305
|
*/
|
|
4176
5306
|
const BACKEND_REQUEST_TYPES = {
|
|
4177
|
-
GET_AGENTS: "backend:get-agents-request",
|
|
4178
|
-
GET_MODELS: "backend:get-models",
|
|
4179
5307
|
LOGIN: "backend:login",
|
|
4180
5308
|
LOGOUT: "backend:logout",
|
|
4181
|
-
GET_ACCOUNT: "backend:get-account"
|
|
5309
|
+
GET_ACCOUNT: "backend:get-account",
|
|
5310
|
+
GET_USER_CONNECTOR: "backend:get-user-connector",
|
|
5311
|
+
MODIFY_USER_CONNECTOR_CONNECT_STATUS: "backend:modify-user-connector-connect-status",
|
|
5312
|
+
MODIFY_USER_CONNECTOR_REPO: "backend:modify-user-connector-repo",
|
|
5313
|
+
MODIFY_USER_CONNECTOR_ACTIVE_STATUS: "backend:modify-user-connector-active-status",
|
|
5314
|
+
DELETE_USER_CONNECTOR: "backend:delete-user-connector",
|
|
5315
|
+
ADD_CONNECTOR_TASK: "backend:add-connector-task",
|
|
5316
|
+
GET_TASK_CONNECTOR: "backend:get-task-connector",
|
|
5317
|
+
MODIFY_TASK_CONNECTOR_ACTIVE_STATUS: "backend:modify-task-connector-active-status",
|
|
5318
|
+
MODIFY_TASK_CONNECTOR_REPO: "backend:modify-task-connector-repo",
|
|
5319
|
+
GET_OAUTH_USER: "backend:get-oauth-user",
|
|
5320
|
+
SAVE_OAUTH_TOKEN: "backend:save-oauth-token",
|
|
5321
|
+
GET_REPO_LIST: "backend:get-repo-list",
|
|
5322
|
+
REVOKE_ALL: "backend:revoke-all",
|
|
5323
|
+
RELOAD_WINDOW: "backend:reload-window",
|
|
5324
|
+
BATCH_TOGGLE_PLUGINS: "backend:batch-toggle-plugins"
|
|
4182
5325
|
};
|
|
4183
5326
|
/**
|
|
4184
5327
|
* 生成唯一请求 ID
|
|
@@ -4189,7 +5332,7 @@ function generateRequestId() {
|
|
|
4189
5332
|
/**
|
|
4190
5333
|
* IPC Backend Provider 实现类
|
|
4191
5334
|
*
|
|
4192
|
-
* 通过 IWidgetChannel
|
|
5335
|
+
* 通过 IWidgetChannel 与后端通信
|
|
4193
5336
|
*/
|
|
4194
5337
|
var IPCBackendProvider = class {
|
|
4195
5338
|
constructor(config) {
|
|
@@ -4220,45 +5363,188 @@ var IPCBackendProvider = class {
|
|
|
4220
5363
|
return response?.data !== void 0 ? response.data : response;
|
|
4221
5364
|
}
|
|
4222
5365
|
/**
|
|
4223
|
-
*
|
|
4224
|
-
* 通过
|
|
5366
|
+
* 获取当前账号信息
|
|
5367
|
+
* IDE 环境: 通过 IPC 获取账号信息,并同步到 accountService
|
|
5368
|
+
*/
|
|
5369
|
+
async getAccount() {
|
|
5370
|
+
this.log("Getting account via IPC");
|
|
5371
|
+
try {
|
|
5372
|
+
const account = await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_ACCOUNT);
|
|
5373
|
+
accountService.setAccount(account);
|
|
5374
|
+
return account;
|
|
5375
|
+
} catch (error) {
|
|
5376
|
+
this.log("Get account failed:", error);
|
|
5377
|
+
accountService.setAccount(null);
|
|
5378
|
+
return null;
|
|
5379
|
+
}
|
|
5380
|
+
}
|
|
5381
|
+
/**
|
|
5382
|
+
* 获取用户连接器列表
|
|
5383
|
+
* IDE 环境: 通过 IPC 获取用户连接器列表
|
|
4225
5384
|
*/
|
|
4226
|
-
async
|
|
4227
|
-
this.log("Getting
|
|
5385
|
+
async getUserConnector() {
|
|
5386
|
+
this.log("Getting user connector via IPC");
|
|
4228
5387
|
try {
|
|
4229
|
-
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.
|
|
5388
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_USER_CONNECTOR);
|
|
4230
5389
|
} catch (error) {
|
|
4231
|
-
this.log("Get
|
|
5390
|
+
this.log("Get user connector failed:", error);
|
|
4232
5391
|
throw error;
|
|
4233
5392
|
}
|
|
4234
5393
|
}
|
|
4235
5394
|
/**
|
|
4236
|
-
*
|
|
4237
|
-
* 通过
|
|
5395
|
+
* 修改用户连接器连接状态
|
|
5396
|
+
* IDE 环境: 通过 IPC 修改用户连接器连接状态
|
|
4238
5397
|
*/
|
|
4239
|
-
async
|
|
4240
|
-
this.log("
|
|
5398
|
+
async modifyUserConnectorConnectStatus(request) {
|
|
5399
|
+
this.log("Modifying user connector connect status via IPC:", request);
|
|
4241
5400
|
try {
|
|
4242
|
-
|
|
5401
|
+
await this.sendBackendRequest(BACKEND_REQUEST_TYPES.MODIFY_USER_CONNECTOR_CONNECT_STATUS, request);
|
|
4243
5402
|
} catch (error) {
|
|
4244
|
-
this.log("
|
|
5403
|
+
this.log("Modify user connector connect status failed:", error);
|
|
4245
5404
|
throw error;
|
|
4246
5405
|
}
|
|
4247
5406
|
}
|
|
4248
5407
|
/**
|
|
4249
|
-
*
|
|
4250
|
-
* IDE 环境: 通过 IPC
|
|
5408
|
+
* 修改用户连接器仓库
|
|
5409
|
+
* IDE 环境: 通过 IPC 修改用户连接器仓库
|
|
4251
5410
|
*/
|
|
4252
|
-
async
|
|
4253
|
-
this.log("
|
|
5411
|
+
async modifyUserConnectorRepo(request) {
|
|
5412
|
+
this.log("Modifying user connector repo via IPC:", request);
|
|
4254
5413
|
try {
|
|
4255
|
-
|
|
4256
|
-
accountService.setAccount(account);
|
|
4257
|
-
return account;
|
|
5414
|
+
await this.sendBackendRequest(BACKEND_REQUEST_TYPES.MODIFY_USER_CONNECTOR_REPO, request);
|
|
4258
5415
|
} catch (error) {
|
|
4259
|
-
this.log("
|
|
4260
|
-
|
|
4261
|
-
|
|
5416
|
+
this.log("Modify user connector repo failed:", error);
|
|
5417
|
+
throw error;
|
|
5418
|
+
}
|
|
5419
|
+
}
|
|
5420
|
+
/**
|
|
5421
|
+
* 修改用户连接器激活状态
|
|
5422
|
+
* IDE 环境: 通过 IPC 修改用户连接器激活状态
|
|
5423
|
+
*/
|
|
5424
|
+
async modifyUserConnectorActiveStatus(request) {
|
|
5425
|
+
this.log("Modifying user connector active status via IPC:", request);
|
|
5426
|
+
try {
|
|
5427
|
+
await this.sendBackendRequest(BACKEND_REQUEST_TYPES.MODIFY_USER_CONNECTOR_ACTIVE_STATUS, request);
|
|
5428
|
+
} catch (error) {
|
|
5429
|
+
this.log("Modify user connector active status failed:", error);
|
|
5430
|
+
throw error;
|
|
5431
|
+
}
|
|
5432
|
+
}
|
|
5433
|
+
/**
|
|
5434
|
+
* 删除用户连接器
|
|
5435
|
+
* IDE 环境: 通过 IPC 删除用户连接器
|
|
5436
|
+
*/
|
|
5437
|
+
async deleteUserConnector(name) {
|
|
5438
|
+
this.log("Deleting user connector via IPC:", name);
|
|
5439
|
+
try {
|
|
5440
|
+
await this.sendBackendRequest(BACKEND_REQUEST_TYPES.DELETE_USER_CONNECTOR, { name });
|
|
5441
|
+
} catch (error) {
|
|
5442
|
+
this.log("Delete user connector failed:", error);
|
|
5443
|
+
throw error;
|
|
5444
|
+
}
|
|
5445
|
+
}
|
|
5446
|
+
/**
|
|
5447
|
+
* 添加任务
|
|
5448
|
+
* IDE 环境: 通过 IPC 添加任务
|
|
5449
|
+
*/
|
|
5450
|
+
async addConnectorTask(request) {
|
|
5451
|
+
this.log("Adding connector task via IPC:", request);
|
|
5452
|
+
try {
|
|
5453
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.ADD_CONNECTOR_TASK, request);
|
|
5454
|
+
} catch (error) {
|
|
5455
|
+
this.log("Add task failed:", error);
|
|
5456
|
+
throw error;
|
|
5457
|
+
}
|
|
5458
|
+
}
|
|
5459
|
+
/**
|
|
5460
|
+
* 获取任务连接器列表
|
|
5461
|
+
* IDE 环境: 通过 IPC 获取任务连接器列表
|
|
5462
|
+
*/
|
|
5463
|
+
async getTaskConnector(taskId) {
|
|
5464
|
+
this.log("Getting task connector via IPC:", taskId);
|
|
5465
|
+
try {
|
|
5466
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_TASK_CONNECTOR, { taskId });
|
|
5467
|
+
} catch (error) {
|
|
5468
|
+
this.log("Get task connector failed:", error);
|
|
5469
|
+
throw error;
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
/**
|
|
5473
|
+
* 修改任务连接器激活状态
|
|
5474
|
+
* IDE 环境: 通过 IPC 修改任务连接器激活状态
|
|
5475
|
+
*/
|
|
5476
|
+
async modifyTaskConnectorActiveStatus(request) {
|
|
5477
|
+
this.log("Modifying task connector active status via IPC:", request);
|
|
5478
|
+
try {
|
|
5479
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.MODIFY_TASK_CONNECTOR_ACTIVE_STATUS, request);
|
|
5480
|
+
} catch (error) {
|
|
5481
|
+
this.log("Modify task connector active status failed:", error);
|
|
5482
|
+
throw error;
|
|
5483
|
+
}
|
|
5484
|
+
}
|
|
5485
|
+
/**
|
|
5486
|
+
* 修改任务连接器仓库
|
|
5487
|
+
* IDE 环境: 通过 IPC 修改任务连接器仓库
|
|
5488
|
+
*/
|
|
5489
|
+
async modifyTaskConnectorRepo(request) {
|
|
5490
|
+
this.log("Modifying task connector repo via IPC:", request);
|
|
5491
|
+
try {
|
|
5492
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.MODIFY_TASK_CONNECTOR_REPO, request);
|
|
5493
|
+
} catch (error) {
|
|
5494
|
+
this.log("Modify task connector repo failed:", error);
|
|
5495
|
+
throw error;
|
|
5496
|
+
}
|
|
5497
|
+
}
|
|
5498
|
+
/**
|
|
5499
|
+
* 获取 OAuth 用户信息
|
|
5500
|
+
* IDE 环境: 通过 IPC 获取 OAuth 用户信息
|
|
5501
|
+
*/
|
|
5502
|
+
async getOauthUser(request) {
|
|
5503
|
+
this.log("Getting OAuth user via IPC:", request);
|
|
5504
|
+
try {
|
|
5505
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_OAUTH_USER, request);
|
|
5506
|
+
} catch (error) {
|
|
5507
|
+
this.log("Get OAuth user failed:", error);
|
|
5508
|
+
throw error;
|
|
5509
|
+
}
|
|
5510
|
+
}
|
|
5511
|
+
/**
|
|
5512
|
+
* 通过回调code,换token
|
|
5513
|
+
* IDE 环境: 通过 IPC 保存 OAuth Token
|
|
5514
|
+
*/
|
|
5515
|
+
async saveOauthToken(request) {
|
|
5516
|
+
this.log("Saving OAuth token via IPC:", request);
|
|
5517
|
+
try {
|
|
5518
|
+
await this.sendBackendRequest(BACKEND_REQUEST_TYPES.SAVE_OAUTH_TOKEN, request);
|
|
5519
|
+
} catch (error) {
|
|
5520
|
+
this.log("Save OAuth token failed:", error);
|
|
5521
|
+
throw error;
|
|
5522
|
+
}
|
|
5523
|
+
}
|
|
5524
|
+
/**
|
|
5525
|
+
* 获取OAuth连接器的仓库列表
|
|
5526
|
+
* IDE 环境: 通过 IPC 获取仓库列表
|
|
5527
|
+
*/
|
|
5528
|
+
async getRepoList(request) {
|
|
5529
|
+
this.log("Getting repo list via IPC:", request);
|
|
5530
|
+
try {
|
|
5531
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_REPO_LIST, request);
|
|
5532
|
+
} catch (error) {
|
|
5533
|
+
this.log("Get repo list failed:", error);
|
|
5534
|
+
throw error;
|
|
5535
|
+
}
|
|
5536
|
+
}
|
|
5537
|
+
/**
|
|
5538
|
+
* 撤销OAuth连接器的所有连接
|
|
5539
|
+
* IDE 环境: 通过 IPC 撤销所有连接
|
|
5540
|
+
*/
|
|
5541
|
+
async revokeAll(request) {
|
|
5542
|
+
this.log("Revoking all connections via IPC:", request);
|
|
5543
|
+
try {
|
|
5544
|
+
await this.sendBackendRequest(BACKEND_REQUEST_TYPES.REVOKE_ALL, request);
|
|
5545
|
+
} catch (error) {
|
|
5546
|
+
this.log("Revoke all connections failed:", error);
|
|
5547
|
+
throw error;
|
|
4262
5548
|
}
|
|
4263
5549
|
}
|
|
4264
5550
|
/**
|
|
@@ -4289,6 +5575,33 @@ var IPCBackendProvider = class {
|
|
|
4289
5575
|
}
|
|
4290
5576
|
}
|
|
4291
5577
|
/**
|
|
5578
|
+
* 重新加载窗口
|
|
5579
|
+
* IDE 环境: 通过 IPC 通知 IDE 重新加载窗口(用于应用语言设置等)
|
|
5580
|
+
* @param params 可选参数,如 locale
|
|
5581
|
+
*/
|
|
5582
|
+
async reloadWindow(params) {
|
|
5583
|
+
this.log("Triggering reload window via IPC", params);
|
|
5584
|
+
try {
|
|
5585
|
+
await this.sendBackendRequest(BACKEND_REQUEST_TYPES.RELOAD_WINDOW, params);
|
|
5586
|
+
} catch (error) {
|
|
5587
|
+
this.log("Reload window request failed:", error);
|
|
5588
|
+
throw error;
|
|
5589
|
+
}
|
|
5590
|
+
}
|
|
5591
|
+
/**
|
|
5592
|
+
* 批量切换插件状态
|
|
5593
|
+
* IDE 环境: 通过 IPC 调用 Extension Host 的 PluginService
|
|
5594
|
+
*/
|
|
5595
|
+
async batchTogglePlugins(request) {
|
|
5596
|
+
this.log("Batch toggling plugins via IPC:", request);
|
|
5597
|
+
try {
|
|
5598
|
+
return await this.sendBackendRequest(BACKEND_REQUEST_TYPES.BATCH_TOGGLE_PLUGINS, request);
|
|
5599
|
+
} catch (error) {
|
|
5600
|
+
this.log("Batch toggle plugins failed:", error);
|
|
5601
|
+
throw error;
|
|
5602
|
+
}
|
|
5603
|
+
}
|
|
5604
|
+
/**
|
|
4292
5605
|
* 调试日志
|
|
4293
5606
|
*/
|
|
4294
5607
|
log(...args) {
|