pi-llama-cpp 0.2.0 → 0.2.1

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 +23 -16
  2. package/package.json +1 -1
  3. package/src/handlers.ts +68 -16
package/README.md CHANGED
@@ -6,20 +6,21 @@ A [Pi Coding Agent](https://pi.dev/) extension that integrates with a running [l
6
6
 
7
7
  - **Auto-detect models** — discovers all models available on your running llama.cpp server
8
8
  - **Live status indicators** — see which models are loaded, loading, failed, sleeping, or unloaded with color-coded icons
9
-
10
- | Icon | Status | Description |
11
- |------|--------|-------------|
12
- | 🟢 | Loaded | Model is active and ready to use |
13
- | 🟡 | Loading | Model is currently being loaded |
14
- | 🔴 | Failed | Model failed to load |
15
- | 🔵 | Sleeping | Model is loaded but inactive (router mode) |
16
- | ⚪ | Unloaded | Model is not loaded on the server |
17
-
18
9
  - **Load / unload / switch** — manage models directly from the Pi command palette
19
10
  - **Multi-model router support** — works with both single-model and multi-model llama.cpp server configurations
20
- - **Image model support** — detects multimodal models automatically
11
+ - **Image capabilities detection** — detects multimodal models automatically
21
12
  - **Flexible URL resolution** — configures the server URL via project config, environment variable, or global settings
22
13
 
14
+ ### Status Indicators
15
+
16
+ | Icon | Status | Description |
17
+ |------|--------|-------------|
18
+ | 🟢 | Loaded | Model is active and ready to use |
19
+ | 🟡 | Loading | Model is currently being loaded |
20
+ | 🔴 | Failed | Model failed to load |
21
+ | 🔵 | Sleeping | Model is loaded but inactive (router mode) |
22
+ | ⚪ | Unloaded | Model is not loaded on the server |
23
+
23
24
  ## Installation
24
25
 
25
26
  This package is a Pi extension. Install it with
@@ -60,9 +61,9 @@ The extension resolves the llama.cpp server URL using the following priority ord
60
61
 
61
62
  ### API Key
62
63
 
63
- If your llama.cpp server requires authentication, use `/login` in Pi, select the "API key" option, and choose the `Llama.cpp` provider.
64
+ If your llama.cpp server requires authentication, use `/login` in Pi, select the "API key" option, and choose the `Llama.cpp` provider from the list.
64
65
 
65
- Alternatively, configure the API key in `~/.pi/agent/auth.json`:
66
+ Alternatively, configure the API key in `~/.pi/agent/auth.json` using the provider ID `llama-server`:
66
67
 
67
68
  ```json
68
69
  {
@@ -77,15 +78,17 @@ Alternatively, configure the API key in `~/.pi/agent/auth.json`:
77
78
 
78
79
  ### Prerequisites
79
80
 
80
- Make sure your llama.cpp server is running with the appropriate flags. For multi-model support (model router), start the server with:
81
+ Make sure your llama.cpp server is running with the appropriate flags.
82
+
83
+ - For multi-model support (model router), start the server with:
81
84
 
82
85
  ```bash
83
- llama-server --models-preset path/to/presets.ini
86
+ llama-server --models-preset path/to/presets.ini ...
84
87
  ```
85
88
 
86
- (You can use both `--fit-ctx` and `--ctx-size` in the preset the extension checks both.)
89
+ The extension reads the context size from the preset file using the `ctx-size` and/or `fit-ctx` keys.
87
90
 
88
- For single-model mode, a standard invocation works:
91
+ - For single-model mode, start the server with:
89
92
 
90
93
  ```bash
91
94
  llama-server --model path/to/model.gguf --ctx-size 128000 ...
@@ -97,6 +100,8 @@ llama-server --model path/to/model.gguf --ctx-size 128000 ...
97
100
  | --------- | ------------------------------------------------------------------------------------------ |
98
101
  | `/models` | Browse your models with live status. Select a model to load, switch, or unload it. |
99
102
 
103
+ > **Note:** When the llama.cpp server is unreachable, `/models` is still available but displays an error notification with the configured server URL.
104
+
100
105
  ### Model Actions
101
106
 
102
107
  When browsing models via the `/models` command, you can:
@@ -108,6 +113,8 @@ When browsing models via the `/models` command, you can:
108
113
  - **Info** — View model details (ID, capabilities, context size)
109
114
  - **Cancel** — Cancel the current operation
110
115
 
116
+ > **Note:** In single-model mode, only **Info** and **Cancel** are available, since there is only one model loaded on the server.
117
+
111
118
  ### Model Selection Event
112
119
 
113
120
  When Pi switches models (via `model_select`), the extension automatically loads the selected model on the llama.cpp server. This keeps the server in sync with the active model in Pi.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-llama-cpp",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Pi extension for llama.cpp integration. Supports both router and single modes",
5
5
  "keywords": [
6
6
  "pi",
package/src/handlers.ts CHANGED
@@ -9,25 +9,30 @@ import { Status } from "./enums/status";
9
9
  import { BaseModel } from "./models/baseModel";
10
10
 
11
11
  /**
12
- * Defines a handler when llama-server is running
12
+ * Select a model from the list. Returns null if user cancels.
13
+ *
13
14
  * @param ctx Pi context
14
- * @returns The action and model, if detected
15
+ * @param models A list of models
16
+ * @returns The selected model
15
17
  */
16
- const modelSelectionHandler = async (
18
+ const selectModel = async (
17
19
  ctx: ExtensionCommandContext,
18
20
  models: BaseModel[],
19
- ): Promise<{ action: Action; model: BaseModel } | null> => {
20
- // Setup the labels
21
+ ): Promise<BaseModel | null> => {
21
22
  const labels = await Promise.all(models.map((m) => m.getLabel()));
22
-
23
- // Detect the selected model
24
23
  const choice = await ctx.ui.select(`${PROVIDER_NAME} models:`, labels);
25
24
  if (!choice) return null;
26
-
27
25
  const idx = labels.indexOf(choice);
28
- const model = models[idx];
26
+ return models[idx];
27
+ };
29
28
 
30
- // Router mode actions
29
+ /**
30
+ * Get available actions for a model based on its mode and status.
31
+ *
32
+ * @param model The selected model
33
+ * @returns
34
+ */
35
+ const getActionsForModel = async (model: BaseModel): Promise<Array<Action>> => {
31
36
  const routerModeActions: Record<Status, Array<Action>> = {
32
37
  [Status.LOADED]: [Action.SWITCH, Action.UNLOAD, Action.INFO, Action.CANCEL],
33
38
  [Status.LOADING]: [Action.CANCEL],
@@ -36,7 +41,6 @@ const modelSelectionHandler = async (
36
41
  [Status.UNLOADED]: [Action.LOAD, Action.CANCEL],
37
42
  };
38
43
 
39
- // Single mode actions (more limited)
40
44
  const singleModeActions: Record<Status, Array<Action>> = {
41
45
  [Status.LOADED]: [Action.INFO, Action.CANCEL],
42
46
  [Status.LOADING]: [Action.CANCEL],
@@ -45,21 +49,69 @@ const modelSelectionHandler = async (
45
49
  [Status.UNLOADED]: [Action.CANCEL],
46
50
  };
47
51
 
48
- // Define the actions that the user can do
49
52
  const allActions =
50
53
  model.mode === Mode.ROUTER ? routerModeActions : singleModeActions;
51
54
 
52
55
  const status = await model.getStatus();
53
- const actions = allActions[status];
56
+ return allActions[status];
57
+ };
58
+
59
+ /**
60
+ * Selects an action for a model.
61
+ *
62
+ * @param ctx Pi context
63
+ * @param model The selected model
64
+ * @param actions Possible actions to execute
65
+ * @returns The action, or null if user cancels
66
+ */
67
+ const selectAction = async (
68
+ ctx: ExtensionCommandContext,
69
+ model: BaseModel,
70
+ actions: Array<Action>,
71
+ ): Promise<Action | null> => {
72
+ const labels = actions.map((a) => String(a));
73
+ const choice = await ctx.ui.select(`${model.name}`, labels);
74
+ if (!choice) return null;
54
75
 
55
- const action = (await ctx.ui.select(`${model.name}`, actions)) as Action;
76
+ const idx = labels.indexOf(choice);
77
+ return actions[idx];
78
+ };
56
79
 
57
- // Send the selected action with the corresponding model
58
- return { action, model };
80
+ /**
81
+ * Handles the menu for model selection
82
+ * Loops: select model → select action → handle action.
83
+ *
84
+ * Escape on actions menu goes back to model selection.
85
+ * Escape on model selection exits.
86
+ *
87
+ * @param ctx Pi context
88
+ * @returns The action and model, if detected
89
+ */
90
+ const modelSelectionHandler = async (
91
+ ctx: ExtensionCommandContext,
92
+ models: BaseModel[],
93
+ ): Promise<{ action: Action; model: BaseModel } | null> => {
94
+ while (true) {
95
+ // Select the model
96
+ const model = await selectModel(ctx, models);
97
+ if (!model) return null;
98
+
99
+ // Select the action
100
+ const actions = await getActionsForModel(model);
101
+ const action = await selectAction(ctx, model, actions);
102
+ if (action === null) {
103
+ // Escape key pressed => back to model selection
104
+ continue;
105
+ }
106
+
107
+ // Return the selected action and model
108
+ return { action, model };
109
+ }
59
110
  };
60
111
 
61
112
  /**
62
113
  * Handles the /models command
114
+ *
63
115
  * @param ctx The context used by Pi
64
116
  * @param pi The Pi extension
65
117
  */