@tencent-ai/cloud-agent-sdk 0.2.11 → 0.2.12-next.21a87f3.20260203

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.mjs CHANGED
@@ -1954,9 +1954,7 @@ var StreamableHttpClient = class {
1954
1954
  });
1955
1955
  await this.handleExtNotification(method, params);
1956
1956
  },
1957
- extMethod: async (method, params) => {
1958
- return await this.handleExtMethod(method, params);
1959
- }
1957
+ extMethod: async (method, params) => this.handleExtMethod(method, params)
1960
1958
  };
1961
1959
  }
1962
1960
  /**
@@ -2176,12 +2174,22 @@ var StreamableHttpClient = class {
2176
2174
  await this.extensionManager.handleNotification(method, params);
2177
2175
  }
2178
2176
  async handleExtMethod(method, params) {
2179
- if (method === ExtensionMethod.QUESTION) return this.questionManager.handleRequest(params);
2177
+ if (method === ExtensionMethod.QUESTION) {
2178
+ const response = await this.questionManager.handleRequest(params);
2179
+ if (response.outcome === "submitted" && response.answers) return { outcome: {
2180
+ outcome: "submitted",
2181
+ data: { answers: response.answers }
2182
+ } };
2183
+ else return { outcome: {
2184
+ outcome: "cancelled",
2185
+ reason: response.reason
2186
+ } };
2187
+ }
2180
2188
  this.options.logger?.warn(`Unknown extension method: ${method}`);
2181
- return {
2189
+ return { outcome: {
2182
2190
  outcome: "cancelled",
2183
2191
  reason: "unknown method"
2184
- };
2192
+ } };
2185
2193
  }
2186
2194
  ensureInitialized(operation) {
2187
2195
  if (this.state !== "initialized") throw new InvalidStateError(operation, this.state, ["initialized"]);
@@ -2364,7 +2372,7 @@ var CloudAgentConnection = class {
2364
2372
  }
2365
2373
  async createSession(params) {
2366
2374
  return {
2367
- ...await this.client.loadSession(this.agentId, this.cwd),
2375
+ ...await this.client.createSession(this.cwd),
2368
2376
  sessionId: this.agentId
2369
2377
  };
2370
2378
  }
@@ -5655,6 +5663,11 @@ var AccountService = class {
5655
5663
  * 导出单例实例
5656
5664
  */
5657
5665
  const accountService = new AccountService();
5666
+ /**
5667
+ * 暴露给全局,供 Agent Manager 直接调用 setAccount 刷新 Widget 状态
5668
+ * 这是为了解决 IDE 环境中 IPC 事件无法直接触发 Widget 账号刷新的问题
5669
+ */
5670
+ if (typeof window !== "undefined") window.__genieAccountService = accountService;
5658
5671
 
5659
5672
  //#endregion
5660
5673
  //#region ../agent-provider/src/common/utils/concurrency.ts
@@ -6262,13 +6275,19 @@ var CloudAgentProvider = class CloudAgentProvider {
6262
6275
  /**
6263
6276
  * Create a new conversation
6264
6277
  * POST {endpoint}/console/as/conversations
6278
+ * @param params - Optional session params containing _meta with tags
6265
6279
  */
6266
- async create() {
6280
+ async create(params) {
6267
6281
  try {
6268
- const apiResponse = await httpService.post("/console/as/conversations/", {
6282
+ const tagsObj = (params?._meta?.["codebuddy.ai"])?.tags;
6283
+ const tagsArray = tagsObj ? Object.entries(tagsObj).map(([key, value]) => `${key}:${value}`) : void 0;
6284
+ const createPayload = {
6269
6285
  prompt: "",
6270
- model: "deepseek-r1"
6271
- });
6286
+ model: "deepseek-r1",
6287
+ ...tagsArray && tagsArray.length > 0 ? { tags: tagsArray } : {}
6288
+ };
6289
+ console.log("[CloudAgentProvider] Creating conversation with payload:", createPayload);
6290
+ const apiResponse = await httpService.post("/console/as/conversations/", createPayload);
6272
6291
  if (!apiResponse.data) throw new Error("No data in API response");
6273
6292
  this.logger?.info(`Created conversation: ${apiResponse.data.id}`);
6274
6293
  return apiResponse.data.id;
@@ -6629,6 +6648,28 @@ var CloudAgentProvider = class CloudAgentProvider {
6629
6648
  }
6630
6649
  }
6631
6650
  }
6651
+ /**
6652
+ * 获取支持的场景列表
6653
+ * API 端点: GET /console/as/support/scenes
6654
+ * 用于 Welcome 页面的 QuickActions 快捷操作
6655
+ *
6656
+ * @returns Promise<SupportScene[]> 支持的场景列表
6657
+ */
6658
+ async getSupportScenes() {
6659
+ try {
6660
+ const apiResponse = await httpService.get("/console/as/support/scenes");
6661
+ if (!apiResponse.data) {
6662
+ this.logger?.warn("[CloudAgentProvider] No data in support scenes response");
6663
+ return [];
6664
+ }
6665
+ const scenes = apiResponse.data.scenes || [];
6666
+ this.logger?.info(`[CloudAgentProvider] Retrieved ${scenes.length} support scenes`);
6667
+ return scenes;
6668
+ } catch (error) {
6669
+ this.logger?.error("[CloudAgentProvider] Failed to get support scenes:", error);
6670
+ return [];
6671
+ }
6672
+ }
6632
6673
  toAgentState(data) {
6633
6674
  const status = data.sessionStatus || data.status;
6634
6675
  return {
@@ -6933,8 +6974,8 @@ var ActiveSessionImpl = class {
6933
6974
  * await session.setMode('architect');
6934
6975
  * ```
6935
6976
  */
6936
- async setMode(modeId) {
6937
- if (this._availableModes) {
6977
+ async setMode(modeId, skipAvailableChecker) {
6978
+ if (this._availableModes && !skipAvailableChecker) {
6938
6979
  if (!this._availableModes.some((m) => m.id === modeId)) {
6939
6980
  const availableIds = this._availableModes.map((m) => m.id).join(", ");
6940
6981
  throw new Error(`Invalid modeId: "${modeId}". Available modes: ${availableIds}`);
@@ -7125,14 +7166,6 @@ var ActiveSessionImpl = class {
7125
7166
  //#endregion
7126
7167
  //#region ../agent-provider/src/common/client/session-manager.ts
7127
7168
  /**
7128
- * SessionManager - Manages session lifecycle and connections
7129
- *
7130
- * Provides the core implementation for session-centric API operations:
7131
- * - list() - Lists sessions (mapped from agents)
7132
- * - createSession() - Creates new session (auto-creates agent)
7133
- * - loadSession() - Loads existing session (finds agent by sessionId)
7134
- */
7135
- /**
7136
7169
  * SessionManager - Session lifecycle management
7137
7170
  *
7138
7171
  * This class manages the relationship between sessions and agents.
@@ -7228,14 +7261,8 @@ var SessionManager = class {
7228
7261
  connectionInfo
7229
7262
  });
7230
7263
  session.setModes(response.modes?.availableModes, response.modes?.currentModeId);
7231
- if (response.models?.availableModels) {
7232
- const localModels = response.models.availableModels.map((m) => ({
7233
- id: m.modelId,
7234
- name: m.name,
7235
- description: m.description ?? void 0
7236
- }));
7237
- session.setModels(localModels, response.models?.currentModelId);
7238
- }
7264
+ const availableModels = this.extractAvailableModels(response);
7265
+ if (availableModels) session.setModels(availableModels, response.models?.currentModelId);
7239
7266
  this.logger?.info(`Session created: ${response.sessionId}`);
7240
7267
  return session;
7241
7268
  }
@@ -7271,17 +7298,31 @@ var SessionManager = class {
7271
7298
  mcpServers: params.mcpServers
7272
7299
  });
7273
7300
  session.setModes(response.modes?.availableModes, response.modes?.currentModeId);
7274
- if (response.models?.availableModels) {
7275
- const localModels = response.models.availableModels.map((m) => ({
7276
- id: m.modelId,
7277
- name: m.name,
7278
- description: m.description ?? void 0
7279
- }));
7280
- session.setModels(localModels, response.models?.currentModelId);
7281
- }
7301
+ const availableModels = this.extractAvailableModels(response);
7302
+ if (availableModels) session.setModels(availableModels, response.models?.currentModelId);
7282
7303
  this.logger?.info(`Session loaded: ${params.sessionId}`);
7283
7304
  return session;
7284
7305
  }
7306
+ /**
7307
+ * 从 ACP response 中提取可用模型列表
7308
+ *
7309
+ * 优先级:
7310
+ * 1. response.models._meta?.['codebuddy.ai']?.availableModels - 包含完整的模型信息(字段名为 'id')
7311
+ * 2. response.models?.availableModels - 只包含基本信息(字段名为 'modelId')
7312
+ * 3. undefined - 都没有时返回 undefined
7313
+ *
7314
+ * @param response - ACP 响应对象
7315
+ * @returns ModelInfo[] | undefined
7316
+ */
7317
+ extractAvailableModels(response) {
7318
+ const metaModels = (response.models?._meta?.["codebuddy.ai"])?.availableModels;
7319
+ if (metaModels && Array.isArray(metaModels) && metaModels.length > 0) return metaModels;
7320
+ const availableModels = response.models?.availableModels;
7321
+ if (availableModels && Array.isArray(availableModels) && availableModels.length > 0) return availableModels.map((model) => ({
7322
+ ...model,
7323
+ ...model._meta?.["codebuddy.ai"] || {}
7324
+ }));
7325
+ }
7285
7326
  };
7286
7327
 
7287
7328
  //#endregion
@@ -7554,6 +7595,28 @@ var AgentClient = class {
7554
7595
  };
7555
7596
  }
7556
7597
  },
7598
+ getSubagentList: async (params) => {
7599
+ try {
7600
+ if (this.provider && this.provider.getSubagentList) {
7601
+ const result = await this.provider.getSubagentList(params);
7602
+ this.logger?.info("Subagent list retrieved", {
7603
+ resultCount: result.results.length,
7604
+ hasError: !!result.error
7605
+ });
7606
+ return result;
7607
+ }
7608
+ return {
7609
+ results: [],
7610
+ error: "Provider does not support getSubagentList"
7611
+ };
7612
+ } catch (error) {
7613
+ this.logger?.error("Failed to get subagent list", error);
7614
+ return {
7615
+ results: [],
7616
+ error: error instanceof Error ? error.message : "Unknown error"
7617
+ };
7618
+ }
7619
+ },
7557
7620
  batchTogglePlugins: async (request) => {
7558
7621
  try {
7559
7622
  if (this.provider && this.provider.batchTogglePlugins) {
@@ -7598,10 +7661,10 @@ var AgentClient = class {
7598
7661
  return [];
7599
7662
  }
7600
7663
  },
7601
- installPlugins: async (pluginNames, marketplaceName, installScope) => {
7664
+ installPlugins: async (pluginNames, marketplaceName, installScope, marketplaceSource) => {
7602
7665
  try {
7603
7666
  if (this.provider && "installPlugins" in this.provider && typeof this.provider.installPlugins === "function") {
7604
- const result = await this.provider.installPlugins(pluginNames, marketplaceName, installScope);
7667
+ const result = await this.provider.installPlugins(pluginNames, marketplaceName, installScope, marketplaceSource);
7605
7668
  this.logger?.info("Install plugins", {
7606
7669
  pluginNames,
7607
7670
  marketplaceName,
@@ -7622,17 +7685,34 @@ var AgentClient = class {
7622
7685
  };
7623
7686
  }
7624
7687
  },
7625
- getSupportPlugins: async () => {
7688
+ getSupportScenes: async () => {
7626
7689
  try {
7627
- if (this.provider && "getSupportPlugins" in this.provider && typeof this.provider.getSupportPlugins === "function") {
7628
- const result = await this.provider.getSupportPlugins();
7629
- this.logger?.info("Got support plugins", { count: result?.length ?? 0 });
7690
+ if (this.provider && "getSupportScenes" in this.provider && typeof this.provider.getSupportScenes === "function") {
7691
+ const result = await this.provider.getSupportScenes();
7692
+ this.logger?.info("Got support scenes", { count: result?.length ?? 0 });
7630
7693
  return result;
7631
7694
  }
7632
- this.logger?.warn("Provider does not support getSupportPlugins");
7695
+ this.logger?.warn("Provider does not support getSupportScenes");
7633
7696
  return [];
7634
7697
  } catch (error) {
7635
- this.logger?.error("Failed to get support plugins", error);
7698
+ this.logger?.error("Failed to get support scenes", error);
7699
+ return [];
7700
+ }
7701
+ },
7702
+ getAvailableCommands: async (sessionId) => {
7703
+ try {
7704
+ if (this.provider && "getAvailableCommands" in this.provider && typeof this.provider.getAvailableCommands === "function") {
7705
+ const result = await this.provider.getAvailableCommands(sessionId);
7706
+ this.logger?.info("Got available commands from provider", {
7707
+ sessionId: sessionId ?? "(default)",
7708
+ count: result?.length ?? 0
7709
+ });
7710
+ return result;
7711
+ }
7712
+ this.logger?.warn("Provider does not support getAvailableCommands", { sessionId });
7713
+ return [];
7714
+ } catch (error) {
7715
+ this.logger?.error("Failed to get available commands", error);
7636
7716
  return [];
7637
7717
  }
7638
7718
  },
@@ -7702,6 +7782,154 @@ let AccountStatus = /* @__PURE__ */ function(AccountStatus) {
7702
7782
  return AccountStatus;
7703
7783
  }({});
7704
7784
 
7785
+ //#endregion
7786
+ //#region ../agent-provider/src/backend/service/oauth-repository-service.ts
7787
+ /**
7788
+ * OAuth Repository Service
7789
+ *
7790
+ * 封装 OAuth 连接器相关的仓库和分支操作
7791
+ */
7792
+ /**
7793
+ * OAuth Repository Service
7794
+ *
7795
+ * 提供仓库和分支的查询操作
7796
+ */
7797
+ var OAuthRepositoryService = class {
7798
+ /**
7799
+ * 获取仓库分支列表
7800
+ * API 端点: GET /console/as/connector/oauth/{name}/branches
7801
+ *
7802
+ * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')
7803
+ * @param params 平台特定的查询参数
7804
+ * @param page 页码,从1开始,0表示不分页获取全部
7805
+ * @param perPage 每页数量,最大100
7806
+ * @returns Promise<OauthBranch[]> 分支列表
7807
+ *
7808
+ * @example
7809
+ * ```typescript
7810
+ * // GitHub
7811
+ * const branches = await service.getBranches('github', {
7812
+ * owner: 'CodeBuddy-Official-Account',
7813
+ * repo: 'CodeBuddyIDE'
7814
+ * });
7815
+ *
7816
+ * // Gongfeng
7817
+ * const branches = await service.getBranches('gongfeng', {
7818
+ * project_id: '1611499'
7819
+ * });
7820
+ *
7821
+ * // CNB
7822
+ * const branches = await service.getBranches('cnb', {
7823
+ * repo: 'genie/genie-ide'
7824
+ * });
7825
+ * ```
7826
+ */
7827
+ async getBranches(connector, params, page = 0, perPage = 100) {
7828
+ try {
7829
+ const url = `/console/as/connector/oauth/${connector}/branches?${this.buildBranchQueryParams(connector, params, page, perPage).toString()}`;
7830
+ console.log(`[OAuthRepositoryService] GET ${url}`);
7831
+ const apiResponse = await httpService.get(url);
7832
+ if (!apiResponse.data) {
7833
+ console.warn(`[OAuthRepositoryService] No data in branches response for ${connector}`);
7834
+ return [];
7835
+ }
7836
+ const branches = apiResponse.data.branches || [];
7837
+ console.log(`[OAuthRepositoryService] Retrieved ${branches.length} branches from ${connector}`);
7838
+ return branches;
7839
+ } catch (error) {
7840
+ console.error(`[OAuthRepositoryService] Failed to get branches from ${connector}:`, error);
7841
+ throw error;
7842
+ }
7843
+ }
7844
+ /**
7845
+ * 获取仓库列表
7846
+ * API 端点: GET /console/as/connector/oauth/{name}/repos
7847
+ *
7848
+ * Note: 由于工蜂原生支持的 Search 能力会匹配 path/name/description 部分,
7849
+ * 且不支持定制,不满足产品要求(只按 name 匹配),因此前端拉取全量数据后做筛选。
7850
+ *
7851
+ * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')
7852
+ * @param page 页码,从1开始,0表示不分页获取全部
7853
+ * - GitHub 只支持全量数据,必须传 0
7854
+ * - 工蜂和 CNB 依据前端逻辑而定
7855
+ * @param perPage 每页数量,最大100
7856
+ * @returns Promise<ListReposResponse> 仓库列表响应
7857
+ *
7858
+ * @example
7859
+ * ```typescript
7860
+ * // GitHub - 必须传 page=0 获取全量数据
7861
+ * const response = await service.getRepositories('github', 0, 100);
7862
+ * // response.github_repos 是 map: installation_id => repo[]
7863
+ *
7864
+ * // Gongfeng
7865
+ * const response = await service.getRepositories('gongfeng', 0, 100);
7866
+ * // response.gongfeng_repos 是数组
7867
+ *
7868
+ * // CNB
7869
+ * const response = await service.getRepositories('cnb', 0, 100);
7870
+ * // response.cnb_repos 是数组
7871
+ * ```
7872
+ */
7873
+ async getRepositories(connector, page = 0, perPage = 100) {
7874
+ try {
7875
+ const queryParams = new URLSearchParams();
7876
+ queryParams.append("page", String(page));
7877
+ queryParams.append("per_page", String(Math.min(perPage, 100)));
7878
+ const url = `/console/as/connector/oauth/${connector}/repos?${queryParams.toString()}`;
7879
+ console.log(`[OAuthRepositoryService] GET ${url}`);
7880
+ const apiResponse = await httpService.get(url);
7881
+ if (!apiResponse.data) {
7882
+ console.warn(`[OAuthRepositoryService] No data in repos response for ${connector}`);
7883
+ return {};
7884
+ }
7885
+ const response = apiResponse.data;
7886
+ this.logRepositoryCounts(response);
7887
+ return response;
7888
+ } catch (error) {
7889
+ console.error(`[OAuthRepositoryService] Failed to get repos from ${connector}:`, error);
7890
+ throw error;
7891
+ }
7892
+ }
7893
+ /**
7894
+ * 构建分支查询参数
7895
+ */
7896
+ buildBranchQueryParams(connector, params, page, perPage) {
7897
+ const queryParams = new URLSearchParams();
7898
+ queryParams.append("page", String(page));
7899
+ queryParams.append("per_page", String(Math.min(perPage, 100)));
7900
+ if (connector === "github") {
7901
+ const githubParams = params;
7902
+ if (!githubParams.owner || !githubParams.repo) throw new Error("GitHub requires owner and repo parameters");
7903
+ queryParams.append("owner", githubParams.owner);
7904
+ queryParams.append("repo", githubParams.repo);
7905
+ } else if (connector === "gongfeng") {
7906
+ const gongfengParams = params;
7907
+ if (!gongfengParams.project_id) throw new Error("Gongfeng requires project_id parameter");
7908
+ queryParams.append("project_id", gongfengParams.project_id);
7909
+ } else if (connector === "cnb") {
7910
+ const cnbParams = params;
7911
+ if (!cnbParams.repo) throw new Error("CNB requires repo parameter");
7912
+ queryParams.append("repo", cnbParams.repo);
7913
+ } else throw new Error(`Unknown connector: ${connector}`);
7914
+ return queryParams;
7915
+ }
7916
+ /**
7917
+ * 记录仓库数量日志
7918
+ */
7919
+ logRepositoryCounts(response) {
7920
+ if (response.github_repos) {
7921
+ const totalCount = Object.values(response.github_repos).reduce((sum, repos) => sum + repos.length, 0);
7922
+ console.log(`[OAuthRepositoryService] Retrieved ${totalCount} GitHub repos across ${Object.keys(response.github_repos).length} installations`);
7923
+ }
7924
+ if (response.gongfeng_repos) console.log(`[OAuthRepositoryService] Retrieved ${response.gongfeng_repos.length} Gongfeng repos`);
7925
+ if (response.cnb_repos) console.log(`[OAuthRepositoryService] Retrieved ${response.cnb_repos.length} CNB repos`);
7926
+ }
7927
+ };
7928
+ /**
7929
+ * OAuth Repository Service 单例实例
7930
+ */
7931
+ const oauthRepositoryService = new OAuthRepositoryService();
7932
+
7705
7933
  //#endregion
7706
7934
  //#region ../agent-provider/src/backend/backend-provider.ts
7707
7935
  /**
@@ -7709,8 +7937,31 @@ let AccountStatus = /* @__PURE__ */ function(AccountStatus) {
7709
7937
  *
7710
7938
  * 封装与后端 API 的 HTTP 通信
7711
7939
  */
7712
- /** 获取当前域名的登录页面 URL */
7713
- const getLoginUrl = () => `${window.location.origin}/login`;
7940
+ /**
7941
+ * 判断当前账号是否是 SSO 账号
7942
+ * 通过 account.accountType === 'sso' 来判断,这种不行,因为未登录之前account 为空
7943
+ */
7944
+ const isSSODomain = () => {
7945
+ const { hostname } = window.location;
7946
+ return hostname.includes(".sso.copilot") || hostname.includes("sso.codebuddy.cn") || hostname.includes(".sso.copilot-staging") || hostname.includes(".staging-sso.codebuddy.cn");
7947
+ };
7948
+ /**
7949
+ * 根据路径获取完整 URL
7950
+ * - SSO 账号需要跳转到对应的预发/生产域名
7951
+ * - 非 SSO 账号直接使用当前域名
7952
+ * @param path 路径,如 '/login'、'/logout'、'/home' 等
7953
+ * @returns 完整的 URL 地址
7954
+ */
7955
+ const getFullUrl = (path) => {
7956
+ const { hostname, protocol } = window.location;
7957
+ if (isSSODomain()) {
7958
+ const isCodebuddy = hostname.includes("codebuddy.cn");
7959
+ const isStaging = hostname.includes("staging");
7960
+ if (isCodebuddy) return isStaging ? `${protocol}//staging.codebuddy.cn${path}` : `${protocol}//www.codebuddy.cn${path}`;
7961
+ else return isStaging ? `${protocol}//staging-copilot.tencent.com${path}` : `${protocol}//copilot.tencent.com${path}`;
7962
+ }
7963
+ return `${window.location.origin}${path}`;
7964
+ };
7714
7965
  /** 获取当前域名的账号选择页面 URL */
7715
7966
  const getSelectAccountUrl = () => `${window.location.origin}/login/select`;
7716
7967
  /** localStorage 中存储选中账号 ID 的 key */
@@ -7797,7 +8048,7 @@ var BackendProvider = class {
7797
8048
  return account;
7798
8049
  }
7799
8050
  const redirectUrl = encodeURIComponent(window.location.href);
7800
- window.location.href = `${getSelectAccountUrl()}?platform=website&state=0&redirect_uri=${redirectUrl}`;
8051
+ window.location.href = `${getSelectAccountUrl()}?platform=agents&state=0&redirect_uri=${redirectUrl}`;
7801
8052
  accountService.setAccount(null);
7802
8053
  return null;
7803
8054
  } catch (error) {
@@ -8159,7 +8410,7 @@ var BackendProvider = class {
8159
8410
  */
8160
8411
  async login() {
8161
8412
  const redirectUrl = encodeURIComponent(window.location.href);
8162
- window.location.href = `${getLoginUrl()}?platform=website&state=0&redirect_uri=${redirectUrl}`;
8413
+ window.location.href = `${getFullUrl("/login")}?platform=agents&state=0&redirect_uri=${redirectUrl}`;
8163
8414
  }
8164
8415
  /**
8165
8416
  * 登出账号
@@ -8223,20 +8474,51 @@ var BackendProvider = class {
8223
8474
  }
8224
8475
  }
8225
8476
  /**
8226
- * 获取支持的插件列表
8227
- * API 端点: GET /console/as/support/plugins
8228
- * 用于 Welcome 页面的 QuickActions 快捷操作
8477
+ * 刷新 Token
8478
+ * 通过调用 getAccount 刷新 cookie,适用于 Cloud 场景下页面切换回来时刷新登录态
8479
+ * @returns Promise<Account | null> 刷新后的账号信息
8229
8480
  */
8230
- async getSupportPlugins() {
8481
+ async refreshToken() {
8482
+ console.log("[BackendProvider] Refreshing token...");
8231
8483
  try {
8232
- const result = await httpService.get("/console/as/support/plugins");
8233
- if (result?.code === 0 && result?.data?.plugins) return result.data.plugins;
8234
- return [];
8484
+ const account = await this.getAccount();
8485
+ console.log("[BackendProvider] Token refreshed, account:", account?.uid);
8486
+ return account;
8235
8487
  } catch (error) {
8236
- console.error("[BackendProvider] getSupportPlugins error:", error);
8237
- return [];
8488
+ console.error("[BackendProvider] refreshToken failed:", error);
8489
+ return null;
8238
8490
  }
8239
8491
  }
8492
+ /**
8493
+ * 获取仓库分支列表
8494
+ * API 端点: GET /console/as/connector/oauth/{name}/branches
8495
+ *
8496
+ * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')
8497
+ * @param params 平台特定的查询参数
8498
+ * @param page 页码,从1开始,0表示不分页获取全部
8499
+ * @param perPage 每页数量,最大100
8500
+ * @returns Promise<OauthBranch[]> 分支列表
8501
+ */
8502
+ async getBranches(connector, params, page = 0, perPage = 100) {
8503
+ return oauthRepositoryService.getBranches(connector, params, page, perPage);
8504
+ }
8505
+ /**
8506
+ * 获取仓库列表
8507
+ * API 端点: GET /console/as/connector/oauth/{name}/repos
8508
+ *
8509
+ * Note: 由于工蜂原生支持的 Search 能力会匹配 path/name/description 部分,
8510
+ * 且不支持定制,不满足产品要求(只按 name 匹配),因此前端拉取全量数据后做筛选。
8511
+ *
8512
+ * @param connector 连接器名称 ('github' | 'gongfeng' | 'cnb')
8513
+ * @param page 页码,从1开始,0表示不分页获取全部
8514
+ * - GitHub 只支持全量数据,必须传 0
8515
+ * - 工蜂和 CNB 依据前端逻辑而定
8516
+ * @param perPage 每页数量,最大100
8517
+ * @returns Promise<ListReposResponse> 仓库列表响应
8518
+ */
8519
+ async getRepositories(connector, page = 0, perPage = 100) {
8520
+ return oauthRepositoryService.getRepositories(connector, page, perPage);
8521
+ }
8240
8522
  };
8241
8523
  /**
8242
8524
  * 创建 BackendProvider 实例
@@ -8248,6 +8530,12 @@ function createBackendProvider(config) {
8248
8530
  //#endregion
8249
8531
  //#region ../agent-provider/src/backend/ipc-backend-provider.ts
8250
8532
  /**
8533
+ * IPC Backend Provider 实现
8534
+ *
8535
+ * 通过 IWidgetChannel 与后端通信
8536
+ * 使用统一的消息格式: { type: 'backend', requestId, params: { type, params } }
8537
+ */
8538
+ /**
8251
8539
  * Backend 请求类型常量
8252
8540
  */
8253
8541
  const BACKEND_REQUEST_TYPES = {
@@ -8269,8 +8557,10 @@ const BACKEND_REQUEST_TYPES = {
8269
8557
  REVOKE_ALL: "backend:revoke-all",
8270
8558
  GET_FILE: "backend:get-file",
8271
8559
  RELOAD_WINDOW: "backend:reload-window",
8560
+ CLOSE_AGENT_MANAGER: "backend:close-agent-manager",
8561
+ OPEN_EXTERNAL: "backend:open-external",
8272
8562
  BATCH_TOGGLE_PLUGINS: "backend:batch-toggle-plugins",
8273
- GET_SUPPORT_PLUGINS: "backend:get-support-plugins"
8563
+ GET_SUPPORT_SCENES: "backend:get-support-scenes"
8274
8564
  };
8275
8565
  /**
8276
8566
  * 生成唯一请求 ID
@@ -8551,6 +8841,33 @@ var IPCBackendProvider = class {
8551
8841
  }
8552
8842
  }
8553
8843
  /**
8844
+ * 关闭 Agent Manager 面板
8845
+ * IDE 环境: 通过 IPC 通知 IDE 关闭 Agent Manager(用于返回 IDE)
8846
+ */
8847
+ async closeAgentManager() {
8848
+ this.log("Triggering close agent manager via IPC");
8849
+ try {
8850
+ await this.sendBackendRequest(BACKEND_REQUEST_TYPES.CLOSE_AGENT_MANAGER);
8851
+ } catch (error) {
8852
+ this.log("Close agent manager request failed:", error);
8853
+ throw error;
8854
+ }
8855
+ }
8856
+ /**
8857
+ * 在外部浏览器中打开链接
8858
+ * IDE 环境: 通过 IPC 通知 IDE 使用 vscode.env.openExternal 打开 URL
8859
+ * @param url 要打开的 URL
8860
+ */
8861
+ async openExternal(url) {
8862
+ this.log("Opening external URL via IPC:", url);
8863
+ try {
8864
+ await this.sendBackendRequest(BACKEND_REQUEST_TYPES.OPEN_EXTERNAL, { url });
8865
+ } catch (error) {
8866
+ this.log("Open external request failed:", error);
8867
+ throw error;
8868
+ }
8869
+ }
8870
+ /**
8554
8871
  * 批量切换插件状态
8555
8872
  * IDE 环境: 通过 IPC 调用 Extension Host 的 PluginService
8556
8873
  */
@@ -8564,22 +8881,22 @@ var IPCBackendProvider = class {
8564
8881
  }
8565
8882
  }
8566
8883
  /**
8567
- * 获取支持的插件列表
8884
+ * 获取支持的场景列表
8568
8885
  * IDE 环境: 通过 IPC 调用后端 API
8569
8886
  * 用于 Welcome 页面的 QuickActions 快捷操作
8570
8887
  *
8571
8888
  * 调用链:
8572
- * 1. agent-ui: IPCBackendProvider.getSupportPlugins()
8573
- * 2. Extension Host: BackendBridgeService.handleGetSupportPlugins()
8574
- * 3. Backend API: GET /v2/as/support/plugins
8575
- * 4. 返回 SupportPlugin[] 数据给 agent-ui
8889
+ * 1. agent-ui: IPCBackendProvider.getSupportScenes()
8890
+ * 2. Extension Host: BackendBridgeService.handleGetSupportScenes()
8891
+ * 3. Backend API: GET /v2/as/support/scenes
8892
+ * 4. 返回 SupportScene[] 数据给 agent-ui
8576
8893
  */
8577
- async getSupportPlugins() {
8578
- this.log("Getting support plugins via IPC");
8894
+ async getSupportScenes() {
8895
+ this.log("Getting support scenes via IPC");
8579
8896
  try {
8580
- return (await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_SUPPORT_PLUGINS, {}))?.plugins || [];
8897
+ return (await this.sendBackendRequest(BACKEND_REQUEST_TYPES.GET_SUPPORT_SCENES, {}))?.scenes || [];
8581
8898
  } catch (error) {
8582
- this.log("Get support plugins failed:", error);
8899
+ this.log("Get support scenes failed:", error);
8583
8900
  return [];
8584
8901
  }
8585
8902
  }