opencode-pollinations-plugin 5.3.0 → 5.3.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.
package/bin/setup.js CHANGED
File without changes
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as http from 'http';
2
2
  import * as fs from 'fs';
3
+ import { execSync } from 'child_process';
3
4
  import { generatePollinationsConfig } from './server/generate-config.js';
4
5
  import { loadConfig } from './server/config.js';
5
6
  import { handleChatCompletion } from './server/proxy.js';
@@ -14,37 +15,55 @@ function log(msg) {
14
15
  catch (e) { }
15
16
  }
16
17
  const TRACKING_PORT = 10001;
17
- // === ANTI-ZOMBIE / PORT MANAGMENT (CROSS-PLATFORM) ===
18
- // Instead of killing specific PIDs (which requires OS-specific commands like fuser/taskkill),
19
- // we use a "Try to Listen" approach. If the port is busy, we assume it's a previous instance
20
- // of ourselves (or another plugin instance) and we try to reuse it or fail gracefully.
21
- // This works on Windows, Linux, and macOS without external dependencies.
22
- const tryListen = (server, port, retries = 3) => {
23
- return new Promise((resolve, reject) => {
24
- server.once('error', (err) => {
25
- if (err.code === 'EADDRINUSE') {
26
- if (retries > 0) {
27
- log(`[Init] Port ${port} busy. Retrying in 500ms... (${retries} left)`);
28
- setTimeout(() => {
29
- server.close();
30
- server.listen(port, '127.0.0.1'); // Retry listen
31
- }, 500);
18
+ // === PORT MANAGEMENT (CROSS-PLATFORM) ===
19
+ // We MUST kill the previous instance to ensure a fresh state.
20
+ // Sticky ports = Zombies = Buggy Behavior.
21
+ const freePort = (port) => {
22
+ try {
23
+ if (process.platform === 'win32') {
24
+ // Windows: Find PID -> TaskKing
25
+ try {
26
+ const output = execSync(`netstat -ano | findstr :${port}`).toString();
27
+ const lines = output.trim().split('\n');
28
+ for (const line of lines) {
29
+ const parts = line.trim().split(/\s+/);
30
+ const pid = parts[parts.length - 1];
31
+ if (pid && /^\d+$/.test(pid) && pid !== '0') {
32
+ try {
33
+ execSync(`taskkill /PID ${pid} /F`);
34
+ log(`[Init] Killed Windows PID ${pid} on port ${port}`);
35
+ }
36
+ catch (e) { }
37
+ }
32
38
  }
33
- else {
34
- log(`[Init] Port ${port} still busy. Assuming persistent instance.`);
35
- resolve(); // Resolve anyway, assuming existing instance will handle requests
39
+ }
40
+ catch (e) { }
41
+ }
42
+ else {
43
+ // Linux / macOS: lsof or fuser
44
+ try {
45
+ // Try lsof first (Cleaner)
46
+ const pid = execSync(`lsof -t -i:${port}`).toString().trim();
47
+ if (pid) {
48
+ execSync(`kill -9 ${pid}`);
49
+ log(`[Init] Killed PID ${pid} via lsof`);
36
50
  }
37
51
  }
38
- else {
39
- reject(err);
52
+ catch (e) {
53
+ // Fallback to fuser (Linux specific but very effective)
54
+ if (process.platform === 'linux') {
55
+ try {
56
+ execSync(`fuser -k ${port}/tcp`);
57
+ log(`[Init] Cleaned port ${port} via fuser`);
58
+ }
59
+ catch (e2) { }
60
+ }
40
61
  }
41
- });
42
- server.once('listening', () => {
43
- log(`[Init] Proxy successfully bound to port ${port}`);
44
- resolve();
45
- });
46
- server.listen(port, '127.0.0.1');
47
- });
62
+ }
63
+ }
64
+ catch (e) {
65
+ // Ignored: Port likely already free
66
+ }
48
67
  };
49
68
  // === GESTION DU CYCLE DE VIE PROXY ===
50
69
  const startProxy = () => {
@@ -94,12 +113,17 @@ const startProxy = () => {
94
113
  });
95
114
  // Robust Startup Logic
96
115
  try {
97
- await tryListen(server, TRACKING_PORT, 3);
98
- resolve(TRACKING_PORT);
116
+ server.listen(TRACKING_PORT, '127.0.0.1', () => {
117
+ log(`[Proxy] Started V5.3.1 on port ${TRACKING_PORT}`);
118
+ resolve(TRACKING_PORT);
119
+ });
120
+ server.on('error', (e) => {
121
+ log(`[Proxy] Fatal Bind Error: ${e}`);
122
+ resolve(0);
123
+ });
99
124
  }
100
125
  catch (e) {
101
- log(`[Proxy] Fatal Bind Error: ${e}`);
102
- resolve(0); // Should handle gracefully upper in stack
126
+ resolve(0);
103
127
  }
104
128
  });
105
129
  };
@@ -107,6 +131,9 @@ const startProxy = () => {
107
131
  export const PollinationsPlugin = async (ctx) => {
108
132
  log("Plugin Initializing V5.2.0 (Stable)...");
109
133
  // START PROXY
134
+ // 1. Force Clean Port
135
+ freePort(TRACKING_PORT);
136
+ // 2. Start
110
137
  const port = await startProxy();
111
138
  const localBaseUrl = `http://127.0.0.1:${port}/v1`;
112
139
  setGlobalClient(ctx.client);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "opencode-pollinations-plugin",
3
3
  "displayName": "Pollinations AI (V5.1)",
4
- "version": "5.3.0",
4
+ "version": "5.3.1",
5
5
  "description": "Native Pollinations.ai Provider Plugin for OpenCode",
6
6
  "publisher": "pollinations",
7
7
  "repository": {