@telefonica/ai-sdlc-opencode-plugin-v1 1.0.1 → 1.0.2-snapshot.37008990101

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/index.js +25 -79
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -110,6 +110,19 @@ async function writeModelCache(scope, models) {
110
110
  await current;
111
111
  if (pendingWrites.get(path) === current) pendingWrites.delete(path);
112
112
  }
113
+ async function resolveModelList(scope, discover, isCurrent = () => true) {
114
+ try {
115
+ const fetched = await discover();
116
+ if (!isCurrent()) return void 0;
117
+ if (validModels(fetched)) {
118
+ if (isCurrent()) await writeModelCache(scope, fetched);
119
+ return fetched;
120
+ }
121
+ } catch {
122
+ if (!isCurrent()) return void 0;
123
+ }
124
+ return readModelCache(scope);
125
+ }
113
126
  //#endregion
114
127
  //#region src/server/auth-hook.ts
115
128
  function createAuthHook(flavor) {
@@ -175,79 +188,8 @@ async function resolveCredentials(flavor, options) {
175
188
  };
176
189
  }
177
190
  //#endregion
178
- //#region src/server/model-cache.ts
179
- function scope(root, flavor, apiKey) {
180
- return {
181
- environment: flavor.environment,
182
- baseURL: root,
183
- apiKey
184
- };
185
- }
186
- function toCanonical(models) {
187
- return Object.entries(models).map(([id, model]) => ({
188
- id,
189
- contextTokens: model.limit?.context,
190
- outputTokens: model.limit?.output,
191
- supportsTools: model.tool_call,
192
- supportsReasoning: model.reasoning,
193
- supportsVision: model.attachment,
194
- reasoningEfforts: model.variants ? Object.keys(model.variants) : void 0,
195
- inputCostPerToken: model.cost?.input == null ? void 0 : model.cost.input / 1e6,
196
- outputCostPerToken: model.cost?.output == null ? void 0 : model.cost.output / 1e6,
197
- cacheReadCostPerToken: model.cost?.cache_read == null ? void 0 : model.cost.cache_read / 1e6,
198
- cacheWriteCostPerToken: model.cost?.cache_write == null ? void 0 : model.cost.cache_write / 1e6
199
- }));
200
- }
201
- function fromCanonical(models) {
202
- return Object.fromEntries(models.map((model) => {
203
- const cost = model.inputCostPerToken != null || model.outputCostPerToken != null ? {
204
- input: (model.inputCostPerToken ?? 0) * 1e6,
205
- output: (model.outputCostPerToken ?? 0) * 1e6,
206
- ...model.cacheReadCostPerToken == null ? {} : { cache_read: model.cacheReadCostPerToken * 1e6 },
207
- ...model.cacheWriteCostPerToken == null ? {} : { cache_write: model.cacheWriteCostPerToken * 1e6 }
208
- } : void 0;
209
- const input = ["text"];
210
- if (model.supportsVision) input.push("image");
211
- if (model.supportsPdf) input.push("pdf");
212
- if (model.supportsAudio) input.push("audio");
213
- return [model.id, {
214
- name: unsanitizeModelId(model.id),
215
- limit: {
216
- context: model.contextTokens ?? 128e3,
217
- output: model.outputTokens ?? 16384
218
- },
219
- tool_call: model.supportsTools ?? true,
220
- reasoning: model.supportsReasoning ?? false,
221
- attachment: model.supportsVision ?? false,
222
- ...model.reasoningEfforts?.length ? { variants: Object.fromEntries(model.reasoningEfforts.map((effort) => [effort, { reasoningEffort: effort }])) } : {},
223
- ...cost ? { cost } : {},
224
- modalities: {
225
- input,
226
- output: ["text"]
227
- }
228
- }];
229
- }));
230
- }
231
- async function readCache(root, flavor, apiKey) {
232
- const models = await readModelCache(scope(root, flavor, apiKey));
233
- return models?.length ? fromCanonical(models) : void 0;
234
- }
235
- async function writeCache(root, flavor, apiKey, models) {
236
- await writeModelCache(scope(root, flavor, apiKey), toCanonical(models));
237
- }
238
- async function resolveCachedModels(root, flavor, apiKey, discover) {
239
- try {
240
- const models = await discover();
241
- if (Object.keys(models).length > 0) {
242
- await writeCache(root, flavor, apiKey, models);
243
- return models;
244
- }
245
- } catch {}
246
- return readCache(root, flavor, apiKey);
247
- }
248
- //#endregion
249
191
  //#region src/server/models-client.ts
250
- function toModelEntry(model) {
192
+ function toV1ModelEntry(model) {
251
193
  const cost = model.inputCostPerToken != null || model.outputCostPerToken != null ? {
252
194
  input: (model.inputCostPerToken ?? 0) * 1e6,
253
195
  output: (model.outputCostPerToken ?? 0) * 1e6,
@@ -275,23 +217,27 @@ function toModelEntry(model) {
275
217
  }
276
218
  };
277
219
  }
278
- async function discoverModelsForV1(root, apiKey, logger) {
220
+ async function discoverGatewayModelsForV1(root, apiKey, logger) {
279
221
  const result = await discoverModels({
280
222
  baseURL: root,
281
223
  apiKey,
282
224
  logger
283
225
  });
284
226
  if (!result.ok) throw new Error(result.error.message);
285
- return Object.fromEntries(result.value.map((model) => [model.id, toModelEntry(model)]));
227
+ return result.value;
228
+ }
229
+ function toV1ModelMap(models) {
230
+ return Object.fromEntries(models.map((model) => [model.id, toV1ModelEntry(model)]));
286
231
  }
287
232
  //#endregion
288
233
  //#region src/server/config-hook.ts
289
234
  async function resolveModels(root, apiKey, flavor, logger) {
290
- return resolveCachedModels(root, flavor, apiKey, async () => {
291
- const models = await discoverModelsForV1(root, apiKey, logger);
292
- if (Object.keys(models).length === 0) throw new Error("No usable chat models");
293
- return models;
294
- });
235
+ const models = await resolveModelList({
236
+ environment: flavor.environment,
237
+ baseURL: root,
238
+ apiKey
239
+ }, () => discoverGatewayModelsForV1(root, apiKey, logger));
240
+ return models?.length ? toV1ModelMap(models) : void 0;
295
241
  }
296
242
  function createConfigHook(flavor, logger) {
297
243
  return async function configHook(config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telefonica/ai-sdlc-opencode-plugin-v1",
3
- "version": "1.0.1",
3
+ "version": "1.0.2-snapshot.37008990101",
4
4
  "description": "OpenCode 1.x plugin: CDO.AI provider registration, model discovery, and budget panel",
5
5
  "type": "module",
6
6
  "exports": {