opencode-pollinations-plugin 6.0.0 → 6.1.0-beta.10

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 (56) hide show
  1. package/README.md +140 -87
  2. package/dist/index.js +33 -154
  3. package/dist/server/commands.d.ts +2 -0
  4. package/dist/server/commands.js +84 -25
  5. package/dist/server/config.d.ts +6 -0
  6. package/dist/server/config.js +4 -1
  7. package/dist/server/generate-config.d.ts +3 -30
  8. package/dist/server/generate-config.js +172 -100
  9. package/dist/server/index.d.ts +2 -1
  10. package/dist/server/index.js +124 -149
  11. package/dist/server/pollinations-api.d.ts +11 -0
  12. package/dist/server/pollinations-api.js +20 -0
  13. package/dist/server/proxy.js +158 -72
  14. package/dist/server/quota.d.ts +8 -0
  15. package/dist/server/quota.js +106 -61
  16. package/dist/server/toast.d.ts +3 -0
  17. package/dist/server/toast.js +16 -0
  18. package/dist/tools/design/gen_diagram.d.ts +2 -0
  19. package/dist/tools/design/gen_diagram.js +94 -0
  20. package/dist/tools/design/gen_palette.d.ts +2 -0
  21. package/dist/tools/design/gen_palette.js +182 -0
  22. package/dist/tools/design/gen_qrcode.d.ts +2 -0
  23. package/dist/tools/design/gen_qrcode.js +50 -0
  24. package/dist/tools/index.d.ts +22 -0
  25. package/dist/tools/index.js +81 -0
  26. package/dist/tools/pollinations/deepsearch.d.ts +7 -0
  27. package/dist/tools/pollinations/deepsearch.js +80 -0
  28. package/dist/tools/pollinations/gen_audio.d.ts +18 -0
  29. package/dist/tools/pollinations/gen_audio.js +204 -0
  30. package/dist/tools/pollinations/gen_image.d.ts +13 -0
  31. package/dist/tools/pollinations/gen_image.js +239 -0
  32. package/dist/tools/pollinations/gen_music.d.ts +14 -0
  33. package/dist/tools/pollinations/gen_music.js +139 -0
  34. package/dist/tools/pollinations/gen_video.d.ts +16 -0
  35. package/dist/tools/pollinations/gen_video.js +222 -0
  36. package/dist/tools/pollinations/search_crawl_scrape.d.ts +7 -0
  37. package/dist/tools/pollinations/search_crawl_scrape.js +85 -0
  38. package/dist/tools/pollinations/shared.d.ts +170 -0
  39. package/dist/tools/pollinations/shared.js +454 -0
  40. package/dist/tools/pollinations/transcribe_audio.d.ts +17 -0
  41. package/dist/tools/pollinations/transcribe_audio.js +235 -0
  42. package/dist/tools/power/extract_audio.d.ts +2 -0
  43. package/dist/tools/power/extract_audio.js +180 -0
  44. package/dist/tools/power/extract_frames.d.ts +2 -0
  45. package/dist/tools/power/extract_frames.js +240 -0
  46. package/dist/tools/power/file_to_url.d.ts +2 -0
  47. package/dist/tools/power/file_to_url.js +217 -0
  48. package/dist/tools/power/remove_background.d.ts +2 -0
  49. package/dist/tools/power/remove_background.js +365 -0
  50. package/dist/tools/power/rmbg_keys.d.ts +2 -0
  51. package/dist/tools/power/rmbg_keys.js +78 -0
  52. package/dist/tools/shared.d.ts +30 -0
  53. package/dist/tools/shared.js +74 -0
  54. package/package.json +9 -3
  55. package/dist/server/models-seed.d.ts +0 -18
  56. package/dist/server/models-seed.js +0 -55
package/README.md CHANGED
@@ -1,119 +1,172 @@
1
- # 🌸 Pollinations AI Plugin for OpenCode
1
+ # 🌸 Pollinations AI Plugin for OpenCode (v6.1-beta)
2
2
 
3
3
  <div align="center">
4
- <img src="https://avatars.githubusercontent.com/u/88394740?s=400&v=4" alt="Pollinations.ai Logo" width="150">
4
+ <img src="https://avatars.githubusercontent.com/u/88394740?s=400&v=4" alt="Pollinations.ai Logo" width="200">
5
5
  <br>
6
- <b>The Bridge between OpenCode and the Pollinations.ai Ecosystem</b>
6
+ <b>The Bridge between OpenCode and the Pollinations.ai Ecosystem.</b>
7
7
  <br>
8
- Access 25+ AI models with Vision, Reasoning, and Tools support.
8
+ Access unlimited free AI models or premium enterprise models directly within your editor.
9
9
  </div>
10
10
 
11
11
  <div align="center">
12
12
 
13
- ![Version](https://img.shields.io/badge/version-6.0.0--beta.25-blue.svg)
13
+ ![Version](https://img.shields.io/badge/version-6.1.0--beta.10-blue.svg)
14
14
  ![License](https://img.shields.io/badge/license-MIT-green.svg)
15
- ![Status](https://img.shields.io/badge/status-Stable-brightgreen.svg)
16
-
17
- [📜 Changelog](./CHANGELOG.md) | [🛣️ Roadmap](./ROADMAP.md)
15
+ ![Status](https://img.shields.io/badge/status-Beta-orange.svg)
18
16
 
19
17
  </div>
20
18
 
21
- ---
22
-
23
- ## ✨ Features
24
-
25
- - **👁️ Vision Support**: Send images to AI models (OpenAI, Claude, Gemini, Kimi)
26
- - **🧠 Reasoning Models**: Access advanced thinking models (DeepSeek, Kimi, Perplexity)
27
- - **🛠️ Native Tools**: Full function calling support for compatible models
28
- - **🔐 Secure Auth**: Native OpenCode `/connect` integration
29
- - **🔄 Hot-Reload**: Change API keys without restarting OpenCode
30
-
31
- ---
32
-
33
- ## 🐝 Understanding Pollen & Tiers
34
-
35
- **Pollen** is Pollinations' unified credit system. $1 ≈ 1 Pollen.
36
-
37
- | Tier | Daily Grant | Requirement |
38
- |:-----|:------------|:------------|
39
- | 🦠 **Microbe** | 0.1 Pollen | Flagged accounts |
40
- | 🌱 **Spore** | 1 Pollen | Sign up |
41
- | 🌿 **Seed** | 3 Pollen | Active GitHub dev (8+ points) |
42
- | 🌸 **Flower** | 10 Pollen | Published app |
43
- | 🍯 **Nectar** | 20 Pollen | Major contributor |
44
-
45
- > 💡 This plugin was published to the OpenCode ecosystem, granting its author **Flower** tier (10 Pollen/day).
46
-
47
- ---
19
+ ## 📖 Philosophy: Open AI for Creators
48
20
 
49
- ## 🚀 Quick Start
21
+ > **"No closed doors, no corporate hoops — just good tools and good people."**
50
22
 
51
- ### 1. Install Plugin
52
- ```bash
53
- npm install -g opencode-pollinations-plugin
54
- npx opencode-pollinations-plugin
55
- ```
23
+ Pollinations.ai is an open-source platform built by and for the community. We provide a unified API for image, text, audio, and video generation.
24
+ - **Transparent**: Our code, roadmap, and discussions are open.
25
+ - **Community Driven**: Features are prioritized based on what *you* need.
26
+ - **Fair**: One single currency (**Pollen**) for all models. No complex subscriptions.
56
27
 
57
- ### 2. Connect Your Account
58
- ```
59
- /connect
60
- ```
61
- Select **pollinations** → Enter your API key from [enter.pollinations.ai](https://enter.pollinations.ai)
28
+ ## 📸 Gallery
62
29
 
63
- ### 3. Start Using
64
- Select any `pollinations/*` model in OpenCode and chat!
65
-
66
- ---
67
-
68
- ## 👁️ Vision Support
69
-
70
- The following models support image input:
30
+ <p align="center">
31
+ <img src="https://github.com/fkom13/opencode-pollinations-plugin/raw/main/docs/images/connect.png" alt="Connect Command" width="800">
32
+ <br>
33
+ <em>Easy Connection with /connect or /pollinations config apiKey</em>
34
+ </p>
71
35
 
72
- | Model | Vision | Reasoning | Tools |
73
- |-------|:------:|:---------:|:-----:|
74
- | `openai` / `openai-large` | ✅ | - | ✅ |
75
- | `gemini` / `gemini-search` | ✅ | - | ✅ |
76
- | `claude` / `claude-large` | ✅ | - | ✅ |
77
- | `kimi` | ✅ | ✅ | - |
78
- | `openai-audio` | ✅ | - | ✅ |
36
+ <p align="center">
37
+ <img src="https://github.com/fkom13/opencode-pollinations-plugin/raw/main/docs/images/usage_dashboard.png" alt="Usage Dashboard" width="800">
38
+ <br>
39
+ <em>Integrated Usage Dashboard (/pollinations usage)</em>
40
+ </p>
79
41
 
80
- **Usage**: Simply paste an image in the chat or use an image URL. The plugin handles encoding automatically.
42
+ <p align="center">
43
+ <img src="https://github.com/fkom13/opencode-pollinations-plugin/raw/main/docs/images/models.png" alt="Models" width="800">
44
+ <br>
45
+ <em>Wide Range of Models (Mistral, OpenAI, Gemini, Claude)</em>
46
+ </p>
81
47
 
82
- ---
48
+ <p align="center">
49
+ <img src="https://github.com/fkom13/opencode-pollinations-plugin/raw/main/docs/images/free_add.png" alt="Free Chat Example" width="800">
50
+ <br>
51
+ <em>Free Universe Chat (Supported by Pollinations Ads)</em>
52
+ </p>
83
53
 
84
- ## 📊 Available Models (25+)
54
+ <p align="center">
55
+ <img src="https://github.com/fkom13/opencode-pollinations-plugin/raw/main/docs/images/plan_1.png" alt="Plan Build Step 1" width="400">
56
+ <img src="https://github.com/fkom13/opencode-pollinations-plugin/raw/main/docs/images/plan_2.png" alt="Plan Build Step 2" width="400">
57
+ <br>
58
+ <em>Integrated Plan Building Workflow</em>
59
+ </p>
85
60
 
86
- ### Text/Chat Models
87
- - **OpenAI**: `openai`, `openai-fast`, `openai-large`
88
- - **Gemini**: `gemini`, `gemini-fast`, `gemini-search`, `gemini-large` 💎
89
- - **Claude**: `claude-fast`, `claude`, `claude-large` 💎
90
- - **Reasoning**: `deepseek`, `kimi`, `perplexity-reasoning`
91
- - **Code**: `qwen-coder`, `mistral`
92
- - **Fast**: `nova-fast`, `grok`
61
+ ## Features
93
62
 
94
- ### Paid-Only Models (💎)
95
- These require purchased credits (not daily grants):
96
- - `claude-large`, `gemini-large`, `veo`, `seedream-pro`
63
+ - **🌍 Free Universe**: Access generic models (`openai`, `mistral`, `gemini`) for **FREE**, unlimited time, no API key required.
64
+ - **🛡️ Robust Quota System (New v6.1)**: Local "Ledger" technology (`~/.pollinations/usage_history.json`) ensures 100% accurate usage tracking, zero lag, and no wallet drain.
65
+ - **🚀 Pro Mode**: Connect your Pollinations API Key to access Premium Models (`claude-3-opus`, `gpt-4o`, `deepseek-coder`).
66
+ - **🔐 Limited Key Support**: Use keys restricted to "Generation Only". The plugin automatically disables Advanced Features (Dashboard/Quota) but allows full generation in Manual Mode.
67
+ - **🛡️ Safety Net V5**: never get blocked.
68
+ - **Transparent Fallback**: If your Pro quota runs out mid-chat, the plugin automatically switches to a free model instantly. No errors, just a seamless experience.
69
+ - **Smart Mode Switching**: Prevents Limited Keys from entering "Pro" mode to avoid confusing errors.
70
+ - **📊 Real-time Dashboard**: Track your **Pollen** usage, Tier Status, and Wallet Balance inside OpenCode.
71
+ - **🔇 Stealth Mode**: Status notifications are now strictly limited to Pollinations Enter (Paid) sessions. No more cluttered notifications when using other providers like Nvidia or Google AI.
97
72
 
98
- ---
73
+ ### 📚 Documentation
99
74
 
100
- ## 🔧 Commands
75
+ - **[User Manual](docs/technical/manual.md)**
76
+ - **[API Reference](docs/technical/api_reference.md)**
77
+ - **[Architecture](docs/technical/architecture.md)**
101
78
 
102
- ```
103
- /pollinations usage # View Pollen balance
104
- /pollinations usage full # Detailed model breakdown
105
- /pollinations status # Plugin health check
106
- ```
79
+ ## 🐝 Understanding Pollen & Tiers
107
80
 
108
- ---
81
+ **Pollen** is our unified credit system. $1 ≈ 1 Pollen.
82
+ You spend it to verify API calls on premium models.
83
+
84
+ ### Tiers (Free Daily Grants during Beta)
85
+
86
+ | Tier | Grant | Requirement |
87
+ | :--- | :--- | :--- |
88
+ | **🦠 Spore** | **1 Pollen/day** | Just Sign Up! |
89
+ | **🌱 Seed** | **3 Pollen/day** | Active GitHub Developer (8+ points) |
90
+ | **🌸 Flower** | **10 Pollen/day** | **Publish an App** (Like this Plugin!) |
91
+ | **🍯 Nectar** | **20 Pollen/day** | Major Contributors (Coming Soon) |
92
+
93
+ > 🎁 **Beta Bonus**: Buy one Pollen pack, get one free!
94
+
95
+ ### 🐧 Platform Support & Dynamic Ports (v5.4.6+)
96
+ This plugin is **true Cross-Platform** (Windows, macOS, Linux).
97
+ - **Dynamic Port Allocation**: No more port conflicts! The plugin automatically finds an available port on startup.
98
+ - **Tools Support**: Using tools with Gemini (Free) triggers an **Automatic Intelligent Fallback** to OpenAI to ensure your workflow never breaks.
99
+
100
+ > **Note**: Legacy static port (10001) logic has been replaced with system-assigned ports (0). This eliminates "Address in use" errors and effectively removes the need for Linux-specific `fuser` commands, making the plugin fully **Cross-Platform**.
101
+
102
+ This plugin is part of the **OpenCode Ecosystem**.
103
+
104
+ ### Option 1: NPM (Instant Setup) (Recommended)
105
+ This method automatically configures OpenCode to load the plugin.
106
+
107
+ 1. Install global:
108
+ ```bash
109
+ npm install -g opencode-pollinations-plugin
110
+ ```
111
+ 2. Run the Auto-Setup (Magic):
112
+ ```bash
113
+ npx opencode-pollinations-plugin
114
+ ```
115
+ *This detects your OpenCode config and injects the plugin path automatically.*
116
+
117
+ ### Option 2: Manual Configuration
118
+ 1. Install globally as above.
119
+ 2. Edit `~/.config/opencode/opencode.json`:
120
+ ```json
121
+ {
122
+ "plugin": [
123
+ "opencode-pollinations-plugin"
124
+ ]
125
+ }
126
+ ```
127
+ *Note: If OpenCode fails to find it, use the absolute path to the global install.*
128
+
129
+ ## 🚀 Publication (The "Registry")
130
+ OpenCode uses NPM as its registry. To publish:
131
+
132
+ 1. **Publish to NPM**:
133
+ ```bash
134
+ npm login
135
+ npm publish
136
+ ```
137
+ 2. **Join Ecosystem**: Submit a Pull Request to [OpenCode Ecosystem](https://github.com/opencode-ai/ecosystem) to list your plugin officially.
138
+ *Once accepted, users can find it via documentation or future registry commands.*
139
+
140
+ ## 🚀 Getting Started
141
+
142
+ ### 1. The Basics (Free Mode)
143
+ Just type in the chat. You are in **Manual Mode** by default.
144
+ - Model: `openai-fast` (GPT-OSS 20b)
145
+ - Model: `mistral` (Mistral Small 3.1)
146
+ - ...
147
+
148
+ ### 🔑 Configuration (API Key)
149
+
150
+ 1. Run the setup command:
151
+ ```bash
152
+ /connect
153
+ ```
154
+ 2. Choose "pollinations" and enter your key if you have one (or leave blank for free tier).
155
+ 3. **IMPORTANT**: You must **restart OpenCode** for the model list to update with your new tier (e.g. to see Paid models).
156
+
157
+ ### 🤖 Models
158
+
159
+ ### 🔑 Types de Clés Supportés
160
+ - **Clés Standard (`sk-...`)**: Accès complet (Modèles + Dashboard Usage + Quota).
161
+ - **Clés Limitées**: Accès Génération uniquement. Le dashboard affichera une alerte de restriction.
162
+ - **Support Legacy**: Les anciennes clés (`sk_...`) sont aussi acceptées.
109
163
 
110
164
  ## 🔗 Links
111
165
 
112
- - **Get API Key**: [enter.pollinations.ai](https://enter.pollinations.ai)
113
- - **Discord**: [Join Community](https://discord.gg/pollinations-ai-885844321461485618)
114
- - **GitHub**: [Plugin Repository](https://github.com/fkom13/opencode-pollinations-plugin)
115
-
116
- ---
166
+ - **Sign up Pollinations Beta (more and best free tiers access and paids models)**: [pollinations.ai](https://enter.pollinations.ai)
167
+ - **Pollinations Website**: [pollinations.ai](https://pollinations.ai)
168
+ - **Discord Community**: [Join us!](https://discord.gg/pollinations-ai-885844321461485618)
169
+ - **OpenCode Ecosystem**: [opencode.ai](https://opencode.ai/docs/ecosystem#plugins)
117
170
 
118
171
  ## 📜 License
119
172
 
package/dist/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import * as http from 'http';
2
2
  import * as fs from 'fs';
3
3
  import { generatePollinationsConfig } from './server/generate-config.js';
4
- import { loadConfig, saveConfig } from './server/config.js';
4
+ import { loadConfig } from './server/config.js';
5
5
  import { handleChatCompletion } from './server/proxy.js';
6
- import { createToastHooks, setGlobalClient } from './server/toast.js';
6
+ import { createToastHooks, createToolHooks, setGlobalClient } from './server/toast.js';
7
7
  import { createStatusHooks } from './server/status.js';
8
- import { createCommandHooks } from './server/commands.js';
8
+ import { createCommandHooks, setClientForCommands } from './server/commands.js';
9
+ import { createToolRegistry } from './tools/index.js';
9
10
  import { createRequire } from 'module';
10
11
  const require = createRequire(import.meta.url);
11
12
  const LOG_FILE = '/tmp/opencode_pollinations_v4.log';
@@ -15,17 +16,12 @@ function log(msg) {
15
16
  }
16
17
  catch (e) { }
17
18
  }
18
- // === PROXY SERVER (Singleton with Fixed Port) ===
19
- const DEFAULT_PORT = 18888;
20
- const GLOBAL_SERVER_KEY = '__POLLINATIONS_PROXY_SERVER__';
19
+ // Port killing removed: Using dynamic ports.
21
20
  const startProxy = () => {
22
- // Check if server exists in global scope (survives module reloads)
23
- if (global[GLOBAL_SERVER_KEY]) {
24
- log(`[Proxy] Reusing existing global server on port ${DEFAULT_PORT}`);
25
- return Promise.resolve(DEFAULT_PORT);
26
- }
27
21
  return new Promise((resolve) => {
28
22
  const server = http.createServer(async (req, res) => {
23
+ // ... (Request Handling) ...
24
+ // We reuse the existing logic structure but simplified startup
29
25
  log(`[Proxy] Request: ${req.method} ${req.url}`);
30
26
  res.setHeader('Access-Control-Allow-Origin', '*');
31
27
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
@@ -67,156 +63,40 @@ const startProxy = () => {
67
63
  res.writeHead(404);
68
64
  res.end("Not Found");
69
65
  });
70
- // Try fixed port first, fallback to dynamic if occupied
71
- const tryListen = (port, fallbackToDynamic) => {
72
- server.listen(port, '127.0.0.1', () => {
73
- // @ts-ignore
74
- const assignedPort = server.address().port;
75
- global[GLOBAL_SERVER_KEY] = server;
76
- log(`[Proxy] Started v${require('../package.json').version} on port ${assignedPort}${port === 0 ? ' (dynamic fallback)' : ''}`);
77
- resolve(assignedPort);
78
- });
79
- server.on('error', (e) => {
80
- if (e.code === 'EADDRINUSE' && fallbackToDynamic) {
81
- log(`[Proxy] Port ${port} in use, falling back to dynamic port`);
82
- server.removeAllListeners('error');
83
- tryListen(0, false); // Try dynamic port
84
- }
85
- else {
86
- log(`[Proxy] Fatal Error: ${e}`);
87
- resolve(0);
88
- }
89
- });
90
- };
91
- tryListen(DEFAULT_PORT, true);
66
+ // Listen on random port (0) to avoid conflicts (CLI/IDE)
67
+ server.listen(0, '127.0.0.1', () => {
68
+ // @ts-ignore
69
+ const assignedPort = server.address().port;
70
+ log(`[Proxy] Started v${require('../package.json').version} (Dynamic Port) on port ${assignedPort}`);
71
+ resolve(assignedPort);
72
+ });
73
+ server.on('error', (e) => {
74
+ log(`[Proxy] Fatal Error: ${e}`);
75
+ resolve(0);
76
+ });
92
77
  });
93
78
  };
94
- // === AUTH HOOK: Native /connect Integration ===
95
- // Auth Hook moved inside plugin to access context
96
79
  // === PLUGIN EXPORT ===
97
80
  export const PollinationsPlugin = async (ctx) => {
98
- log(`Plugin Initializing v${require('../package.json').version}...`);
99
- // START PROXY on fixed port
81
+ const v = require('../package.json').version;
82
+ log(`Plugin Initializing v${v}...`);
83
+ console.log(`🚀 POLLINATIONS PLUGIN v${v} LOADED 🚀`);
84
+ // START PROXY
100
85
  const port = await startProxy();
101
86
  const localBaseUrl = `http://127.0.0.1:${port}/v1`;
102
87
  setGlobalClient(ctx.client);
88
+ setClientForCommands(ctx.client);
103
89
  const toastHooks = createToastHooks(ctx.client);
104
90
  const commandHooks = createCommandHooks();
105
- // Helper: Refresh provider config (for hot-reload after /connect)
106
- let isRefreshing = false;
107
- const refreshProviderConfig = async () => {
108
- if (isRefreshing)
109
- return;
110
- isRefreshing = true;
111
- try {
112
- log('[Event] Refreshing provider config after auth update...');
113
- const modelsArray = await generatePollinationsConfig();
114
- const modelsObj = {};
115
- for (const m of modelsArray) {
116
- modelsObj[m.id] = m;
117
- }
118
- const version = require('../package.json').version;
119
- // CRITICAL: Fetch current config first to avoid overwriting other providers
120
- let currentConfig = {};
121
- try {
122
- // Try to fetch existing config to preserve other providers
123
- const response = await ctx.client.fetch('/config');
124
- if (response.ok) {
125
- currentConfig = await response.json();
126
- }
127
- }
128
- catch (err) {
129
- log(`[Event] Warning: Could not fetch current config: ${err}`);
130
- }
131
- // Safe Merge
132
- if (!currentConfig.provider)
133
- currentConfig.provider = {};
134
- currentConfig.provider.pollinations = {
135
- id: 'openai',
136
- name: `Pollinations AI (v${version})`,
137
- options: {
138
- baseURL: localBaseUrl,
139
- apiKey: 'plugin-managed',
140
- },
141
- models: modelsObj
142
- };
143
- // Use Server API to update config with the MERGED object
144
- await ctx.client.fetch('/config', {
145
- method: 'PATCH',
146
- headers: { 'Content-Type': 'application/json' },
147
- body: JSON.stringify({
148
- provider: currentConfig.provider
149
- })
150
- });
151
- log(`[Event] Provider config refreshed with ${Object.keys(modelsObj).length} models.`);
152
- }
153
- catch (e) {
154
- log(`[Event] Failed to refresh provider config: ${e}`);
155
- }
156
- finally {
157
- // Debounce: prevent another refresh for 5 seconds
158
- setTimeout(() => { isRefreshing = false; }, 5000);
159
- }
160
- };
91
+ // Build tool registry (conditional on API key presence)
92
+ const toolRegistry = createToolRegistry();
93
+ log(`[Tools] ${Object.keys(toolRegistry).length} tools registered`);
161
94
  return {
162
- // AUTH HOOK: Native /connect integration (INLINED)
163
- auth: {
164
- provider: 'pollinations',
165
- loader: async (auth, provider) => {
166
- log('[AuthHook] loader() called');
167
- try {
168
- const authData = await auth();
169
- if (authData && 'key' in authData) {
170
- const k = authData.key;
171
- saveConfig({ apiKey: k });
172
- return { apiKey: k };
173
- }
174
- }
175
- catch (e) {
176
- log(`[AuthHook] loader error: ${e}`);
177
- }
178
- const config = loadConfig();
179
- if (config.apiKey)
180
- return { apiKey: config.apiKey };
181
- return {};
182
- },
183
- methods: [{
184
- type: 'api',
185
- label: 'Pollinations API Key',
186
- prompts: [{
187
- type: 'text',
188
- key: 'apiKey',
189
- message: 'Enter Pollinations API Key (starts with sk_)',
190
- validate: (v) => (!v || v.length < 10) ? 'Invalid key' : undefined
191
- }],
192
- authorize: async (inputs) => {
193
- log(`[AuthHook] authorize() called`);
194
- if (!inputs?.apiKey)
195
- return { type: 'failed' };
196
- try {
197
- const r = await fetch('https://gen.pollinations.ai/text/models', {
198
- headers: { 'Authorization': `Bearer ${inputs.apiKey}` }
199
- });
200
- if (r.ok) {
201
- log('[AuthHook] Success. Saving & Refreshing Config...');
202
- saveConfig({ apiKey: inputs.apiKey });
203
- // CRITICAL: Refresh config IMMEDIATELY after successful auth
204
- await refreshProviderConfig();
205
- return { type: 'success', key: inputs.apiKey };
206
- }
207
- }
208
- catch (e) {
209
- log(`[AuthHook] Auth error: ${e}`);
210
- }
211
- return { type: 'failed' };
212
- }
213
- }]
214
- },
215
- // Event hook removed (logic moved to authorize)
216
- event: async ({ event }) => { },
95
+ tool: toolRegistry,
217
96
  async config(config) {
218
97
  log("[Hook] config() called");
219
- // Generate models based on current auth state
98
+ // STARTUP only - No complex hot reload logic
99
+ // The user must restart OpenCode to refresh this list if they change keys.
220
100
  const modelsArray = await generatePollinationsConfig();
221
101
  const modelsObj = {};
222
102
  for (const m of modelsArray) {
@@ -224,19 +104,18 @@ export const PollinationsPlugin = async (ctx) => {
224
104
  }
225
105
  if (!config.provider)
226
106
  config.provider = {};
107
+ // Dynamic Provider Name
227
108
  const version = require('../package.json').version;
228
109
  config.provider['pollinations'] = {
229
- id: 'openai',
110
+ id: 'pollinations',
230
111
  name: `Pollinations AI (v${version})`,
231
- options: {
232
- baseURL: localBaseUrl,
233
- apiKey: 'plugin-managed', // Key is managed by auth hook
234
- },
112
+ options: { baseURL: localBaseUrl },
235
113
  models: modelsObj
236
114
  };
237
115
  log(`[Hook] Registered ${Object.keys(modelsObj).length} models.`);
238
116
  },
239
117
  ...toastHooks,
118
+ ...createToolHooks(ctx.client),
240
119
  ...createStatusHooks(ctx.client),
241
120
  ...commandHooks
242
121
  };
@@ -9,8 +9,10 @@ interface CommandResult {
9
9
  response?: string;
10
10
  error?: string;
11
11
  }
12
+ export declare function setClientForCommands(client: any): void;
12
13
  export declare function handleCommand(command: string): Promise<CommandResult>;
13
14
  export declare function createCommandHooks(): {
14
15
  'tui.command.execute': (input: any, output: any) => Promise<void>;
16
+ 'command.execute.before': (input: any, output: any) => Promise<void>;
15
17
  };
16
18
  export {};