@victor-software-house/pi-openai-proxy 4.4.1 → 4.5.0

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/config.d.mts CHANGED
@@ -1,3 +1,3 @@
1
1
 
2
- import { a as configToEnv, c as isPublicModelIdMode, d as saveConfigToFile, i as PublicModelIdMode, l as loadConfigFromFile, n as ModelExposureMode, o as getConfigPath, r as ProxyConfig, s as isModelExposureMode, t as DEFAULT_CONFIG, u as normalizeConfig } from "./schema-BTAG6Urs.mjs";
3
- export { DEFAULT_CONFIG, ModelExposureMode, ProxyConfig, PublicModelIdMode, configToEnv, getConfigPath, isModelExposureMode, isPublicModelIdMode, loadConfigFromFile, normalizeConfig, saveConfigToFile };
2
+ import { a as ZedSyncConfig, c as isModelExposureMode, d as normalizeConfig, f as saveConfigToFile, i as PublicModelIdMode, l as isPublicModelIdMode, n as ModelExposureMode, o as configToEnv, r as ProxyConfig, s as getConfigPath, t as DEFAULT_CONFIG, u as loadConfigFromFile } from "./schema-B2x0rLJN.mjs";
3
+ export { DEFAULT_CONFIG, ModelExposureMode, ProxyConfig, PublicModelIdMode, ZedSyncConfig, configToEnv, getConfigPath, isModelExposureMode, isPublicModelIdMode, loadConfigFromFile, normalizeConfig, saveConfigToFile };
package/dist/config.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env bun
2
- import { a as isPublicModelIdMode, c as saveConfigToFile, i as isModelExposureMode, n as configToEnv, o as loadConfigFromFile, r as getConfigPath, s as normalizeConfig, t as DEFAULT_CONFIG } from "./schema-x6mps-hM.mjs";
2
+ import { a as isPublicModelIdMode, c as saveConfigToFile, i as isModelExposureMode, n as configToEnv, o as loadConfigFromFile, r as getConfigPath, s as normalizeConfig, t as DEFAULT_CONFIG } from "./schema-IE4WK0Dj.mjs";
3
3
  export { DEFAULT_CONFIG, configToEnv, getConfigPath, isModelExposureMode, isPublicModelIdMode, loadConfigFromFile, normalizeConfig, saveConfigToFile };
@@ -1,5 +1,5 @@
1
1
 
2
- import { i as PublicModelIdMode, n as ModelExposureMode } from "./schema-BTAG6Urs.mjs";
2
+ import { i as PublicModelIdMode, n as ModelExposureMode } from "./schema-B2x0rLJN.mjs";
3
3
  import { Api, Model } from "@mariozechner/pi-ai";
4
4
 
5
5
  //#region src/openai/model-exposure.d.ts
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env bun
2
- import { l as isRecord, o as loadConfigFromFile, r as getConfigPath } from "./schema-x6mps-hM.mjs";
2
+ import { l as isRecord, o as loadConfigFromFile, r as getConfigPath } from "./schema-IE4WK0Dj.mjs";
3
3
  import { computeModelExposure, resolveExposedModel } from "./exposure.mjs";
4
+ import * as z from "zod";
4
5
  import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
5
6
  import { randomBytes } from "node:crypto";
6
- import * as z from "zod";
7
7
  import { Type } from "@sinclair/typebox";
8
8
  import { completeSimple, streamSimple } from "@mariozechner/pi-ai";
9
9
  import { Hono } from "hono";
@@ -1,12 +1,7 @@
1
1
 
2
+ import * as z from "zod";
3
+
2
4
  //#region src/config/schema.d.ts
3
- /**
4
- * Proxy configuration schema -- single source of truth.
5
- *
6
- * Used by both the proxy server and the pi extension.
7
- * The server reads the JSON config file as defaults, with env vars and CLI args as overrides.
8
- * The pi extension reads and writes the JSON config file via the /proxy config panel.
9
- */
10
5
  /**
11
6
  * How public model IDs are generated from canonical provider/model-id pairs.
12
7
  *
@@ -48,7 +43,14 @@ interface ProxyConfig {
48
43
  readonly customModels: readonly string[];
49
44
  /** Provider key -> custom public prefix label. Default prefix = provider key. */
50
45
  readonly providerPrefixes: Readonly<Record<string, string>>;
46
+ /** Zed editor sync settings. */
47
+ readonly zed: ZedSyncConfig;
51
48
  }
49
+ declare const ZedSyncConfigSchema: z.ZodObject<{
50
+ providerName: z.ZodDefault<z.ZodString>;
51
+ autoSync: z.ZodDefault<z.ZodBoolean>;
52
+ }, z.core.$strip>;
53
+ type ZedSyncConfig = z.infer<typeof ZedSyncConfigSchema>;
52
54
  declare const DEFAULT_CONFIG: Readonly<ProxyConfig>;
53
55
  declare function isPublicModelIdMode(value: string): value is PublicModelIdMode;
54
56
  declare function isModelExposureMode(value: string): value is ModelExposureMode;
@@ -58,4 +60,4 @@ declare function loadConfigFromFile(): ProxyConfig;
58
60
  declare function saveConfigToFile(config: ProxyConfig): void;
59
61
  declare function configToEnv(config: ProxyConfig): Record<string, string>;
60
62
  //#endregion
61
- export { configToEnv as a, isPublicModelIdMode as c, saveConfigToFile as d, PublicModelIdMode as i, loadConfigFromFile as l, ModelExposureMode as n, getConfigPath as o, ProxyConfig as r, isModelExposureMode as s, DEFAULT_CONFIG as t, normalizeConfig as u };
63
+ export { ZedSyncConfig as a, isModelExposureMode as c, normalizeConfig as d, saveConfigToFile as f, PublicModelIdMode as i, isPublicModelIdMode as l, ModelExposureMode as n, configToEnv as o, ProxyConfig as r, getConfigPath as s, DEFAULT_CONFIG as t, loadConfigFromFile as u };
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
3
3
  import { dirname, resolve } from "node:path";
4
+ import * as z from "zod";
4
5
  //#region src/utils/guards.ts
5
6
  /**
6
7
  * Shared type guard utilities.
@@ -21,6 +22,10 @@ function isRecord(value) {
21
22
  * The server reads the JSON config file as defaults, with env vars and CLI args as overrides.
22
23
  * The pi extension reads and writes the JSON config file via the /proxy config panel.
23
24
  */
25
+ const ZedSyncConfigSchema = z.object({
26
+ providerName: z.string().trim().min(1, { error: "Provider name must not be empty" }).default("Pi Proxy"),
27
+ autoSync: z.boolean({ error: "autoSync must be a boolean" }).default(false)
28
+ });
24
29
  const DEFAULT_CONFIG = {
25
30
  host: "127.0.0.1",
26
31
  port: 4141,
@@ -33,7 +38,11 @@ const DEFAULT_CONFIG = {
33
38
  modelExposureMode: "scoped",
34
39
  scopedProviders: [],
35
40
  customModels: [],
36
- providerPrefixes: {}
41
+ providerPrefixes: {},
42
+ zed: {
43
+ providerName: "Pi Proxy",
44
+ autoSync: false
45
+ }
37
46
  };
38
47
  function clampInt(raw, min, max, fallback) {
39
48
  if (typeof raw !== "number" || !Number.isFinite(raw)) return fallback;
@@ -86,9 +95,15 @@ function normalizeConfig(raw) {
86
95
  modelExposureMode: typeof rawExposureMode === "string" && isModelExposureMode(rawExposureMode) ? rawExposureMode : DEFAULT_CONFIG.modelExposureMode,
87
96
  scopedProviders: normalizeStringArray(v["scopedProviders"]),
88
97
  customModels: normalizeStringArray(v["customModels"]),
89
- providerPrefixes: normalizeStringRecord(v["providerPrefixes"])
98
+ providerPrefixes: normalizeStringRecord(v["providerPrefixes"]),
99
+ zed: parseZedSyncConfig(v["zed"])
90
100
  };
91
101
  }
102
+ function parseZedSyncConfig(raw) {
103
+ const result = ZedSyncConfigSchema.safeParse(isRecord(raw) ? raw : {});
104
+ if (result.success) return result.data;
105
+ return ZedSyncConfigSchema.parse({});
106
+ }
92
107
  function getConfigPath() {
93
108
  return resolve(process.env.PI_CODING_AGENT_DIR ?? resolve(process.env.HOME ?? "~", ".pi", "agent"), "proxy-config.json");
94
109
  }
@@ -587,27 +587,23 @@ export default function proxyExtension(pi: ExtensionAPI): void {
587
587
 
588
588
  // --- Zed sync ---
589
589
 
590
- function handleZedSync(ctx: ExtensionContext, args: string): void {
591
- config = loadConfigFromFile();
592
-
593
- const dryRun = args.includes("--dry-run");
594
-
595
- // Compute exposed models (same as /proxy models)
590
+ /**
591
+ * Run Zed sync and return the result. Shared by the command and auto-sync.
592
+ */
593
+ function runZedSync(dryRun: boolean): { ok: boolean; message: string } {
596
594
  const available = getAvailableModels();
597
595
  const allModels = getAllRegisteredModels();
598
596
  const outcome = computeModelExposure(available, allModels, buildExposureConfig());
599
597
  if (!outcome.ok) {
600
- ctx.ui.notify(`Model exposure error: ${outcome.message}`, "error");
601
- return;
598
+ return { ok: false, message: `Model exposure error: ${outcome.message}` };
602
599
  }
603
600
 
604
601
  if (outcome.models.length === 0) {
605
- ctx.ui.notify("No models exposed. Nothing to sync.", "warning");
606
- return;
602
+ return { ok: false, message: "No models exposed. Nothing to sync." };
607
603
  }
608
604
 
609
605
  const syncOptions: ZedSyncOptions = {
610
- providerName: "Pi Proxy",
606
+ providerName: config.zed.providerName,
611
607
  apiUrl: `http://${config.host}:${String(config.port)}/v1`,
612
608
  dryRun,
613
609
  };
@@ -615,14 +611,30 @@ export default function proxyExtension(pi: ExtensionAPI): void {
615
611
  const result = syncToZed(outcome.models, syncOptions);
616
612
 
617
613
  if (!result.ok) {
618
- ctx.ui.notify(result.error ?? "Zed sync failed", "error");
619
- return;
614
+ return { ok: false, message: result.error ?? "Zed sync failed" };
620
615
  }
621
616
 
622
- const msg = dryRun
623
- ? `Zed sync dry-run: ${result.summary}\n${result.configPath}`
624
- : `Zed sync complete: ${result.summary}\n${result.configPath}`;
625
- ctx.ui.notify(msg, "info");
617
+ const prefix = dryRun ? "[dry-run] " : "";
618
+ return { ok: true, message: `${prefix}${result.summary} (${result.configPath})` };
619
+ }
620
+
621
+ function handleZedSync(ctx: ExtensionContext, args: string): void {
622
+ config = loadConfigFromFile();
623
+ const dryRun = args.includes("--dry-run");
624
+ const result = runZedSync(dryRun);
625
+ ctx.ui.notify(`Zed sync: ${result.message}`, result.ok ? "info" : "error");
626
+ }
627
+
628
+ /**
629
+ * Trigger auto-sync to Zed if enabled. Called after config save.
630
+ */
631
+ function maybeAutoSyncZed(ctx: ExtensionContext): void {
632
+ if (!config.zed.autoSync) return;
633
+ const result = runZedSync(false);
634
+ if (result.ok) {
635
+ ctx.ui.notify(`Zed auto-sync: ${result.message}`, "info");
636
+ }
637
+ // Silent on failure during auto-sync -- don't spam the user
626
638
  }
627
639
 
628
640
  async function waitForReady(timeoutMs: number): Promise<RuntimeStatus> {
@@ -868,6 +880,21 @@ export default function proxyExtension(pi: ExtensionAPI): void {
868
880
  currentValue: customModelsDisplay(),
869
881
  submenu: config.modelExposureMode === "custom" ? buildModelSelectorSubmenu : undefined,
870
882
  },
883
+ // --- Zed sync ---
884
+ {
885
+ id: "zed.autoSync",
886
+ label: "Zed auto-sync",
887
+ description: "Sync models to Zed settings.json when config changes",
888
+ currentValue: config.zed.autoSync ? "on" : "off",
889
+ values: ["off", "on"],
890
+ },
891
+ {
892
+ id: "zed.providerName",
893
+ label: "Zed provider name",
894
+ description: "Provider label in Zed's openai_compatible section",
895
+ currentValue: config.zed.providerName,
896
+ values: ["Pi Proxy"],
897
+ },
871
898
  ];
872
899
  }
873
900
 
@@ -958,6 +985,14 @@ export default function proxyExtension(pi: ExtensionAPI): void {
958
985
  case "customModels":
959
986
  // Handled by submenu -- no cycling
960
987
  break;
988
+ case "zed.autoSync":
989
+ config = { ...config, zed: { ...config.zed, autoSync: value === "on" } };
990
+ break;
991
+ case "zed.providerName":
992
+ if (value.length > 0) {
993
+ config = { ...config, zed: { ...config.zed, providerName: value } };
994
+ }
995
+ break;
961
996
  }
962
997
  saveConfigToFile(config);
963
998
  config = loadConfigFromFile();
@@ -988,6 +1023,10 @@ export default function proxyExtension(pi: ExtensionAPI): void {
988
1023
  return config.modelExposureMode;
989
1024
  case "customModels":
990
1025
  return customModelsDisplay();
1026
+ case "zed.autoSync":
1027
+ return config.zed.autoSync ? "on" : "off";
1028
+ case "zed.providerName":
1029
+ return config.zed.providerName;
991
1030
  default:
992
1031
  return "";
993
1032
  }
@@ -1023,6 +1062,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
1023
1062
  settingsList.updateValue("customModels", customModelsDisplay());
1024
1063
  }
1025
1064
 
1065
+ maybeAutoSyncZed(ctx);
1026
1066
  tui.requestRender();
1027
1067
  },
1028
1068
  () => done(undefined),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@victor-software-house/pi-openai-proxy",
3
- "version": "4.4.1",
3
+ "version": "4.5.0",
4
4
  "description": "OpenAI-compatible HTTP proxy for pi's multi-provider model registry",
5
5
  "license": "MIT",
6
6
  "author": "Victor Software House",