pi-ollama-cloud 0.4.1 → 0.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/CHANGELOG.md +17 -0
- package/README.md +34 -13
- package/config.ts +130 -0
- package/index.ts +114 -19
- package/models.generated.ts +1353 -0
- package/models.ts +86 -108
- package/package.json +11 -5
- package/thinking-levels.ts +1 -1
- package/web-tools.ts +52 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.5.0] - 2026-05-22
|
|
6
|
+
|
|
7
|
+
- Update `peerDependencies` and imports to the new `@earendil-works/*` packages.
|
|
8
|
+
- Add build script (`scripts/generate-models.ts`) to generate `models.generated.ts` with Ollama Cloud tool-capable models from live API data. The script requires no API key.
|
|
9
|
+
- Drop `FALLBACK_MODELS` in favor of `GENERATED_MODELS` which ships with the package.
|
|
10
|
+
- Remove `apiKey` requirement from `fetchModelIds` and `fetchModelDetails`. Ollama Cloud's public `/v1/models` and `/api/show` endpoints do not require authentication for model metadata. (#15)
|
|
11
|
+
- Remove `getOllamaCloudApiKey`, `refreshModelsFromAuth`, and the "No API key found" notification path from `fetchModels`. Users can now browse model metadata without configuring a key.
|
|
12
|
+
- Remove `401`/`403` error handling from the model metadata fetch functions.
|
|
13
|
+
- Add configuration system (`config.ts`) with JSON config files (global + project-local) and `/ollama-webtools` command for runtime web tools toggling.
|
|
14
|
+
- Add test infrastructure (`vitest`) and model validation tests (`test/models.test.ts`).
|
|
15
|
+
- Add HTTP status-aware error handling in web tools (`401`/`403` → auth error, `429` → rate limit).
|
|
16
|
+
- Add explicit `buildCompat()` with all 17 `OpenAICompletionsCompat` flags set explicitly, verified against Ollama API docs.
|
|
17
|
+
- Set the provider display name to `Ollama Cloud` so it reads cleanly in `/login`, `/model`, and the model selector.
|
|
18
|
+
- Document `/login` as the recommended way to configure the API key.
|
|
19
|
+
- Update README to clarify baked-in model list and refresh behavior.
|
|
20
|
+
- Document web-tools.ts module boundaries in file header comment.
|
|
21
|
+
|
|
5
22
|
## [0.4.1] - 2026-05-07
|
|
6
23
|
|
|
7
24
|
- Add `renderCall` to `ollama_web_search` and `ollama_web_fetch` tools so the TUI displays the query/URL in the tool call header instead of just the bare tool name. (#12)
|
package/README.md
CHANGED
|
@@ -8,8 +8,9 @@ Registers Ollama Cloud as a model provider with dynamically fetched models, and
|
|
|
8
8
|
|
|
9
9
|
- **Dynamic model discovery** - Fetches the full model list from `ollama.com/v1/models`, then fetches per-model details via `/api/show` to determine capabilities, context length, and tool support.
|
|
10
10
|
- **Curated thinking levels** - Maps Pi's thinking levels to Ollama Cloud's OpenAI-compatible `reasoning_effort` values via `thinking-levels.ts`, with per-model exceptions based on API testing.
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
11
|
+
- **Baked-in model list** - A generated model list (`models.generated.ts`) ships with the extension so models are available immediately on first launch without any network calls. Updated by running `npm run generate-models` and releasing a new version.
|
|
12
|
+
- **Persistent cache** - Running `/ollama-cloud-refresh` fetches the latest models from the API and caches them to `~/.pi/agent/cache/ollama-cloud-models.json`. On subsequent launches, this disk cache takes precedence over the baked-in list.
|
|
13
|
+
- **Auto-refresh on stale cache** - When the disk cache is older than 30 days, the extension uses it immediately and shows a visible refresh progress widget on the next `session_start` to pull in any new models.
|
|
13
14
|
- **`/ollama-cloud-refresh` command** - Re-fetches the model list and updates the cache and provider registration live (no restart needed).
|
|
14
15
|
- **`ollama_web_search` tool** - Search the web for real-time information using Ollama Cloud's `/api/web_search` endpoint. Returns titles, URLs, and content snippets.
|
|
15
16
|
- **`ollama_web_fetch` tool** - Fetch and extract text content from a web page URL using Ollama Cloud's `/api/web_fetch` endpoint. Returns page title, content, and links.
|
|
@@ -65,13 +66,15 @@ Sign up at [ollama.com](https://ollama.com) and generate an API key.
|
|
|
65
66
|
|
|
66
67
|
### 2. Configure the API key
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
The simplest way is the `/login` command inside Pi: run `/login`, choose **Use an API key**, pick **Ollama Cloud**, and paste your key. Pi stores it in `~/.pi/agent/auth.json` and `/logout` removes it.
|
|
70
|
+
|
|
71
|
+
Alternatively, set the `OLLAMA_API_KEY` environment variable:
|
|
69
72
|
|
|
70
73
|
```bash
|
|
71
74
|
export OLLAMA_API_KEY="your-key"
|
|
72
75
|
```
|
|
73
76
|
|
|
74
|
-
Or add it to `~/.pi/agent/auth.json
|
|
77
|
+
Or add it to `~/.pi/agent/auth.json` by hand:
|
|
75
78
|
|
|
76
79
|
```json
|
|
77
80
|
{
|
|
@@ -82,19 +85,36 @@ Or add it to `~/.pi/agent/auth.json`:
|
|
|
82
85
|
}
|
|
83
86
|
```
|
|
84
87
|
|
|
85
|
-
### 3.
|
|
88
|
+
### 3. Configure the extension (optional)
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
Extension settings can be set via JSON config files. Project-local settings override global/user-level settings.
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
| Location | Scope |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `~/.pi/agent/ollama-cloud.json` | Global / user-level (all projects) |
|
|
95
|
+
| `.pi/ollama-cloud.json` | Project-local (takes precedence) |
|
|
96
|
+
|
|
97
|
+
**Available settings:**
|
|
98
|
+
|
|
99
|
+
| Setting | Type | Default | Description |
|
|
100
|
+
|---|---|---|---|
|
|
101
|
+
| `webTools` | boolean | `true` | Set to `false` to prevent `ollama_web_search` and `ollama_web_fetch` from being registered |
|
|
102
|
+
|
|
103
|
+
Example `ollama-cloud.json`:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"webTools": false
|
|
108
|
+
}
|
|
91
109
|
```
|
|
92
110
|
|
|
93
|
-
|
|
111
|
+
The `PI_OLLAMA_WEB_TOOLS` environment variable still works as an override above config files. Set it to `0`, `false`, `no`, or `off` to disable web tools regardless of config file settings.
|
|
112
|
+
|
|
113
|
+
### 4. Fetch models (optional)
|
|
94
114
|
|
|
95
|
-
|
|
115
|
+
On first launch the plugin uses a baked-in model list shipped with the extension — no network calls needed. If you want the very latest models, run `/ollama-cloud-refresh` to fetch from the API and cache the result to disk. After that, the disk cache is used on subsequent launches.
|
|
96
116
|
|
|
97
|
-
|
|
117
|
+
If the disk cache is older than 30 days, the extension uses it immediately and runs a visible refresh on the next session start (progress appears in the UI widget). You can also run:
|
|
98
118
|
|
|
99
119
|
```
|
|
100
120
|
/ollama-cloud-refresh
|
|
@@ -115,7 +135,7 @@ The plugin uses two Ollama Cloud API endpoints to build the model list:
|
|
|
115
135
|
|
|
116
136
|
Only models with the `tools` capability are registered - these are the ones Pi can use for tool-calling.
|
|
117
137
|
|
|
118
|
-
The raw `/api/show` responses are cached at `~/.pi/agent/cache/ollama-cloud-models.json` with a top-level `timestamp` value. If that local cache is older than 30 days, the plugin keeps using it immediately and
|
|
138
|
+
The raw `/api/show` responses are cached at `~/.pi/agent/cache/ollama-cloud-models.json` with a top-level `timestamp` value. If that local cache is older than 30 days, the plugin keeps using it immediately and runs a visible refresh on `session_start` (progress appears in the UI widget). If the cache is missing, the plugin uses the baked-in model list shipped with the extension (`models.generated.ts`).
|
|
119
139
|
|
|
120
140
|
Model metadata is derived from the cached data:
|
|
121
141
|
|
|
@@ -163,6 +183,7 @@ Both tools use the same Ollama Cloud API key configured for the provider. No loc
|
|
|
163
183
|
| Command | Description |
|
|
164
184
|
|---|---|
|
|
165
185
|
| `/ollama-cloud-refresh` | Fetch models from the Ollama Cloud API, update cache, and re-register the provider |
|
|
186
|
+
| `/ollama-webtools [on\|off\|enable\|disable]` | Enable or disable the `ollama_web_search` and `ollama_web_fetch` tools. Toggles if no argument given. |
|
|
166
187
|
|
|
167
188
|
## Development
|
|
168
189
|
|
|
@@ -220,5 +241,5 @@ Each publish also gets automatic [provenance attestation](https://docs.npmjs.com
|
|
|
220
241
|
|
|
221
242
|
## Notes
|
|
222
243
|
|
|
223
|
-
- The extension sets `supportsDeveloperRole: false` on all models so the system prompt always uses `role: "system"`. Without this, pi sends the prompt as `role: "developer"` for thinking-capable models, which some models (e.g. GLM-5.1) ignore entirely - the prompt simply isn't read.
|
|
224
244
|
- The fetch timeout is 10 seconds per request. On slow connections, some model detail fetches may time out - the plugin reports how many succeeded vs failed.
|
|
245
|
+
- `deepseek-v4` occasionally emits raw `<|DSML|tool_calls|>` markup as plain text instead of structured tool calls, then stops. This is DeepSeek's native tool-call format leaking through Ollama Cloud's OpenAI-compatible endpoint, so it looks like an upstream Ollama issue rather than something this extension can fix. If you hit it, retry or switch models.
|
package/config.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loader for pi-ollama-cloud.
|
|
3
|
+
*
|
|
4
|
+
* Reads settings from JSON config files with project-over-global precedence:
|
|
5
|
+
* - ~/.pi/agent/ollama-cloud.json (global / user-level)
|
|
6
|
+
* - .pi/ollama-cloud.json (project-local, takes precedence)
|
|
7
|
+
*
|
|
8
|
+
* Environment variables serve as overrides above both config files:
|
|
9
|
+
* - PI_OLLAMA_WEB_TOOLS=0 disables web tool registration
|
|
10
|
+
*
|
|
11
|
+
* Example ollama-cloud.json:
|
|
12
|
+
* ```json
|
|
13
|
+
* {
|
|
14
|
+
* "webTools": false
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
22
|
+
|
|
23
|
+
// --- Types ---
|
|
24
|
+
|
|
25
|
+
export interface OllamaCloudConfig {
|
|
26
|
+
/** When false, ollama_web_search and ollama_web_fetch tools are not registered. Default: true. */
|
|
27
|
+
webTools?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// --- Defaults ---
|
|
31
|
+
|
|
32
|
+
const DEFAULT_CONFIG: OllamaCloudConfig = {
|
|
33
|
+
webTools: true,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// --- Validation ---
|
|
37
|
+
|
|
38
|
+
/** Allowed config keys and their expected types for runtime validation. */
|
|
39
|
+
const CONFIG_SCHEMA: Record<keyof OllamaCloudConfig, "boolean"> = {
|
|
40
|
+
webTools: "boolean",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Validate a parsed JSON object against the known schema.
|
|
45
|
+
* Unknown keys are silently dropped; values with wrong types fall back to undefined.
|
|
46
|
+
*/
|
|
47
|
+
function sanitizeConfig(raw: Record<string, unknown>): OllamaCloudConfig {
|
|
48
|
+
const out: OllamaCloudConfig = {};
|
|
49
|
+
for (const [key, expectedType] of Object.entries(CONFIG_SCHEMA)) {
|
|
50
|
+
const value = raw[key];
|
|
51
|
+
if (typeof value === expectedType) {
|
|
52
|
+
(out as Record<string, unknown>)[key] = value;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// --- Loader ---
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Load configuration from JSON files.
|
|
62
|
+
* Project-local config overrides global config.
|
|
63
|
+
* Environment variables override both.
|
|
64
|
+
*/
|
|
65
|
+
export function loadConfig(cwd: string): OllamaCloudConfig {
|
|
66
|
+
const globalPath = join(getAgentDir(), "ollama-cloud.json");
|
|
67
|
+
const projectPath = join(cwd, ".pi", "ollama-cloud.json");
|
|
68
|
+
|
|
69
|
+
let globalConfig: OllamaCloudConfig = {};
|
|
70
|
+
let projectConfig: OllamaCloudConfig = {};
|
|
71
|
+
|
|
72
|
+
// Load global config
|
|
73
|
+
if (existsSync(globalPath)) {
|
|
74
|
+
try {
|
|
75
|
+
const content = readFileSync(globalPath, "utf-8");
|
|
76
|
+
const parsed = JSON.parse(content);
|
|
77
|
+
// Silently skip files that parse to null, arrays, or primitives —
|
|
78
|
+
// malformed config should not crash the extension (defaults apply).
|
|
79
|
+
if (parsed != null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
80
|
+
globalConfig = sanitizeConfig(parsed as Record<string, unknown>);
|
|
81
|
+
}
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.error(`[pi-ollama-cloud] Failed to load config from ${globalPath}: ${err}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Load project config
|
|
88
|
+
if (existsSync(projectPath)) {
|
|
89
|
+
try {
|
|
90
|
+
const content = readFileSync(projectPath, "utf-8");
|
|
91
|
+
const parsed = JSON.parse(content);
|
|
92
|
+
// Same guard as global config: null/array/primitive parses are ignored.
|
|
93
|
+
if (parsed != null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
94
|
+
projectConfig = sanitizeConfig(parsed as Record<string, unknown>);
|
|
95
|
+
}
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.error(`[pi-ollama-cloud] Failed to load config from ${projectPath}: ${err}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Merge with defaults: defaults < global < project
|
|
102
|
+
const merged: OllamaCloudConfig = {
|
|
103
|
+
...DEFAULT_CONFIG,
|
|
104
|
+
...globalConfig,
|
|
105
|
+
...projectConfig,
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// Environment variable overrides (only webTools for now)
|
|
109
|
+
const envOverride = resolveWebToolsEnv();
|
|
110
|
+
if (envOverride !== undefined) {
|
|
111
|
+
merged.webTools = envOverride;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return merged;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Resolve the PI_OLLAMA_WEB_TOOLS environment variable override.
|
|
119
|
+
* Returns undefined when not set (no override),
|
|
120
|
+
* true/false when explicitly set.
|
|
121
|
+
*/
|
|
122
|
+
export function resolveWebToolsEnv(): boolean | undefined {
|
|
123
|
+
const raw = process.env.PI_OLLAMA_WEB_TOOLS;
|
|
124
|
+
if (raw === undefined) return undefined;
|
|
125
|
+
|
|
126
|
+
const lowered = raw.toLowerCase();
|
|
127
|
+
if (["0", "false", "no", "off", ""].includes(lowered)) return false;
|
|
128
|
+
// Treat any other non-empty value as "enabled"
|
|
129
|
+
return true;
|
|
130
|
+
}
|
package/index.ts
CHANGED
|
@@ -17,16 +17,21 @@
|
|
|
17
17
|
* Raw /api/show responses are cached at <agentDir>/cache/ollama-cloud-models.json
|
|
18
18
|
* so the provider assembly can be debugged and re-derived without re-fetching.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* Startup behavior:
|
|
21
|
+
* - Missing cache: uses baked-in GENERATED_MODELS (manually generated via
|
|
22
|
+
* `npm run generate-models` and committed to the repo).
|
|
23
|
+
* - Stale cache (>30 days): uses the cached data immediately and triggers a visible refresh
|
|
24
|
+
* on session_start that shows progress in the UI widget.
|
|
25
|
+
* - Fresh cache: uses cached data directly, no refresh triggered.
|
|
22
26
|
*
|
|
23
27
|
* Only models with "tools" capability are registered.
|
|
24
28
|
*/
|
|
25
29
|
|
|
26
|
-
import type { ExtensionAPI, ExtensionCommandContext, ProviderModelConfig } from "@
|
|
30
|
+
import type { ExtensionAPI, ExtensionCommandContext, ProviderModelConfig } from "@earendil-works/pi-coding-agent";
|
|
31
|
+
import { loadConfig, resolveWebToolsEnv } from "./config.ts";
|
|
32
|
+
import { GENERATED_MODELS } from "./models.generated.ts";
|
|
27
33
|
import {
|
|
28
34
|
assembleModels,
|
|
29
|
-
FALLBACK_MODELS,
|
|
30
35
|
fetchModels,
|
|
31
36
|
OLLAMA_BASE,
|
|
32
37
|
type RefreshProgress,
|
|
@@ -35,20 +40,11 @@ import {
|
|
|
35
40
|
} from "./models.ts";
|
|
36
41
|
import { registerWebFetchTool, registerWebSearchTool } from "./web-tools.ts";
|
|
37
42
|
|
|
38
|
-
/**
|
|
39
|
-
* Opt-out flag for the ollama_web_search and ollama_web_fetch tools.
|
|
40
|
-
* When the value is one of "0", "false", "no", "off", or the empty string,
|
|
41
|
-
* both web tool registrations are skipped. The model provider and
|
|
42
|
-
* /ollama-cloud-refresh command remain active regardless.
|
|
43
|
-
*/
|
|
44
|
-
const PI_OWT_RAW = process.env.PI_OLLAMA_WEB_TOOLS;
|
|
45
|
-
const WEB_TOOLS_DISABLED =
|
|
46
|
-
PI_OWT_RAW !== undefined && ["0", "false", "no", "off", ""].includes(PI_OWT_RAW.toLowerCase());
|
|
47
|
-
|
|
48
43
|
// --- Registrations ---
|
|
49
44
|
|
|
50
45
|
function registerProvider(pi: ExtensionAPI, models: ProviderModelConfig[]) {
|
|
51
46
|
pi.registerProvider("ollama-cloud", {
|
|
47
|
+
name: "Ollama Cloud",
|
|
52
48
|
baseUrl: `${OLLAMA_BASE}/v1`,
|
|
53
49
|
apiKey: "OLLAMA_API_KEY",
|
|
54
50
|
api: "openai-completions",
|
|
@@ -124,8 +120,14 @@ function registerRefreshCommand(pi: ExtensionAPI) {
|
|
|
124
120
|
|
|
125
121
|
export default async function (pi: ExtensionAPI) {
|
|
126
122
|
const cacheState = readCacheState();
|
|
127
|
-
|
|
128
|
-
|
|
123
|
+
// Auto-refresh only when the disk cache is stale (>30 days).
|
|
124
|
+
// When cache is missing, GENERATED_MODELS serves as the cache —
|
|
125
|
+
// it is manually generated via `npm run generate-models` and committed to the repo.
|
|
126
|
+
const needsStartupRefresh = cacheState.status === "stale";
|
|
127
|
+
// GENERATED_MODELS ships with the package (36 tool-capable models from
|
|
128
|
+
// the build script). Used when no local cache exists. A fresh user cache
|
|
129
|
+
// from /ollama-cloud-refresh takes precedence over the generated list.
|
|
130
|
+
const models = cacheState.status === "missing" ? GENERATED_MODELS : assembleModels(cacheState.models);
|
|
129
131
|
|
|
130
132
|
registerProvider(pi, models);
|
|
131
133
|
registerRefreshCommand(pi);
|
|
@@ -139,8 +141,101 @@ export default async function (pi: ExtensionAPI) {
|
|
|
139
141
|
});
|
|
140
142
|
}
|
|
141
143
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
// --- Web Tools Management ---
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Ensure web tools are registered (idempotent).
|
|
148
|
+
* Returns true if any tools were newly registered.
|
|
149
|
+
*/
|
|
150
|
+
function ensureWebToolsRegistered(): boolean {
|
|
151
|
+
const allTools = pi.getAllTools();
|
|
152
|
+
let registered = false;
|
|
153
|
+
if (!allTools.some((t) => t.name === "ollama_web_search")) {
|
|
154
|
+
registerWebSearchTool(pi);
|
|
155
|
+
registered = true;
|
|
156
|
+
}
|
|
157
|
+
if (!allTools.some((t) => t.name === "ollama_web_fetch")) {
|
|
158
|
+
registerWebFetchTool(pi);
|
|
159
|
+
registered = true;
|
|
160
|
+
}
|
|
161
|
+
return registered;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Add or remove web tools from the active tools set.
|
|
166
|
+
*/
|
|
167
|
+
function setWebToolsActive(active: boolean) {
|
|
168
|
+
const currentActive = pi.getActiveTools();
|
|
169
|
+
const webToolNames = ["ollama_web_search", "ollama_web_fetch"];
|
|
170
|
+
|
|
171
|
+
if (active) {
|
|
172
|
+
const missing = webToolNames.filter((n) => !currentActive.includes(n));
|
|
173
|
+
if (missing.length > 0) {
|
|
174
|
+
pi.setActiveTools([...currentActive, ...missing]);
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
const filtered = currentActive.filter((t) => !webToolNames.includes(t));
|
|
178
|
+
if (filtered.length < currentActive.length) {
|
|
179
|
+
pi.setActiveTools(filtered);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Module-level tracking across session restarts within the same extension
|
|
185
|
+
// instance. The config file is read once, on the first session_start;
|
|
186
|
+
// later sessions reuse webToolsEnabled (including any /ollama-webtools
|
|
187
|
+
// override). Restart pi or /reload to pick up config file changes.
|
|
188
|
+
let webToolsConfigured = false;
|
|
189
|
+
let webToolsEnabled = false;
|
|
190
|
+
|
|
191
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
192
|
+
if (!webToolsConfigured) {
|
|
193
|
+
webToolsConfigured = true;
|
|
194
|
+
const config = loadConfig(ctx.cwd);
|
|
195
|
+
if (config.webTools !== false) {
|
|
196
|
+
webToolsEnabled = true;
|
|
197
|
+
ensureWebToolsRegistered();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// On every session start (including resume/fork/new), re-apply the
|
|
201
|
+
// runtime state. Tools may have been unregistered during teardown.
|
|
202
|
+
if (webToolsEnabled) {
|
|
203
|
+
ensureWebToolsRegistered();
|
|
204
|
+
setWebToolsActive(true);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// Only register the runtime toggle command when the env var doesn't force tools off.
|
|
209
|
+
// PI_OLLAMA_WEB_TOOLS acts as a hard kill switch — no command to re-enable.
|
|
210
|
+
if (resolveWebToolsEnv() !== false) {
|
|
211
|
+
pi.registerCommand("ollama-webtools", {
|
|
212
|
+
description:
|
|
213
|
+
"Enable or disable Ollama Cloud web tools (ollama_web_search, ollama_web_fetch). " +
|
|
214
|
+
"Accepts optional argument: on/off/enable/disable. Without argument, toggles.",
|
|
215
|
+
handler: async (args, ctx) => {
|
|
216
|
+
const arg = args.trim().toLowerCase();
|
|
217
|
+
|
|
218
|
+
if (arg === "on" || arg === "enable") {
|
|
219
|
+
webToolsEnabled = true;
|
|
220
|
+
} else if (arg === "off" || arg === "disable") {
|
|
221
|
+
webToolsEnabled = false;
|
|
222
|
+
} else if (arg === "") {
|
|
223
|
+
// Toggle current state
|
|
224
|
+
webToolsEnabled = !webToolsEnabled;
|
|
225
|
+
} else {
|
|
226
|
+
ctx.ui.notify(`Unknown argument "${args.trim()}". Usage: /ollama-webtools [on|off|enable|disable]`, "error");
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (webToolsEnabled) {
|
|
231
|
+
ensureWebToolsRegistered();
|
|
232
|
+
setWebToolsActive(true);
|
|
233
|
+
} else {
|
|
234
|
+
setWebToolsActive(false);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
ctx.ui.notify(`Ollama Web Tools: ${webToolsEnabled ? "enabled" : "disabled"}`, "info");
|
|
238
|
+
},
|
|
239
|
+
});
|
|
145
240
|
}
|
|
146
241
|
}
|