Diff
1diff --git a/README.md b/README.md
2index 80565ced77f2cc5a71db936f23e052111f96fb1c..b3e058812775ab905697ef29c73587272b596454 100644
3--- a/README.md
4+++ b/README.md
5@@ -32,6 +32,13 @@ pi -e ~/code/pi-llama/index.ts
6 `-e` loads the extension only for the current session, useful while
7 developing.
8
9+## Environment Variables
10+
11+This extension supports the following environment variables:
12+
13+- LLAMA_BASE_URL (Default: `http://localhost:8080/v1`)
14+- LLAMA_API_KEY (Default: `no-key`)
15+
16 ## Usage
17
18 ```bash
19@@ -41,6 +48,9 @@ curl -LsSf https://llama.app/install.sh | bash
20 # 2. Start the server
21 llama serve
22
23+# Optional: Use a remote instance of llama.cpp server instead of local
24+export LLAMA_BASE_URL="https://llama.example.com/v1"
25+
26 # 3. Launch pi in another terminal
27 pi
28
29diff --git a/index.ts b/index.ts
30index c0eb0dc076d6b73333209418bf442052042dc3ae..777a9ed8c51605ff637a6bd0ab71ab373c78757c 100644
31--- a/index.ts
32+++ b/index.ts
33@@ -60,6 +60,7 @@ const PropsResponseSchema = Type.Object({
34 }),
35 ),
36 chat_template: Type.Optional(Type.String()),
37+ build_info: Type.Optional(Type.String()),
38 });
39
40 const validatePropsResponse = Compile(PropsResponseSchema);
41@@ -98,18 +99,30 @@ export default async function (pi: ExtensionAPI) {
42 let currentModels: LlamaModel[] = [];
43
44 pi.registerCommand("llama-version", {
45- description: "Print llama-server --version output",
46+ description: "Get build info of llama.cpp server",
47 handler: async (_args, ctx) => {
48- const result = await pi.exec("llama-server", ["--version"]);
49- const output = `${result.stderr ?? ""}\n${result.stdout ?? ""}`;
50- const versionLine = output
51- .split("\n")
52- .map((l) => l.trim())
53- .find((l) => /^version:\s/i.test(l));
54- ctx.ui.notify(
55- versionLine ?? `llama-server exited with code ${result.code}`,
56- versionLine ? "info" : "error",
57- );
58+ const response = await fetch(`${baseUrl.replace(/\/v1$/, "")}/props`);
59+ if (!response.ok) {
60+ ctx.ui.notify(`[llama-cpp] /props returned ${response.status}`, "error");
61+ return;
62+ }
63+
64+ const data: unknown = await response.json();
65+ if (!validatePropsResponse.Check(data)) {
66+ const errors = [...validatePropsResponse.Errors(data)]
67+ .map((e) => `${"path" in e ? e.path : ""} ${e.message}`)
68+ .join("; ");
69+ ctx.ui.notify(`[llama-cpp] invalid /props response: ${errors}`, "error");
70+ return;
71+ }
72+
73+ const match = data.build_info?.match(/^b([a-zA-Z0-9]+)-([a-zA-Z0-9]+)$/);
74+
75+ if (match && match.length === 3) {
76+ ctx.ui.notify(`Build number: ${match[1]}, Commit hash: ${match[2]}`, "info");
77+ } else {
78+ ctx.ui.notify(`Malformed build info: ${data.build_info}`, "warning");
79+ }
80 },
81 });
82