opencode-pollinations-plugin 6.0.0-beta.18 → 6.0.0-beta.20
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/dist/index.js +76 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,8 +15,16 @@ function log(msg) {
|
|
|
15
15
|
}
|
|
16
16
|
catch (e) { }
|
|
17
17
|
}
|
|
18
|
-
// === PROXY SERVER ===
|
|
18
|
+
// === PROXY SERVER (Singleton with Fixed Port) ===
|
|
19
|
+
const DEFAULT_PORT = 18888;
|
|
20
|
+
let existingServer = null;
|
|
21
|
+
let existingPort = 0;
|
|
19
22
|
const startProxy = () => {
|
|
23
|
+
// Singleton: reuse existing server if already running
|
|
24
|
+
if (existingServer && existingPort > 0) {
|
|
25
|
+
log(`[Proxy] Reusing existing server on port ${existingPort}`);
|
|
26
|
+
return Promise.resolve(existingPort);
|
|
27
|
+
}
|
|
20
28
|
return new Promise((resolve) => {
|
|
21
29
|
const server = http.createServer(async (req, res) => {
|
|
22
30
|
log(`[Proxy] Request: ${req.method} ${req.url}`);
|
|
@@ -60,16 +68,29 @@ const startProxy = () => {
|
|
|
60
68
|
res.writeHead(404);
|
|
61
69
|
res.end("Not Found");
|
|
62
70
|
});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
// Try fixed port first, fallback to dynamic if occupied
|
|
72
|
+
const tryListen = (port, fallbackToDynamic) => {
|
|
73
|
+
server.listen(port, '127.0.0.1', () => {
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
const assignedPort = server.address().port;
|
|
76
|
+
existingServer = server;
|
|
77
|
+
existingPort = assignedPort;
|
|
78
|
+
log(`[Proxy] Started v${require('../package.json').version} on port ${assignedPort}${port === 0 ? ' (dynamic fallback)' : ''}`);
|
|
79
|
+
resolve(assignedPort);
|
|
80
|
+
});
|
|
81
|
+
server.on('error', (e) => {
|
|
82
|
+
if (e.code === 'EADDRINUSE' && fallbackToDynamic) {
|
|
83
|
+
log(`[Proxy] Port ${port} in use, falling back to dynamic port`);
|
|
84
|
+
server.removeAllListeners('error');
|
|
85
|
+
tryListen(0, false); // Try dynamic port
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
log(`[Proxy] Fatal Error: ${e}`);
|
|
89
|
+
resolve(0);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
tryListen(DEFAULT_PORT, true);
|
|
73
94
|
});
|
|
74
95
|
};
|
|
75
96
|
// === AUTH HOOK: Native /connect Integration ===
|
|
@@ -150,15 +171,58 @@ const createAuthHook = () => ({
|
|
|
150
171
|
// === PLUGIN EXPORT ===
|
|
151
172
|
export const PollinationsPlugin = async (ctx) => {
|
|
152
173
|
log(`Plugin Initializing v${require('../package.json').version}...`);
|
|
153
|
-
// START PROXY
|
|
174
|
+
// START PROXY on fixed port
|
|
154
175
|
const port = await startProxy();
|
|
155
176
|
const localBaseUrl = `http://127.0.0.1:${port}/v1`;
|
|
156
177
|
setGlobalClient(ctx.client);
|
|
157
178
|
const toastHooks = createToastHooks(ctx.client);
|
|
158
179
|
const commandHooks = createCommandHooks();
|
|
180
|
+
// Helper: Refresh provider config (for hot-reload after /connect)
|
|
181
|
+
const refreshProviderConfig = async () => {
|
|
182
|
+
try {
|
|
183
|
+
log('[Event] Refreshing provider config after auth update...');
|
|
184
|
+
const modelsArray = await generatePollinationsConfig();
|
|
185
|
+
const modelsObj = {};
|
|
186
|
+
for (const m of modelsArray) {
|
|
187
|
+
modelsObj[m.id] = m;
|
|
188
|
+
}
|
|
189
|
+
const version = require('../package.json').version;
|
|
190
|
+
// Use Server API to PATCH the config at runtime
|
|
191
|
+
await ctx.client.fetch('/config', {
|
|
192
|
+
method: 'PATCH',
|
|
193
|
+
headers: { 'Content-Type': 'application/json' },
|
|
194
|
+
body: JSON.stringify({
|
|
195
|
+
provider: {
|
|
196
|
+
pollinations: {
|
|
197
|
+
id: 'openai',
|
|
198
|
+
name: `Pollinations AI (v${version})`,
|
|
199
|
+
options: {
|
|
200
|
+
baseURL: localBaseUrl,
|
|
201
|
+
apiKey: 'plugin-managed',
|
|
202
|
+
},
|
|
203
|
+
models: modelsObj
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
});
|
|
208
|
+
log(`[Event] Provider config refreshed with ${Object.keys(modelsObj).length} models.`);
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
log(`[Event] Failed to refresh provider config: ${e}`);
|
|
212
|
+
}
|
|
213
|
+
};
|
|
159
214
|
return {
|
|
160
215
|
// AUTH HOOK: Native /connect integration
|
|
161
216
|
auth: createAuthHook(),
|
|
217
|
+
// EVENT HOOK: Listen for auth/installation updates (triggered by /connect)
|
|
218
|
+
event: async ({ event }) => {
|
|
219
|
+
log(`[Event] Received: ${event.type}`);
|
|
220
|
+
// React to installation.updated (fired after /connect completes)
|
|
221
|
+
if (event.type === 'installation.updated') {
|
|
222
|
+
log('[Event] installation.updated detected - triggering hot-reload');
|
|
223
|
+
await refreshProviderConfig();
|
|
224
|
+
}
|
|
225
|
+
},
|
|
162
226
|
async config(config) {
|
|
163
227
|
log("[Hook] config() called");
|
|
164
228
|
// Generate models based on current auth state
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-pollinations-plugin",
|
|
3
3
|
"displayName": "Pollinations AI (V5.6)",
|
|
4
|
-
"version": "6.0.0-beta.
|
|
4
|
+
"version": "6.0.0-beta.20",
|
|
5
5
|
"description": "Native Pollinations.ai Provider Plugin for OpenCode",
|
|
6
6
|
"publisher": "pollinations",
|
|
7
7
|
"repository": {
|