@victor-software-house/pi-openai-proxy 0.3.1 → 1.0.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 +33 -0
- package/dist/config.mjs +78 -0
- package/dist/index.d.mts +1 -10
- package/dist/index.mjs +331 -3020
- package/extensions/proxy.ts +64 -152
- package/package.json +19 -7
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
//#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
|
+
interface ProxyConfig {
|
|
11
|
+
/** Bind address. Default: "127.0.0.1" */
|
|
12
|
+
readonly host: string;
|
|
13
|
+
/** Listen port. Default: 4141 */
|
|
14
|
+
readonly port: number;
|
|
15
|
+
/** Bearer token for proxy auth. Empty string = disabled. */
|
|
16
|
+
readonly authToken: string;
|
|
17
|
+
/** Allow remote image URL fetching. Default: false */
|
|
18
|
+
readonly remoteImages: boolean;
|
|
19
|
+
/** Max request body in MB. Default: 50 */
|
|
20
|
+
readonly maxBodySizeMb: number;
|
|
21
|
+
/** Upstream timeout in seconds. Default: 120 */
|
|
22
|
+
readonly upstreamTimeoutSec: number;
|
|
23
|
+
/** "detached" = background daemon, "session" = dies with pi session. Default: "detached" */
|
|
24
|
+
readonly lifetime: "detached" | "session";
|
|
25
|
+
}
|
|
26
|
+
declare const DEFAULT_CONFIG: Readonly<ProxyConfig>;
|
|
27
|
+
declare function normalizeConfig(raw: unknown): ProxyConfig;
|
|
28
|
+
declare function getConfigPath(): string;
|
|
29
|
+
declare function loadConfigFromFile(): ProxyConfig;
|
|
30
|
+
declare function saveConfigToFile(config: ProxyConfig): void;
|
|
31
|
+
declare function configToEnv(config: ProxyConfig): Record<string, string>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { DEFAULT_CONFIG, ProxyConfig, configToEnv, getConfigPath, loadConfigFromFile, normalizeConfig, saveConfigToFile };
|
package/dist/config.mjs
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
//#region src/config/schema.ts
|
|
5
|
+
/**
|
|
6
|
+
* Proxy configuration schema -- single source of truth.
|
|
7
|
+
*
|
|
8
|
+
* Used by both the proxy server and the pi extension.
|
|
9
|
+
* The server reads the JSON config file as defaults, with env vars and CLI args as overrides.
|
|
10
|
+
* The pi extension reads and writes the JSON config file via the /proxy config panel.
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_CONFIG = {
|
|
13
|
+
host: "127.0.0.1",
|
|
14
|
+
port: 4141,
|
|
15
|
+
authToken: "",
|
|
16
|
+
remoteImages: false,
|
|
17
|
+
maxBodySizeMb: 50,
|
|
18
|
+
upstreamTimeoutSec: 120,
|
|
19
|
+
lifetime: "detached"
|
|
20
|
+
};
|
|
21
|
+
function isRecord(value) {
|
|
22
|
+
return value !== null && value !== void 0 && typeof value === "object" && !Array.isArray(value);
|
|
23
|
+
}
|
|
24
|
+
function clampInt(raw, min, max, fallback) {
|
|
25
|
+
if (typeof raw !== "number" || !Number.isFinite(raw)) return fallback;
|
|
26
|
+
return Math.max(min, Math.min(max, Math.round(raw)));
|
|
27
|
+
}
|
|
28
|
+
function normalizeConfig(raw) {
|
|
29
|
+
const v = isRecord(raw) ? raw : {};
|
|
30
|
+
const rawHost = v["host"];
|
|
31
|
+
const rawAuthToken = v["authToken"];
|
|
32
|
+
const rawRemoteImages = v["remoteImages"];
|
|
33
|
+
return {
|
|
34
|
+
host: typeof rawHost === "string" && rawHost.length > 0 ? rawHost : DEFAULT_CONFIG.host,
|
|
35
|
+
port: clampInt(v["port"], 1, 65535, DEFAULT_CONFIG.port),
|
|
36
|
+
authToken: typeof rawAuthToken === "string" ? rawAuthToken : DEFAULT_CONFIG.authToken,
|
|
37
|
+
remoteImages: typeof rawRemoteImages === "boolean" ? rawRemoteImages : DEFAULT_CONFIG.remoteImages,
|
|
38
|
+
maxBodySizeMb: clampInt(v["maxBodySizeMb"], 1, 500, DEFAULT_CONFIG.maxBodySizeMb),
|
|
39
|
+
upstreamTimeoutSec: clampInt(v["upstreamTimeoutSec"], 5, 600, DEFAULT_CONFIG.upstreamTimeoutSec),
|
|
40
|
+
lifetime: v["lifetime"] === "session" ? "session" : "detached"
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function getConfigPath() {
|
|
44
|
+
return resolve(process.env["PI_CODING_AGENT_DIR"] ?? resolve(process.env["HOME"] ?? "~", ".pi", "agent"), "proxy-config.json");
|
|
45
|
+
}
|
|
46
|
+
function loadConfigFromFile() {
|
|
47
|
+
const p = getConfigPath();
|
|
48
|
+
if (!existsSync(p)) return { ...DEFAULT_CONFIG };
|
|
49
|
+
try {
|
|
50
|
+
return normalizeConfig(JSON.parse(readFileSync(p, "utf-8")));
|
|
51
|
+
} catch {
|
|
52
|
+
return { ...DEFAULT_CONFIG };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function saveConfigToFile(config) {
|
|
56
|
+
const p = getConfigPath();
|
|
57
|
+
const normalized = normalizeConfig(config);
|
|
58
|
+
const tmp = `${p}.tmp`;
|
|
59
|
+
try {
|
|
60
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
61
|
+
writeFileSync(tmp, `${JSON.stringify(normalized, null, " ")}\n`, "utf-8");
|
|
62
|
+
renameSync(tmp, p);
|
|
63
|
+
} catch {
|
|
64
|
+
if (existsSync(tmp)) unlinkSync(tmp);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function configToEnv(config) {
|
|
68
|
+
const env = {};
|
|
69
|
+
env["PI_PROXY_HOST"] = config.host;
|
|
70
|
+
env["PI_PROXY_PORT"] = String(config.port);
|
|
71
|
+
if (config.authToken.length > 0) env["PI_PROXY_AUTH_TOKEN"] = config.authToken;
|
|
72
|
+
env["PI_PROXY_REMOTE_IMAGES"] = String(config.remoteImages);
|
|
73
|
+
env["PI_PROXY_MAX_BODY_SIZE"] = String(config.maxBodySizeMb * 1024 * 1024);
|
|
74
|
+
env["PI_PROXY_UPSTREAM_TIMEOUT_MS"] = String(config.upstreamTimeoutSec * 1e3);
|
|
75
|
+
return env;
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
export { DEFAULT_CONFIG, configToEnv, getConfigPath, loadConfigFromFile, normalizeConfig, saveConfigToFile };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* pi-openai-proxy entry point.
|
|
5
|
-
*
|
|
6
|
-
* Initializes the pi model registry, creates the Hono app, and starts serving.
|
|
7
|
-
* Implements graceful shutdown on SIGTERM/SIGINT.
|
|
8
|
-
*/
|
|
9
|
-
declare const server: Bun.Server<undefined>;
|
|
10
|
-
//#endregion
|
|
11
|
-
export { server as default };
|
|
2
|
+
export { };
|