opencode-codebuddy-external-auth 1.0.16 → 1.0.18

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.
Files changed (2) hide show
  1. package/dist/plugin.js +114 -6
  2. package/package.json +1 -1
package/dist/plugin.js CHANGED
@@ -91,10 +91,111 @@ function resolveModel(inputModel) {
91
91
  return CONFIG.defaultModel;
92
92
  return inputModel || "";
93
93
  }
94
- function buildAuthHeaders(accessToken) {
95
- const tenantId = resolveTenantId(accessToken);
96
- const enterpriseId = resolveEnterpriseId(accessToken);
97
- const userId = resolveUserId(accessToken);
94
+ let cachedTenantId = "";
95
+ let cachedEnterpriseId = "";
96
+ let cachedUserId = "";
97
+ let cachedModelIds = [];
98
+ let warnedModelFallback = false;
99
+ function extractModelIds(payload) {
100
+ const results = [];
101
+ const collect = (list) => {
102
+ if (!Array.isArray(list))
103
+ return;
104
+ for (const item of list) {
105
+ if (!item)
106
+ continue;
107
+ if (typeof item === "string") {
108
+ results.push(item);
109
+ continue;
110
+ }
111
+ if (typeof item === "object") {
112
+ const id = item.id ||
113
+ item.model ||
114
+ item.modelId ||
115
+ item.model_id ||
116
+ item.code ||
117
+ item.name;
118
+ if (typeof id === "string")
119
+ results.push(id);
120
+ if (Array.isArray(item.models))
121
+ collect(item.models);
122
+ }
123
+ }
124
+ };
125
+ const candidates = [
126
+ payload?.data?.models,
127
+ payload?.data?.modelList,
128
+ payload?.data?.availableModels,
129
+ payload?.models,
130
+ payload?.modelList,
131
+ payload?.availableModels,
132
+ payload?.data?.modelGroups,
133
+ payload?.modelGroups,
134
+ ];
135
+ for (const list of candidates) {
136
+ collect(list);
137
+ }
138
+ return Array.from(new Set(results)).filter(Boolean);
139
+ }
140
+ async function fetchConfigModels(accessToken, tenantId) {
141
+ if (!tenantId)
142
+ return { enterpriseId: "", models: [] };
143
+ try {
144
+ const url = `${CONFIG.serverUrl}/console/enterprises/${tenantId}/config/models`;
145
+ const response = await fetch(url, {
146
+ method: "GET",
147
+ headers: {
148
+ "Accept": "application/json, text/plain, */*",
149
+ "X-Requested-With": "XMLHttpRequest",
150
+ "Authorization": `Bearer ${accessToken}`,
151
+ },
152
+ });
153
+ if (!response.ok) {
154
+ return { enterpriseId: "", models: [] };
155
+ }
156
+ const data = await response.json();
157
+ const enterpriseId = data?.data?.enterpriseId || data?.enterpriseId || "";
158
+ const models = extractModelIds(data);
159
+ return { enterpriseId, models };
160
+ }
161
+ catch {
162
+ return { enterpriseId: "", models: [] };
163
+ }
164
+ }
165
+ async function getSupportedModels(accessToken, tenantId) {
166
+ if (cachedModelIds.length > 0)
167
+ return cachedModelIds;
168
+ const config = await fetchConfigModels(accessToken, tenantId);
169
+ if (config.enterpriseId && !cachedEnterpriseId) {
170
+ cachedEnterpriseId = config.enterpriseId;
171
+ }
172
+ if (config.models.length) {
173
+ cachedModelIds = config.models;
174
+ }
175
+ return cachedModelIds;
176
+ }
177
+ function pickFallbackModel(models) {
178
+ if (models.includes("glm-4.7-ioa"))
179
+ return "glm-4.7-ioa";
180
+ return models[0] || "";
181
+ }
182
+ async function buildAuthHeaders(accessToken) {
183
+ const tenantId = cachedTenantId || resolveTenantId(accessToken);
184
+ let enterpriseId = cachedEnterpriseId || resolveEnterpriseId(accessToken);
185
+ const userId = cachedUserId || resolveUserId(accessToken);
186
+ if (!enterpriseId) {
187
+ const config = await fetchConfigModels(accessToken, tenantId);
188
+ enterpriseId = config.enterpriseId || enterpriseId;
189
+ if (config.models.length) {
190
+ cachedModelIds = config.models;
191
+ }
192
+ }
193
+ if (tenantId)
194
+ cachedTenantId = tenantId;
195
+ if (enterpriseId)
196
+ cachedEnterpriseId = enterpriseId;
197
+ if (userId)
198
+ cachedUserId = userId;
98
199
  if (!tenantId && !warnedTenantId) {
99
200
  warnedTenantId = true;
100
201
  console.warn("[codebuddy-external] 未获取到 X-Tenant-Id,请设置 CODEBUDDY_TENANT_ID");
@@ -343,10 +444,16 @@ async function executeViaAuthApi(openaiRequest, auth) {
343
444
  throw new Error("缺少 access token,无法调用 CodeBuddy API");
344
445
  }
345
446
  let accessToken = auth.access;
447
+ const tenantId = resolveTenantId(accessToken);
346
448
  const resolvedModel = resolveModel(openaiRequest.model);
449
+ const supportedModels = await getSupportedModels(accessToken, tenantId);
347
450
  if (!resolvedModel) {
348
- throw new Error("未设置模型,请设置 CODEBUDDY_DEFAULT_MODEL 或在 OpenCode 选择模型");
451
+ throw new Error("未设置模型,请在 OpenCode 选择模型");
452
+ }
453
+ if (supportedModels.length && !supportedModels.includes(resolvedModel)) {
454
+ throw new Error(`[codebuddy-external] 模型 ${resolvedModel} 不在可用列表,请更换模型`);
349
455
  }
456
+ console.log(`[codebuddy-external] 使用模型: ${resolvedModel}`);
350
457
  const requestBody = {
351
458
  ...openaiRequest,
352
459
  model: resolvedModel,
@@ -354,9 +461,10 @@ async function executeViaAuthApi(openaiRequest, auth) {
354
461
  stream: openaiRequest.stream ?? true,
355
462
  };
356
463
  const doRequest = async (token) => {
464
+ const headers = await buildAuthHeaders(token);
357
465
  const response = await fetch(`${CONFIG.serverUrl}${CONFIG.chatCompletionsPath}`, {
358
466
  method: "POST",
359
- headers: buildAuthHeaders(token),
467
+ headers,
360
468
  body: JSON.stringify(requestBody),
361
469
  });
362
470
  return response;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-codebuddy-external-auth",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "OpenCode plugin for CodeBuddy External (IOA) authentication",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",