4410635afdf38432d9a6d737e0fdefaf1295012d

Author
TheEdgeOfRage <git@theedgeofrage.com>
Committer
TheEdgeOfRage <git@theedgeofrage.com>
Date

Message

Add llama base URL to config options

Diff

  1diff --git a/README.md b/README.md
  2index eebc531869308291c084e9fa8caa4d28fd45cfe3..137ab18c2d1cbba081ead6641c85fa9a89a04e3f 100644
  3--- a/README.md
  4+++ b/README.md
  5@@ -42,13 +42,14 @@ Use `~/.pi/agent/extensions/pi-llama.json` for global settings or
  6 
  7 ```json
  8 {
  9-  "autoloadOnSelect": false
 10+  "autoloadOnSelect": false,
 11+  "baseUrl": "http://localhost:8080/v1"
 12 }
 13 ```
 14 
 15 Project settings override global settings. Set `autoloadOnSelect` to `true` to
 16-restore loading on model selection. Restart pi or run `/reload` after changing
 17-configuration.
 18+restore loading on model selection. `LLAMA_BASE_URL` overrides the configured
 19+`baseUrl`. Restart pi or run `/reload` after changing configuration.
 20 
 21 ## Environment Variables
 22 
 23diff --git a/index.ts b/index.ts
 24index 63de5dafe5a0409e8377b13ee95cba903c6f7bfb..4018d36e669aaab191e05b5ecd13e75b25c9dd28 100644
 25--- a/index.ts
 26+++ b/index.ts
 27@@ -27,12 +27,18 @@ const CONFIG_FILE_NAME = "pi-llama.json";
 28 
 29 type LlamaConfig = {
 30 	autoloadOnSelect?: boolean;
 31+	baseUrl?: string;
 32 };
 33 
 34 const DEFAULT_CONFIG: Required<LlamaConfig> = {
 35 	autoloadOnSelect: false,
 36+	baseUrl: DEFAULT_BASE_URL,
 37 };
 38 
 39+function normalizeBaseUrl(url: string): string {
 40+	return url.replace(/\/+$/, "");
 41+}
 42+
 43 function readConfig(path: string): LlamaConfig {
 44 	if (!existsSync(path)) {
 45 		return {};
 46@@ -44,8 +50,15 @@ function readConfig(path: string): LlamaConfig {
 47 			throw new Error("expected a JSON object");
 48 		}
 49 
 50-		const autoloadOnSelect = (value as Record<string, unknown>).autoloadOnSelect;
 51-		return typeof autoloadOnSelect === "boolean" ? { autoloadOnSelect } : {};
 52+		const config = value as Record<string, unknown>;
 53+		const result: LlamaConfig = {};
 54+		if (typeof config.autoloadOnSelect === "boolean") {
 55+			result.autoloadOnSelect = config.autoloadOnSelect;
 56+		}
 57+		if (typeof config.baseUrl === "string" && config.baseUrl.trim()) {
 58+			result.baseUrl = normalizeBaseUrl(config.baseUrl.trim());
 59+		}
 60+		return result;
 61 	} catch (error) {
 62 		console.warn(`[llama-cpp] failed to read config ${path}: ${(error as Error).message}`);
 63 		return {};
 64@@ -57,8 +70,12 @@ function loadConfig(cwd: string, projectIsTrusted: boolean): Required<LlamaConfi
 65 	const projectConfig = projectIsTrusted
 66 		? readConfig(join(cwd, CONFIG_DIR_NAME, CONFIG_FILE_NAME))
 67 		: {};
 68+	const config = { ...DEFAULT_CONFIG, ...globalConfig, ...projectConfig };
 69 
 70-	return { ...DEFAULT_CONFIG, ...globalConfig, ...projectConfig };
 71+	return {
 72+		...config,
 73+		baseUrl: normalizeBaseUrl(process.env.LLAMA_BASE_URL ?? config.baseUrl),
 74+	};
 75 }
 76 
 77 const ModelsResponseSchema = Type.Object({
 78@@ -178,7 +195,8 @@ function isStaleContextError(error: unknown): boolean {
 79 
 80 export default async function (pi: ExtensionAPI) {
 81 	let currentModels: LlamaModel[] = [];
 82-	let autoloadOnSelect = DEFAULT_CONFIG.autoloadOnSelect;
 83+	let config = loadConfig(process.cwd(), false);
 84+	let autoloadOnSelect = config.autoloadOnSelect;
 85 
 86 	pi.registerCommand("llama-version", {
 87 		description: "Get build info of llama.cpp server",
 88@@ -208,7 +226,7 @@ export default async function (pi: ExtensionAPI) {
 89 		},
 90 	});
 91 
 92-	const baseUrl = (process.env.LLAMA_BASE_URL ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
 93+	let baseUrl = config.baseUrl;
 94 	const apiKey = process.env.LLAMA_API_KEY ?? "no-key";
 95 
 96 	async function refreshProvider(): Promise<void> {
 97@@ -591,8 +609,13 @@ export default async function (pi: ExtensionAPI) {
 98 		}
 99 	}
100 
101-	pi.on("session_start", (_event, ctx) => {
102-		autoloadOnSelect = loadConfig(ctx.cwd, ctx.isProjectTrusted()).autoloadOnSelect;
103+	pi.on("session_start", async (_event, ctx) => {
104+		config = loadConfig(ctx.cwd, ctx.isProjectTrusted());
105+		autoloadOnSelect = config.autoloadOnSelect;
106+		if (baseUrl !== config.baseUrl) {
107+			baseUrl = config.baseUrl;
108+			await refreshProvider();
109+		}
110 	});
111 
112 	await refreshProvider();