gitlab-ai-provider 5.2.0 → 5.2.1

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
@@ -2675,6 +2675,7 @@ import * as fs from "fs";
2675
2675
  import * as path2 from "path";
2676
2676
  import * as os from "os";
2677
2677
  import * as crypto from "crypto";
2678
+ var DISCOVERY_TTL_MS = 10 * 60 * 1e3;
2678
2679
  function getCacheFilePath() {
2679
2680
  const cacheHome = process.env.XDG_CACHE_HOME || path2.join(os.homedir(), ".cache");
2680
2681
  return path2.join(cacheHome, "opencode", "gitlab-workflow-model-cache.json");
@@ -2724,13 +2725,23 @@ var GitLabModelCache = class {
2724
2725
  data[this.key] = entry;
2725
2726
  this.writeAll(data);
2726
2727
  }
2728
+ /**
2729
+ * Returns true if the discovery data is missing or older than DISCOVERY_TTL_MS.
2730
+ */
2731
+ isDiscoveryExpired() {
2732
+ const entry = this.load();
2733
+ if (!entry?.discovery || !entry.updatedAt) return true;
2734
+ return Date.now() - new Date(entry.updatedAt).getTime() > DISCOVERY_TTL_MS;
2735
+ }
2727
2736
  /**
2728
2737
  * Update only the discovery portion of the cache, preserving selection.
2738
+ * Optionally persists the associated GitLab project.
2729
2739
  */
2730
- saveDiscovery(discovery) {
2740
+ saveDiscovery(discovery, project) {
2731
2741
  const existing = this.load();
2732
2742
  this.save({
2733
2743
  discovery,
2744
+ project: project !== void 0 ? project : existing?.project ?? null,
2734
2745
  selectedModelRef: existing?.selectedModelRef ?? null,
2735
2746
  selectedModelName: existing?.selectedModelName ?? null,
2736
2747
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -2738,13 +2749,22 @@ var GitLabModelCache = class {
2738
2749
  }
2739
2750
  /**
2740
2751
  * Update only the selected model, preserving the discovery data.
2752
+ * If name is null but ref is provided, attempts to resolve the name
2753
+ * from the cached discovery data.
2741
2754
  */
2742
2755
  saveSelection(ref, name) {
2743
2756
  const existing = this.load();
2757
+ let resolved = name;
2758
+ if (!resolved && ref && existing?.discovery) {
2759
+ const d = existing.discovery;
2760
+ const match = d.pinnedModel?.ref === ref ? d.pinnedModel : d.selectableModels.find((m) => m.ref === ref) ?? (d.defaultModel?.ref === ref ? d.defaultModel : null);
2761
+ resolved = match?.name ?? null;
2762
+ }
2744
2763
  this.save({
2745
2764
  discovery: existing?.discovery ?? null,
2765
+ project: existing?.project ?? null,
2746
2766
  selectedModelRef: ref,
2747
- selectedModelName: name,
2767
+ selectedModelName: resolved,
2748
2768
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2749
2769
  });
2750
2770
  }
@@ -2886,7 +2906,8 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
2886
2906
  */
2887
2907
  set selectedModelRef(ref) {
2888
2908
  this._selectedModelRef = ref ?? void 0;
2889
- this.modelCache.saveSelection(ref, this._selectedModelName ?? null);
2909
+ this._selectedModelName = void 0;
2910
+ this.modelCache.saveSelection(ref, null);
2890
2911
  }
2891
2912
  /**
2892
2913
  * Get the cached selected model display name.
@@ -4426,29 +4447,8 @@ function parseModelsYml(text) {
4426
4447
 
4427
4448
  // src/gitlab-workflow-discovery.ts
4428
4449
  var configRegistry = new GitLabModelConfigRegistry();
4429
- async function discoverWorkflowModels(config, options) {
4430
- const detector = new GitLabProjectDetector({
4431
- instanceUrl: config.instanceUrl,
4432
- getHeaders: config.getHeaders,
4433
- fetch: config.fetch
4434
- });
4435
- let project = null;
4436
- try {
4437
- project = await detector.detectProject(options.workingDirectory);
4438
- } catch {
4439
- return { models: [], project: null };
4440
- }
4441
- const namespaceId = project?.namespaceId;
4442
- if (!namespaceId) return { models: [], project };
4443
- const discovery = new GitLabModelDiscovery({
4444
- instanceUrl: config.instanceUrl,
4445
- getHeaders: config.getHeaders,
4446
- fetch: config.fetch
4447
- });
4448
- const [discovered, configs] = await Promise.all([
4449
- discovery.discover(`gid://gitlab/Group/${namespaceId}`),
4450
- configRegistry.getConfigs()
4451
- ]);
4450
+ async function buildModels(discovered, project) {
4451
+ const configs = await configRegistry.getConfigs();
4452
4452
  const refToID = /* @__PURE__ */ new Map();
4453
4453
  for (const [id, mapping] of Object.entries(MODEL_MAPPINGS)) {
4454
4454
  if (mapping.provider === "workflow" && id !== "duo-workflow" && id !== "duo-workflow-default") {
@@ -4477,6 +4477,34 @@ async function discoverWorkflowModels(config, options) {
4477
4477
  }
4478
4478
  return { models, project };
4479
4479
  }
4480
+ async function discoverWorkflowModels(config, options) {
4481
+ const cache = new GitLabModelCache(options.workingDirectory, config.instanceUrl);
4482
+ if (!cache.isDiscoveryExpired()) {
4483
+ const entry = cache.load();
4484
+ return buildModels(entry.discovery, entry.project);
4485
+ }
4486
+ const detector = new GitLabProjectDetector({
4487
+ instanceUrl: config.instanceUrl,
4488
+ getHeaders: config.getHeaders,
4489
+ fetch: config.fetch
4490
+ });
4491
+ let project = null;
4492
+ try {
4493
+ project = await detector.detectProject(options.workingDirectory);
4494
+ } catch {
4495
+ return { models: [], project: null };
4496
+ }
4497
+ const namespaceId = project?.namespaceId;
4498
+ if (!namespaceId) return { models: [], project };
4499
+ const discovery = new GitLabModelDiscovery({
4500
+ instanceUrl: config.instanceUrl,
4501
+ getHeaders: config.getHeaders,
4502
+ fetch: config.fetch
4503
+ });
4504
+ const discovered = await discovery.discover(`gid://gitlab/Group/${namespaceId}`);
4505
+ cache.saveDiscovery(discovered, project);
4506
+ return buildModels(discovered, project);
4507
+ }
4480
4508
  export {
4481
4509
  AGENT_PRIVILEGES,
4482
4510
  BUNDLED_CLIENT_ID,