@billjr99/pi-openai-compat 1.1.12 → 1.1.13

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 (3) hide show
  1. package/README.md +13 -1
  2. package/index.ts +69 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -82,7 +82,7 @@ If pi is already running when you install, type `/reload` first.
82
82
 
83
83
  ## Commands
84
84
 
85
- Only two commands are needed.
85
+ Three commands are available; `/compat-login` is the only one you need to get started.
86
86
 
87
87
  ### `/compat-login`
88
88
 
@@ -98,6 +98,18 @@ After login, the provider's models appear in pi's `/model` command and
98
98
  `Ctrl+L` picker immediately. You can run `/compat-login` again to add a
99
99
  second provider — all providers are active simultaneously.
100
100
 
101
+ ### `/compat-refresh`
102
+
103
+ Re-fetches the model list for an already-registered provider, reusing the
104
+ saved base URL, API key, and discovery settings — no need to re-enter URLs,
105
+ keys, or account IDs. Use it to pick up models a provider has added (or
106
+ dropped) since you logged in, without restarting your session.
107
+
108
+ If you have multiple providers registered, you are asked which one to refresh
109
+ (or choose **All providers**); with a single provider it refreshes directly.
110
+ A failed or empty refresh leaves the existing model list untouched, so a flaky
111
+ network call can't blank out a working provider.
112
+
101
113
  ### `/compat-logout`
102
114
 
103
115
  Unregisters a provider from pi. If you have multiple providers registered,
package/index.ts CHANGED
@@ -8,8 +8,9 @@
8
8
  * - Every provider saved in config.json is registered automatically at
9
9
  * startup. The factory is async so pi waits for registration to complete
10
10
  * before showing the model list — no session_start delay.
11
- * - /compat-login adds a provider (fetches fresh model list, registers).
12
- * - /compat-logout removes a provider (unregisters, restores previous model).
11
+ * - /compat-login adds a provider (fetches fresh model list, registers).
12
+ * - /compat-refresh re-fetches the model list for a registered provider.
13
+ * - /compat-logout removes a provider (unregisters, restores previous model).
13
14
  * - No activeProviders list — presence in config.providers means registered.
14
15
  *
15
16
  * Config: ~/.config/pi-openai-compat/config.json
@@ -690,6 +691,72 @@ export default async function (pi: ExtensionAPI) {
690
691
  },
691
692
  });
692
693
 
694
+ // ── /compat-refresh ──────────────────────────────────────────────────────────
695
+ // Force a re-fetch of an already-registered provider's model list, reusing
696
+ // the persisted baseUrl/apiKey and discovery overrides — no need to re-enter
697
+ // URLs, keys, or account IDs like /compat-login. Picks up newly added (or
698
+ // dropped) upstream models without restarting the session.
699
+ pi.registerCommand("compat-refresh", {
700
+ description: "Re-fetch the model list for a registered OpenAI-compatible provider",
701
+ handler: async (_args, ctx) => {
702
+ const providerKeys = Object.keys(config.providers);
703
+ if (!providerKeys.length) {
704
+ ctx.ui.notify("No compat providers are registered. Run /compat-login first.", "info");
705
+ return;
706
+ }
707
+
708
+ // Choose which provider(s) to refresh. With one provider, refresh it
709
+ // directly; otherwise offer each by name plus an "All providers" option.
710
+ let keys: string[];
711
+ if (providerKeys.length === 1) {
712
+ keys = providerKeys;
713
+ } else {
714
+ const ALL = "All providers";
715
+ const labels = [ALL, ...providerKeys.map((k) => config.providers[k].displayName)];
716
+ const chosen = await ctx.ui.select("Refresh which provider?", labels);
717
+ if (!chosen) { ctx.ui.notify("Cancelled.", "info"); return; }
718
+ keys = chosen === ALL ? providerKeys : [providerKeys[labels.indexOf(chosen) - 1]];
719
+ }
720
+
721
+ const refreshed: string[] = [];
722
+ const failed: string[] = [];
723
+ for (const key of keys) {
724
+ const p = config.providers[key];
725
+ ctx.ui.notify(`Refreshing ${p.displayName} …`, "info");
726
+ try {
727
+ const models = await fetchModels(p.baseUrl, p.apiKey, {
728
+ url: p.modelsUrl,
729
+ idField: p.modelsIdField,
730
+ keepTask: p.modelsKeepTask,
731
+ });
732
+ if (models.length > 0) {
733
+ // Only overwrite the cache on a successful, non-empty fetch — a
734
+ // flaky refresh must never blank out a working provider's models.
735
+ p.cachedModels = models;
736
+ saveConfig(config);
737
+ registerProvider(pi, key, p);
738
+ refreshed.push(`${p.displayName} (${models.length})`);
739
+ } else {
740
+ failed.push(p.displayName);
741
+ }
742
+ } catch {
743
+ failed.push(p.displayName);
744
+ }
745
+ }
746
+
747
+ if (refreshed.length > 0) {
748
+ ctx.ui.notify(`Refreshed: ${refreshed.join(", ")}.`, "success");
749
+ }
750
+ if (failed.length > 0) {
751
+ ctx.ui.notify(
752
+ `Could not refresh ${failed.join(", ")} — kept the existing model list. ` +
753
+ `Run /compat-login if the provider's URL or key changed.`,
754
+ "warning"
755
+ );
756
+ }
757
+ },
758
+ });
759
+
693
760
  // ── /compat-logout ─────────────────────────────────────────────────────────
694
761
  pi.registerCommand("compat-logout", {
695
762
  description: "Remove an OpenAI-compatible provider from pi's model list",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@billjr99/pi-openai-compat",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "description": "pi-coding-agent extension: OpenAI-compatible endpoint support (OpenRouter, NVIDIA NIM, Nous Portal, Ollama, custom)",
5
5
  "author": "Bill Mongan <https://github.com/BillJr99>",
6
6
  "license": "MIT",