mcp-perplexity-pro 1.1.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/README.md +638 -0
- package/bin/mcp-perplexity-pro +8 -0
- package/bin/mcp-perplexity-pro-stdio +9 -0
- package/dist/claude-code-bridge.d.ts +3 -0
- package/dist/claude-code-bridge.d.ts.map +1 -0
- package/dist/claude-code-bridge.js +111 -0
- package/dist/claude-code-bridge.js.map +1 -0
- package/dist/http-index.d.ts +3 -0
- package/dist/http-index.d.ts.map +1 -0
- package/dist/http-index.js +38 -0
- package/dist/http-index.js.map +1 -0
- package/dist/http-server.d.ts +33 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +362 -0
- package/dist/http-server.js.map +1 -0
- package/dist/http-streaming-server.d.ts +4 -0
- package/dist/http-streaming-server.d.ts.map +1 -0
- package/dist/http-streaming-server.js +514 -0
- package/dist/http-streaming-server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/launcher.d.ts +3 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +209 -0
- package/dist/launcher.js.map +1 -0
- package/dist/mcp-server.d.ts +5 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +329 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/models.d.ts +45 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +284 -0
- package/dist/models.js.map +1 -0
- package/dist/perplexity-api.d.ts +59 -0
- package/dist/perplexity-api.d.ts.map +1 -0
- package/dist/perplexity-api.js +455 -0
- package/dist/perplexity-api.js.map +1 -0
- package/dist/port-utils.d.ts +31 -0
- package/dist/port-utils.d.ts.map +1 -0
- package/dist/port-utils.js +114 -0
- package/dist/port-utils.js.map +1 -0
- package/dist/project-manager.d.ts +91 -0
- package/dist/project-manager.d.ts.map +1 -0
- package/dist/project-manager.js +422 -0
- package/dist/project-manager.js.map +1 -0
- package/dist/simple-streaming.d.ts +26 -0
- package/dist/simple-streaming.d.ts.map +1 -0
- package/dist/simple-streaming.js +75 -0
- package/dist/simple-streaming.js.map +1 -0
- package/dist/sse-index.d.ts +3 -0
- package/dist/sse-index.d.ts.map +1 -0
- package/dist/sse-index.js +38 -0
- package/dist/sse-index.js.map +1 -0
- package/dist/sse-server.d.ts +4 -0
- package/dist/sse-server.d.ts.map +1 -0
- package/dist/sse-server.js +208 -0
- package/dist/sse-server.js.map +1 -0
- package/dist/stdio-bridge.d.ts +21 -0
- package/dist/stdio-bridge.d.ts.map +1 -0
- package/dist/stdio-bridge.js +157 -0
- package/dist/stdio-bridge.js.map +1 -0
- package/dist/stdio-server.d.ts +7 -0
- package/dist/stdio-server.d.ts.map +1 -0
- package/dist/stdio-server.js +396 -0
- package/dist/stdio-server.js.map +1 -0
- package/dist/storage.d.ts +65 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +328 -0
- package/dist/storage.js.map +1 -0
- package/dist/streaming-wrapper.d.ts +63 -0
- package/dist/streaming-wrapper.d.ts.map +1 -0
- package/dist/streaming-wrapper.js +452 -0
- package/dist/streaming-wrapper.js.map +1 -0
- package/dist/tools/async.d.ts +28 -0
- package/dist/tools/async.d.ts.map +1 -0
- package/dist/tools/async.js +167 -0
- package/dist/tools/async.js.map +1 -0
- package/dist/tools/chat.d.ts +29 -0
- package/dist/tools/chat.d.ts.map +1 -0
- package/dist/tools/chat.js +233 -0
- package/dist/tools/chat.js.map +1 -0
- package/dist/tools/projects.d.ts +19 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +219 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/query.d.ts +13 -0
- package/dist/tools/query.d.ts.map +1 -0
- package/dist/tools/query.js +178 -0
- package/dist/tools/query.js.map +1 -0
- package/dist/types.d.ts +330 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +90 -0
- package/dist/types.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import fetch from 'node-fetch';
|
|
2
|
+
import { suggestFallbackModel } from './models.js';
|
|
3
|
+
// Perplexity API endpoints
|
|
4
|
+
const PERPLEXITY_BASE_URL = 'https://api.perplexity.ai';
|
|
5
|
+
const CHAT_COMPLETIONS_ENDPOINT = '/chat/completions';
|
|
6
|
+
const ASYNC_CHAT_COMPLETIONS_ENDPOINT = '/async/chat/completions';
|
|
7
|
+
export class PerplexityApiError extends Error {
|
|
8
|
+
status;
|
|
9
|
+
response;
|
|
10
|
+
constructor(message, status, response) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.response = response;
|
|
14
|
+
this.name = 'PerplexityApiError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class PerplexityApiClient {
|
|
18
|
+
apiKey;
|
|
19
|
+
baseUrl;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.apiKey = config.api_key;
|
|
22
|
+
this.baseUrl = PERPLEXITY_BASE_URL;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Makes a request to the Perplexity API with proper error handling
|
|
26
|
+
*/
|
|
27
|
+
async makeRequest(endpoint, body, method = 'POST') {
|
|
28
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
29
|
+
console.error(`Making request to: ${url}`);
|
|
30
|
+
console.error(`API key: ${this.apiKey ? this.apiKey.substring(0, 10) + '...' : 'MISSING'}`);
|
|
31
|
+
try {
|
|
32
|
+
const response = await fetch(url, {
|
|
33
|
+
method,
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
36
|
+
'Content-Type': 'application/json',
|
|
37
|
+
},
|
|
38
|
+
body: method === 'POST' ? JSON.stringify(body) : null,
|
|
39
|
+
});
|
|
40
|
+
// Check if response is JSON before parsing
|
|
41
|
+
const contentType = response.headers.get('content-type');
|
|
42
|
+
let data;
|
|
43
|
+
if (contentType?.includes('application/json')) {
|
|
44
|
+
data = await response.json();
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// If not JSON, get the text for better error messages
|
|
48
|
+
const text = await response.text();
|
|
49
|
+
data = { error: { message: `Non-JSON response: ${text.substring(0, 200)}...` } };
|
|
50
|
+
}
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new PerplexityApiError(data.error?.message || `HTTP ${response.status}: ${response.statusText}`, response.status, data);
|
|
53
|
+
}
|
|
54
|
+
return data;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (error instanceof PerplexityApiError) {
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
if (error instanceof Error) {
|
|
61
|
+
throw new PerplexityApiError(`Network error: ${error.message}`);
|
|
62
|
+
}
|
|
63
|
+
throw new PerplexityApiError('Unknown error occurred');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Sends a chat completion request to Perplexity
|
|
68
|
+
*/
|
|
69
|
+
async chatCompletion(request) {
|
|
70
|
+
// Prepare the request body according to Perplexity API format
|
|
71
|
+
const requestBody = {
|
|
72
|
+
model: request.model,
|
|
73
|
+
messages: request.messages,
|
|
74
|
+
...(request.max_tokens && { max_tokens: request.max_tokens }),
|
|
75
|
+
...(request.temperature !== undefined && { temperature: request.temperature }),
|
|
76
|
+
...(request.top_p !== undefined && { top_p: request.top_p }),
|
|
77
|
+
...(request.search_domain_filter && { search_domain_filter: request.search_domain_filter }),
|
|
78
|
+
...(request.return_images !== undefined && { return_images: request.return_images }),
|
|
79
|
+
...(request.return_related_questions !== undefined && {
|
|
80
|
+
return_related_questions: request.return_related_questions,
|
|
81
|
+
}),
|
|
82
|
+
...(request.search_recency_filter && {
|
|
83
|
+
search_recency_filter: request.search_recency_filter,
|
|
84
|
+
}),
|
|
85
|
+
...(request.search_after_date_filter && {
|
|
86
|
+
search_after_date_filter: request.search_after_date_filter,
|
|
87
|
+
}),
|
|
88
|
+
...(request.search_before_date_filter && {
|
|
89
|
+
search_before_date_filter: request.search_before_date_filter,
|
|
90
|
+
}),
|
|
91
|
+
...(request.last_updated_after_filter && {
|
|
92
|
+
last_updated_after_filter: request.last_updated_after_filter,
|
|
93
|
+
}),
|
|
94
|
+
...(request.last_updated_before_filter && {
|
|
95
|
+
last_updated_before_filter: request.last_updated_before_filter,
|
|
96
|
+
}),
|
|
97
|
+
...(request.top_k !== undefined && { top_k: request.top_k }),
|
|
98
|
+
...(request.stream !== undefined && { stream: request.stream }),
|
|
99
|
+
...(request.presence_penalty !== undefined && { presence_penalty: request.presence_penalty }),
|
|
100
|
+
...(request.frequency_penalty !== undefined && {
|
|
101
|
+
frequency_penalty: request.frequency_penalty,
|
|
102
|
+
}),
|
|
103
|
+
...(request.response_format && { response_format: request.response_format }),
|
|
104
|
+
...(request.disable_search !== undefined && { disable_search: request.disable_search }),
|
|
105
|
+
...(request.enable_search_classifier !== undefined && {
|
|
106
|
+
enable_search_classifier: request.enable_search_classifier,
|
|
107
|
+
}),
|
|
108
|
+
...(request.web_search_options && { web_search_options: request.web_search_options }),
|
|
109
|
+
};
|
|
110
|
+
return this.makeRequest(CHAT_COMPLETIONS_ENDPOINT, requestBody);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Sends a streaming chat completion request to Perplexity
|
|
114
|
+
*/
|
|
115
|
+
async chatCompletionStream(request, callbacks) {
|
|
116
|
+
const url = `${this.baseUrl}${CHAT_COMPLETIONS_ENDPOINT}`;
|
|
117
|
+
// Force streaming mode
|
|
118
|
+
const requestBody = {
|
|
119
|
+
model: request.model,
|
|
120
|
+
messages: request.messages,
|
|
121
|
+
stream: true, // Force streaming
|
|
122
|
+
...(request.max_tokens && { max_tokens: request.max_tokens }),
|
|
123
|
+
...(request.temperature !== undefined && { temperature: request.temperature }),
|
|
124
|
+
...(request.top_p !== undefined && { top_p: request.top_p }),
|
|
125
|
+
...(request.search_domain_filter && { search_domain_filter: request.search_domain_filter }),
|
|
126
|
+
...(request.return_images !== undefined && { return_images: request.return_images }),
|
|
127
|
+
...(request.return_related_questions !== undefined && {
|
|
128
|
+
return_related_questions: request.return_related_questions,
|
|
129
|
+
}),
|
|
130
|
+
...(request.search_recency_filter && {
|
|
131
|
+
search_recency_filter: request.search_recency_filter,
|
|
132
|
+
}),
|
|
133
|
+
...(request.search_after_date_filter && {
|
|
134
|
+
search_after_date_filter: request.search_after_date_filter,
|
|
135
|
+
}),
|
|
136
|
+
...(request.search_before_date_filter && {
|
|
137
|
+
search_before_date_filter: request.search_before_date_filter,
|
|
138
|
+
}),
|
|
139
|
+
...(request.last_updated_after_filter && {
|
|
140
|
+
last_updated_after_filter: request.last_updated_after_filter,
|
|
141
|
+
}),
|
|
142
|
+
...(request.last_updated_before_filter && {
|
|
143
|
+
last_updated_before_filter: request.last_updated_before_filter,
|
|
144
|
+
}),
|
|
145
|
+
...(request.top_k !== undefined && { top_k: request.top_k }),
|
|
146
|
+
...(request.presence_penalty !== undefined && { presence_penalty: request.presence_penalty }),
|
|
147
|
+
...(request.frequency_penalty !== undefined && {
|
|
148
|
+
frequency_penalty: request.frequency_penalty,
|
|
149
|
+
}),
|
|
150
|
+
...(request.response_format && { response_format: request.response_format }),
|
|
151
|
+
...(request.disable_search !== undefined && { disable_search: request.disable_search }),
|
|
152
|
+
...(request.enable_search_classifier !== undefined && {
|
|
153
|
+
enable_search_classifier: request.enable_search_classifier,
|
|
154
|
+
}),
|
|
155
|
+
...(request.web_search_options && { web_search_options: request.web_search_options }),
|
|
156
|
+
};
|
|
157
|
+
try {
|
|
158
|
+
const response = await fetch(url, {
|
|
159
|
+
method: 'POST',
|
|
160
|
+
headers: {
|
|
161
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
162
|
+
'Content-Type': 'application/json',
|
|
163
|
+
Accept: 'text/event-stream',
|
|
164
|
+
},
|
|
165
|
+
body: JSON.stringify(requestBody),
|
|
166
|
+
});
|
|
167
|
+
if (!response.ok) {
|
|
168
|
+
const errorText = await response.text();
|
|
169
|
+
throw new PerplexityApiError(`HTTP ${response.status}: ${response.statusText}`, response.status, { error: { message: errorText } });
|
|
170
|
+
}
|
|
171
|
+
if (!response.body) {
|
|
172
|
+
throw new PerplexityApiError('No response body received');
|
|
173
|
+
}
|
|
174
|
+
// In node-fetch v3, response.body is already a Node.js Readable stream
|
|
175
|
+
// Cast it to the correct type for TypeScript
|
|
176
|
+
const bodyStream = response.body;
|
|
177
|
+
return this.processStreamingResponse(bodyStream, callbacks);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
if (callbacks.onError) {
|
|
181
|
+
callbacks.onError(error instanceof Error ? error : new Error('Unknown streaming error'));
|
|
182
|
+
}
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Processes Server-Sent Events from Perplexity's streaming API
|
|
188
|
+
*/
|
|
189
|
+
async processStreamingResponse(body, callbacks) {
|
|
190
|
+
return new Promise((resolve, reject) => {
|
|
191
|
+
let buffer = '';
|
|
192
|
+
let finalResponse = null;
|
|
193
|
+
let aggregatedContent = '';
|
|
194
|
+
let responseMetadata = {};
|
|
195
|
+
body.on('data', chunk => {
|
|
196
|
+
buffer += chunk.toString();
|
|
197
|
+
// Process complete lines
|
|
198
|
+
const lines = buffer.split('\n');
|
|
199
|
+
buffer = lines.pop() || ''; // Keep incomplete line in buffer
|
|
200
|
+
for (const line of lines) {
|
|
201
|
+
this.processSSELine(line, {
|
|
202
|
+
onChunk: chunk => {
|
|
203
|
+
// Aggregate content for final response
|
|
204
|
+
if (chunk.choices?.[0]?.delta?.content) {
|
|
205
|
+
aggregatedContent += chunk.choices[0].delta.content;
|
|
206
|
+
}
|
|
207
|
+
// Store metadata from first chunk
|
|
208
|
+
if (!responseMetadata.id) {
|
|
209
|
+
responseMetadata = {
|
|
210
|
+
id: chunk.id,
|
|
211
|
+
model: chunk.model,
|
|
212
|
+
created: chunk.created,
|
|
213
|
+
object: 'chat.completion',
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
// Forward chunk to callback
|
|
217
|
+
if (callbacks.onChunk) {
|
|
218
|
+
callbacks.onChunk(chunk);
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
onComplete: response => {
|
|
222
|
+
finalResponse = response;
|
|
223
|
+
},
|
|
224
|
+
onError: callbacks.onError || (() => { }),
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
body.on('end', () => {
|
|
229
|
+
// If we have a final response from [DONE], use it
|
|
230
|
+
if (finalResponse) {
|
|
231
|
+
if (callbacks.onComplete) {
|
|
232
|
+
callbacks.onComplete(finalResponse);
|
|
233
|
+
}
|
|
234
|
+
resolve(finalResponse);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
// Otherwise, construct final response from aggregated data
|
|
238
|
+
const constructedResponse = {
|
|
239
|
+
...responseMetadata,
|
|
240
|
+
choices: [
|
|
241
|
+
{
|
|
242
|
+
index: 0,
|
|
243
|
+
finish_reason: 'stop',
|
|
244
|
+
message: {
|
|
245
|
+
role: 'assistant',
|
|
246
|
+
content: aggregatedContent,
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
usage: {
|
|
251
|
+
prompt_tokens: 0,
|
|
252
|
+
completion_tokens: 0,
|
|
253
|
+
total_tokens: 0,
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
if (callbacks.onComplete) {
|
|
257
|
+
callbacks.onComplete(constructedResponse);
|
|
258
|
+
}
|
|
259
|
+
resolve(constructedResponse);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
body.on('error', error => {
|
|
263
|
+
if (callbacks.onError) {
|
|
264
|
+
callbacks.onError(error);
|
|
265
|
+
}
|
|
266
|
+
reject(error);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Processes a single Server-Sent Event line
|
|
272
|
+
*/
|
|
273
|
+
processSSELine(line, callbacks) {
|
|
274
|
+
if (!line.trim())
|
|
275
|
+
return;
|
|
276
|
+
// Handle SSE format: "data: {json}"
|
|
277
|
+
if (line.startsWith('data: ')) {
|
|
278
|
+
const data = line.slice(6).trim();
|
|
279
|
+
// Check for completion signal
|
|
280
|
+
if (data === '[DONE]') {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
try {
|
|
284
|
+
const chunk = JSON.parse(data);
|
|
285
|
+
if (callbacks.onChunk) {
|
|
286
|
+
callbacks.onChunk(chunk);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
console.warn('Failed to parse SSE chunk:', data, error);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Creates an async chat completion job
|
|
296
|
+
*/
|
|
297
|
+
async createAsyncChatCompletion(request) {
|
|
298
|
+
const requestBody = {
|
|
299
|
+
request: {
|
|
300
|
+
model: request.model,
|
|
301
|
+
messages: request.messages,
|
|
302
|
+
...(request.max_tokens && { max_tokens: request.max_tokens }),
|
|
303
|
+
...(request.temperature !== undefined && { temperature: request.temperature }),
|
|
304
|
+
...(request.top_p !== undefined && { top_p: request.top_p }),
|
|
305
|
+
...(request.search_domain_filter && { search_domain_filter: request.search_domain_filter }),
|
|
306
|
+
...(request.return_images !== undefined && { return_images: request.return_images }),
|
|
307
|
+
...(request.return_related_questions !== undefined && {
|
|
308
|
+
return_related_questions: request.return_related_questions,
|
|
309
|
+
}),
|
|
310
|
+
...(request.search_recency_filter && {
|
|
311
|
+
search_recency_filter: request.search_recency_filter,
|
|
312
|
+
}),
|
|
313
|
+
...(request.search_after_date_filter && {
|
|
314
|
+
search_after_date_filter: request.search_after_date_filter,
|
|
315
|
+
}),
|
|
316
|
+
...(request.search_before_date_filter && {
|
|
317
|
+
search_before_date_filter: request.search_before_date_filter,
|
|
318
|
+
}),
|
|
319
|
+
...(request.last_updated_after_filter && {
|
|
320
|
+
last_updated_after_filter: request.last_updated_after_filter,
|
|
321
|
+
}),
|
|
322
|
+
...(request.last_updated_before_filter && {
|
|
323
|
+
last_updated_before_filter: request.last_updated_before_filter,
|
|
324
|
+
}),
|
|
325
|
+
...(request.top_k !== undefined && { top_k: request.top_k }),
|
|
326
|
+
...(request.stream !== undefined && { stream: request.stream }),
|
|
327
|
+
...(request.presence_penalty !== undefined && {
|
|
328
|
+
presence_penalty: request.presence_penalty,
|
|
329
|
+
}),
|
|
330
|
+
...(request.frequency_penalty !== undefined && {
|
|
331
|
+
frequency_penalty: request.frequency_penalty,
|
|
332
|
+
}),
|
|
333
|
+
...(request.response_format && { response_format: request.response_format }),
|
|
334
|
+
...(request.disable_search !== undefined && { disable_search: request.disable_search }),
|
|
335
|
+
...(request.enable_search_classifier !== undefined && {
|
|
336
|
+
enable_search_classifier: request.enable_search_classifier,
|
|
337
|
+
}),
|
|
338
|
+
...(request.web_search_options && { web_search_options: request.web_search_options }),
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
return this.makeRequest(ASYNC_CHAT_COMPLETIONS_ENDPOINT, requestBody);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Alias for backward compatibility
|
|
345
|
+
*/
|
|
346
|
+
async createAsyncChat(request) {
|
|
347
|
+
return this.createAsyncChatCompletion(request);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Lists async chat completion jobs
|
|
351
|
+
*/
|
|
352
|
+
async listAsyncJobs(limit = 20, nextToken) {
|
|
353
|
+
const params = new URLSearchParams();
|
|
354
|
+
params.append('limit', limit.toString());
|
|
355
|
+
if (nextToken) {
|
|
356
|
+
params.append('next_token', encodeURIComponent(nextToken));
|
|
357
|
+
}
|
|
358
|
+
const endpoint = `${ASYNC_CHAT_COMPLETIONS_ENDPOINT}?${params.toString()}`;
|
|
359
|
+
return this.makeRequest(endpoint, null, 'GET');
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Gets the status and result of an async job
|
|
363
|
+
*/
|
|
364
|
+
async getAsyncJob(jobId) {
|
|
365
|
+
const endpoint = `${ASYNC_CHAT_COMPLETIONS_ENDPOINT}/${jobId}`;
|
|
366
|
+
return this.makeRequest(endpoint, null, 'GET');
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Handles API errors and creates structured error responses
|
|
370
|
+
*/
|
|
371
|
+
static handleError(error, context) {
|
|
372
|
+
if (error instanceof PerplexityApiError) {
|
|
373
|
+
// Rate limiting
|
|
374
|
+
if (error.status === 429) {
|
|
375
|
+
return {
|
|
376
|
+
error: {
|
|
377
|
+
type: 'rate_limit',
|
|
378
|
+
message: 'Rate limit exceeded',
|
|
379
|
+
details: {
|
|
380
|
+
suggestion: 'Wait before retrying or use async_perplexity for queuing',
|
|
381
|
+
retry_after: error.response?.headers?.['retry-after'] || 60,
|
|
382
|
+
...(context?.model && {
|
|
383
|
+
fallback_model: suggestFallbackModel(context.model, 'rate_limit'),
|
|
384
|
+
}),
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
// Invalid model
|
|
390
|
+
if (error.status === 400 && error.message.toLowerCase().includes('model')) {
|
|
391
|
+
return {
|
|
392
|
+
error: {
|
|
393
|
+
type: 'invalid_model',
|
|
394
|
+
message: `Invalid model: ${context?.model || 'unknown'}`,
|
|
395
|
+
details: {
|
|
396
|
+
suggestion: 'Use a supported model: sonar, sonar-pro, sonar-reasoning, sonar-reasoning-pro, sonar-deep-research',
|
|
397
|
+
fallback_model: 'sonar-reasoning-pro',
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
// Authentication error
|
|
403
|
+
if (error.status === 401) {
|
|
404
|
+
return {
|
|
405
|
+
error: {
|
|
406
|
+
type: 'api_error',
|
|
407
|
+
message: 'Authentication failed - check your API key',
|
|
408
|
+
details: {
|
|
409
|
+
suggestion: 'Verify your Perplexity API key is correct and has sufficient credits',
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
// Server error
|
|
415
|
+
if (error.status && error.status >= 500) {
|
|
416
|
+
return {
|
|
417
|
+
error: {
|
|
418
|
+
type: 'api_error',
|
|
419
|
+
message: 'Perplexity API server error',
|
|
420
|
+
details: {
|
|
421
|
+
suggestion: 'Try again later or use a different model',
|
|
422
|
+
fallback_model: context?.model ? suggestFallbackModel(context.model) : 'sonar',
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
// General API error
|
|
428
|
+
return {
|
|
429
|
+
error: {
|
|
430
|
+
type: 'api_error',
|
|
431
|
+
message: error.message || 'Unknown API error',
|
|
432
|
+
details: {
|
|
433
|
+
suggestion: 'Check your request parameters and try again',
|
|
434
|
+
fallback_model: context?.model
|
|
435
|
+
? suggestFallbackModel(context.model)
|
|
436
|
+
: 'sonar-reasoning-pro',
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
// Network or unknown error
|
|
442
|
+
return {
|
|
443
|
+
error: {
|
|
444
|
+
type: 'api_error',
|
|
445
|
+
message: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
446
|
+
details: {
|
|
447
|
+
suggestion: 'Check your internet connection and try again',
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
// Export alias for backward compatibility
|
|
454
|
+
export { PerplexityApiClient as PerplexityAPI };
|
|
455
|
+
//# sourceMappingURL=perplexity-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perplexity-api.js","sourceRoot":"","sources":["../src/perplexity-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAW/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,2BAA2B;AAC3B,MAAM,mBAAmB,GAAG,2BAA2B,CAAC;AACxD,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;AACtD,MAAM,+BAA+B,GAAG,yBAAyB,CAAC;AAElE,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAGlC;IACA;IAHT,YACE,OAAe,EACR,MAAe,EACf,QAAc;QAErB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,WAAM,GAAN,MAAM,CAAS;QACf,aAAQ,GAAR,QAAQ,CAAM;QAGrB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,mBAAmB;IACtB,MAAM,CAAS;IACf,OAAO,CAAS;IAExB,YAAY,MAAc;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,mBAAmB,CAAC;IACrC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,WAAW,CAAI,QAAgB,EAAE,IAAS,EAAE,MAAM,GAAG,MAAM;QACvE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAE5F,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM;gBACN,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;oBACtC,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;aACtD,CAAC,CAAC;YAEH,2CAA2C;YAC3C,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YACzD,IAAI,IAAS,CAAC;YAEd,IAAI,WAAW,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC9C,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,sDAAsD;gBACtD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnC,IAAI,GAAG,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,sBAAsB,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;YACnF,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,kBAAkB,CAC1B,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,EACxE,QAAQ,CAAC,MAAM,EACf,IAAI,CACL,CAAC;YACJ,CAAC;YAED,OAAO,IAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;gBACxC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,MAAM,IAAI,kBAAkB,CAAC,kBAAkB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAClE,CAAC;YAED,MAAM,IAAI,kBAAkB,CAAC,wBAAwB,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,OAA0B;QAC7C,8DAA8D;QAC9D,MAAM,WAAW,GAAG;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;YAC7D,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;YAC9E,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAC5D,GAAG,CAAC,OAAO,CAAC,oBAAoB,IAAI,EAAE,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,EAAE,CAAC;YAC3F,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;YACpF,GAAG,CAAC,OAAO,CAAC,wBAAwB,KAAK,SAAS,IAAI;gBACpD,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;aAC3D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,qBAAqB,IAAI;gBACnC,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;aACrD,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,wBAAwB,IAAI;gBACtC,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;aAC3D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,yBAAyB,IAAI;gBACvC,yBAAyB,EAAE,OAAO,CAAC,yBAAyB;aAC7D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,yBAAyB,IAAI;gBACvC,yBAAyB,EAAE,OAAO,CAAC,yBAAyB;aAC7D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,0BAA0B,IAAI;gBACxC,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;aAC/D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAC5D,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YAC/D,GAAG,CAAC,OAAO,CAAC,gBAAgB,KAAK,SAAS,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAC7F,GAAG,CAAC,OAAO,CAAC,iBAAiB,KAAK,SAAS,IAAI;gBAC7C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;aAC7C,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC;YAC5E,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;YACvF,GAAG,CAAC,OAAO,CAAC,wBAAwB,KAAK,SAAS,IAAI;gBACpD,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;aAC3D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC;SACtF,CAAC;QAEF,OAAO,IAAI,CAAC,WAAW,CAAqB,yBAAyB,EAAE,WAAW,CAAC,CAAC;IACtF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,oBAAoB,CACxB,OAA0B,EAC1B,SAA6B;QAE7B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,yBAAyB,EAAE,CAAC;QAE1D,uBAAuB;QACvB,MAAM,WAAW,GAAG;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,IAAI,EAAE,kBAAkB;YAChC,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;YAC7D,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;YAC9E,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAC5D,GAAG,CAAC,OAAO,CAAC,oBAAoB,IAAI,EAAE,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,EAAE,CAAC;YAC3F,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;YACpF,GAAG,CAAC,OAAO,CAAC,wBAAwB,KAAK,SAAS,IAAI;gBACpD,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;aAC3D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,qBAAqB,IAAI;gBACnC,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;aACrD,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,wBAAwB,IAAI;gBACtC,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;aAC3D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,yBAAyB,IAAI;gBACvC,yBAAyB,EAAE,OAAO,CAAC,yBAAyB;aAC7D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,yBAAyB,IAAI;gBACvC,yBAAyB,EAAE,OAAO,CAAC,yBAAyB;aAC7D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,0BAA0B,IAAI;gBACxC,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;aAC/D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAC5D,GAAG,CAAC,OAAO,CAAC,gBAAgB,KAAK,SAAS,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAC7F,GAAG,CAAC,OAAO,CAAC,iBAAiB,KAAK,SAAS,IAAI;gBAC7C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;aAC7C,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC;YAC5E,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;YACvF,GAAG,CAAC,OAAO,CAAC,wBAAwB,KAAK,SAAS,IAAI;gBACpD,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;aAC3D,CAAC;YACF,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC;SACtF,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;oBACtC,cAAc,EAAE,kBAAkB;oBAClC,MAAM,EAAE,mBAAmB;iBAC5B;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;aAClC,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxC,MAAM,IAAI,kBAAkB,CAC1B,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,EACjD,QAAQ,CAAC,MAAM,EACf,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,CAClC,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,kBAAkB,CAAC,2BAA2B,CAAC,CAAC;YAC5D,CAAC;YAED,uEAAuE;YACvE,6CAA6C;YAC7C,MAAM,UAAU,GAAG,QAAQ,CAAC,IAA2B,CAAC;YAExD,OAAO,IAAI,CAAC,wBAAwB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;gBACtB,SAAS,CAAC,OAAO,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAC3F,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,wBAAwB,CACpC,IAAc,EACd,SAA6B;QAE7B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,aAAa,GAA8B,IAAI,CAAC;YACpD,IAAI,iBAAiB,GAAG,EAAE,CAAC;YAC3B,IAAI,gBAAgB,GAAQ,EAAE,CAAC;YAE/B,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;gBACtB,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAE3B,yBAAyB;gBACzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,iCAAiC;gBAE7D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE;wBACxB,OAAO,EAAE,KAAK,CAAC,EAAE;4BACf,uCAAuC;4BACvC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;gCACvC,iBAAiB,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;4BACtD,CAAC;4BAED,kCAAkC;4BAClC,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC;gCACzB,gBAAgB,GAAG;oCACjB,EAAE,EAAE,KAAK,CAAC,EAAE;oCACZ,KAAK,EAAE,KAAK,CAAC,KAAK;oCAClB,OAAO,EAAE,KAAK,CAAC,OAAO;oCACtB,MAAM,EAAE,iBAAiB;iCAC1B,CAAC;4BACJ,CAAC;4BAED,4BAA4B;4BAC5B,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;gCACtB,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;4BAC3B,CAAC;wBACH,CAAC;wBACD,UAAU,EAAE,QAAQ,CAAC,EAAE;4BACrB,aAAa,GAAG,QAAQ,CAAC;wBAC3B,CAAC;wBACD,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;qBACzC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBAClB,kDAAkD;gBAClD,IAAI,aAAa,EAAE,CAAC;oBAClB,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;wBACzB,SAAS,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;oBACtC,CAAC;oBACD,OAAO,CAAC,aAAa,CAAC,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACN,2DAA2D;oBAC3D,MAAM,mBAAmB,GAAuB;wBAC9C,GAAG,gBAAgB;wBACnB,OAAO,EAAE;4BACP;gCACE,KAAK,EAAE,CAAC;gCACR,aAAa,EAAE,MAAM;gCACrB,OAAO,EAAE;oCACP,IAAI,EAAE,WAAW;oCACjB,OAAO,EAAE,iBAAiB;iCAC3B;6BACF;yBACF;wBACD,KAAK,EAAE;4BACL,aAAa,EAAE,CAAC;4BAChB,iBAAiB,EAAE,CAAC;4BACpB,YAAY,EAAE,CAAC;yBAChB;qBACF,CAAC;oBAEF,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;wBACzB,SAAS,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;oBAC5C,CAAC;oBACD,OAAO,CAAC,mBAAmB,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;gBACvB,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;oBACtB,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC3B,CAAC;gBACD,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,IAAY,EAAE,SAA6B;QAChE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO;QAEzB,oCAAoC;QACpC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAElC,8BAA8B;YAC9B,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,KAAK,GAA0B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACtD,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;oBACtB,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,yBAAyB,CAAC,OAA0B;QACxD,MAAM,WAAW,GAAG;YAClB,OAAO,EAAE;gBACP,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;gBAC7D,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;gBAC9E,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC5D,GAAG,CAAC,OAAO,CAAC,oBAAoB,IAAI,EAAE,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,EAAE,CAAC;gBAC3F,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;gBACpF,GAAG,CAAC,OAAO,CAAC,wBAAwB,KAAK,SAAS,IAAI;oBACpD,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;iBAC3D,CAAC;gBACF,GAAG,CAAC,OAAO,CAAC,qBAAqB,IAAI;oBACnC,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;iBACrD,CAAC;gBACF,GAAG,CAAC,OAAO,CAAC,wBAAwB,IAAI;oBACtC,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;iBAC3D,CAAC;gBACF,GAAG,CAAC,OAAO,CAAC,yBAAyB,IAAI;oBACvC,yBAAyB,EAAE,OAAO,CAAC,yBAAyB;iBAC7D,CAAC;gBACF,GAAG,CAAC,OAAO,CAAC,yBAAyB,IAAI;oBACvC,yBAAyB,EAAE,OAAO,CAAC,yBAAyB;iBAC7D,CAAC;gBACF,GAAG,CAAC,OAAO,CAAC,0BAA0B,IAAI;oBACxC,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;iBAC/D,CAAC;gBACF,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC5D,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC/D,GAAG,CAAC,OAAO,CAAC,gBAAgB,KAAK,SAAS,IAAI;oBAC5C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;iBAC3C,CAAC;gBACF,GAAG,CAAC,OAAO,CAAC,iBAAiB,KAAK,SAAS,IAAI;oBAC7C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;iBAC7C,CAAC;gBACF,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC;gBAC5E,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;gBACvF,GAAG,CAAC,OAAO,CAAC,wBAAwB,KAAK,SAAS,IAAI;oBACpD,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;iBAC3D,CAAC;gBACF,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC;aACtF;SACF,CAAC;QAEF,OAAO,IAAI,CAAC,WAAW,CAAW,+BAA+B,EAAE,WAAW,CAAC,CAAC;IAClF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,OAA0B;QAC9C,OAAO,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,KAAK,GAAG,EAAE,EACV,SAAkB;QAElB,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QACzC,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,+BAA+B,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC3E,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,MAAM,QAAQ,GAAG,GAAG,+BAA+B,IAAI,KAAK,EAAE,CAAC;QAC/D,OAAO,IAAI,CAAC,WAAW,CAAW,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,KAAc,EAAE,OAA4C;QAC7E,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;YACxC,gBAAgB;YAChB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACzB,OAAO;oBACL,KAAK,EAAE;wBACL,IAAI,EAAE,YAAY;wBAClB,OAAO,EAAE,qBAAqB;wBAC9B,OAAO,EAAE;4BACP,UAAU,EAAE,0DAA0D;4BACtE,WAAW,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE;4BAC3D,GAAG,CAAC,OAAO,EAAE,KAAK,IAAI;gCACpB,cAAc,EAAE,oBAAoB,CAAC,OAAO,CAAC,KAAY,EAAE,YAAY,CAAC;6BACzE,CAAC;yBACH;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,gBAAgB;YAChB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1E,OAAO;oBACL,KAAK,EAAE;wBACL,IAAI,EAAE,eAAe;wBACrB,OAAO,EAAE,kBAAkB,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE;wBACxD,OAAO,EAAE;4BACP,UAAU,EACR,oGAAoG;4BACtG,cAAc,EAAE,qBAAqB;yBACtC;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,uBAAuB;YACvB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACzB,OAAO;oBACL,KAAK,EAAE;wBACL,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,4CAA4C;wBACrD,OAAO,EAAE;4BACP,UAAU,EAAE,sEAAsE;yBACnF;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,eAAe;YACf,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBACxC,OAAO;oBACL,KAAK,EAAE;wBACL,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,6BAA6B;wBACtC,OAAO,EAAE;4BACP,UAAU,EAAE,0CAA0C;4BACtD,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,KAAY,CAAC,CAAC,CAAC,CAAC,OAAO;yBACtF;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,oBAAoB;YACpB,OAAO;gBACL,KAAK,EAAE;oBACL,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,mBAAmB;oBAC7C,OAAO,EAAE;wBACP,UAAU,EAAE,6CAA6C;wBACzD,cAAc,EAAE,OAAO,EAAE,KAAK;4BAC5B,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,KAAY,CAAC;4BAC5C,CAAC,CAAC,qBAAqB;qBAC1B;iBACF;aACF,CAAC;QACJ,CAAC;QAED,2BAA2B;QAC3B,OAAO;YACL,KAAK,EAAE;gBACL,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;gBAC1E,OAAO,EAAE;oBACP,UAAU,EAAE,8CAA8C;iBAC3D;aACF;SACF,CAAC;IACJ,CAAC;CACF;AAED,0CAA0C;AAC1C,OAAO,EAAE,mBAAmB,IAAI,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface PortDiscoveryResult {
|
|
2
|
+
port: number;
|
|
3
|
+
isExistingServer: boolean;
|
|
4
|
+
healthStatus?: 'healthy' | 'unhealthy';
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Checks if a port is available for binding
|
|
8
|
+
*/
|
|
9
|
+
export declare function isPortAvailable(port: number): Promise<boolean>;
|
|
10
|
+
/**
|
|
11
|
+
* Checks if an MCP server is running on the specified port
|
|
12
|
+
*/
|
|
13
|
+
export declare function checkMcpServerHealth(port: number): Promise<'healthy' | 'unhealthy' | 'not-running'>;
|
|
14
|
+
/**
|
|
15
|
+
* Discovers the best port to use for the MCP server
|
|
16
|
+
* Strategy:
|
|
17
|
+
* 1. Check if there's already a healthy MCP server running in the port range
|
|
18
|
+
* 2. If yes, return that port (shared server model)
|
|
19
|
+
* 3. If no, find the first available port in the range
|
|
20
|
+
* 4. If none available in range, throw an error
|
|
21
|
+
*/
|
|
22
|
+
export declare function discoverMcpPort(preferredPort?: number): Promise<PortDiscoveryResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Lists all ports in the MCP range and their status
|
|
25
|
+
*/
|
|
26
|
+
export declare function scanMcpPortRange(): Promise<Array<{
|
|
27
|
+
port: number;
|
|
28
|
+
available: boolean;
|
|
29
|
+
mcpHealth: 'healthy' | 'unhealthy' | 'not-running';
|
|
30
|
+
}>>;
|
|
31
|
+
//# sourceMappingURL=port-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-utils.d.ts","sourceRoot":"","sources":["../src/port-utils.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;CACxC;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUpE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC,CAkBlD;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA0D1F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAC/C,KAAK,CAAC;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;CACpD,CAAC,CACH,CAeA"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { createServer } from 'http';
|
|
2
|
+
// Port range for MCP server discovery (Claude Code uses 8124, Claude Desktop uses 8125)
|
|
3
|
+
const MCP_PORT_RANGE = { start: 8124, end: 8133 };
|
|
4
|
+
/**
|
|
5
|
+
* Checks if a port is available for binding
|
|
6
|
+
*/
|
|
7
|
+
export async function isPortAvailable(port) {
|
|
8
|
+
return new Promise(resolve => {
|
|
9
|
+
const server = createServer();
|
|
10
|
+
server.listen(port, () => {
|
|
11
|
+
server.close(() => resolve(true));
|
|
12
|
+
});
|
|
13
|
+
server.on('error', () => resolve(false));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Checks if an MCP server is running on the specified port
|
|
18
|
+
*/
|
|
19
|
+
export async function checkMcpServerHealth(port) {
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetch(`http://localhost:${port}/health`, {
|
|
22
|
+
method: 'GET',
|
|
23
|
+
signal: AbortSignal.timeout(2000), // 2 second timeout
|
|
24
|
+
});
|
|
25
|
+
if (response.ok) {
|
|
26
|
+
const health = await response.json();
|
|
27
|
+
return health.status === 'healthy' ? 'healthy' : 'unhealthy';
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
return 'unhealthy';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
// Port might be occupied by non-MCP service or not running
|
|
35
|
+
const available = await isPortAvailable(port);
|
|
36
|
+
return available ? 'not-running' : 'unhealthy';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Discovers the best port to use for the MCP server
|
|
41
|
+
* Strategy:
|
|
42
|
+
* 1. Check if there's already a healthy MCP server running in the port range
|
|
43
|
+
* 2. If yes, return that port (shared server model)
|
|
44
|
+
* 3. If no, find the first available port in the range
|
|
45
|
+
* 4. If none available in range, throw an error
|
|
46
|
+
*/
|
|
47
|
+
export async function discoverMcpPort(preferredPort) {
|
|
48
|
+
const debugMode = process.env.MCP_DEBUG_MODE === 'true';
|
|
49
|
+
const debugLog = debugMode ? console.log : console.error;
|
|
50
|
+
debugLog(`Discovering MCP server port (preferred: ${preferredPort || 'none'})`);
|
|
51
|
+
// First, check if preferred port has a healthy MCP server
|
|
52
|
+
if (preferredPort) {
|
|
53
|
+
const health = await checkMcpServerHealth(preferredPort);
|
|
54
|
+
if (health === 'healthy') {
|
|
55
|
+
debugLog(`Found healthy MCP server on preferred port ${preferredPort}`);
|
|
56
|
+
return {
|
|
57
|
+
port: preferredPort,
|
|
58
|
+
isExistingServer: true,
|
|
59
|
+
healthStatus: 'healthy',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Scan the entire port range for existing healthy MCP servers
|
|
64
|
+
for (let port = MCP_PORT_RANGE.start; port <= MCP_PORT_RANGE.end; port++) {
|
|
65
|
+
const health = await checkMcpServerHealth(port);
|
|
66
|
+
if (health === 'healthy') {
|
|
67
|
+
debugLog(`Found healthy MCP server on port ${port}`);
|
|
68
|
+
return {
|
|
69
|
+
port,
|
|
70
|
+
isExistingServer: true,
|
|
71
|
+
healthStatus: 'healthy',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// No existing healthy server found, find an available port
|
|
76
|
+
// Start with preferred port if specified and available
|
|
77
|
+
if (preferredPort && (await isPortAvailable(preferredPort))) {
|
|
78
|
+
debugLog(`Using preferred port ${preferredPort} (no existing server found)`);
|
|
79
|
+
return {
|
|
80
|
+
port: preferredPort,
|
|
81
|
+
isExistingServer: false,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// Find first available port in range
|
|
85
|
+
for (let port = MCP_PORT_RANGE.start; port <= MCP_PORT_RANGE.end; port++) {
|
|
86
|
+
if (await isPortAvailable(port)) {
|
|
87
|
+
debugLog(`Using available port ${port}`);
|
|
88
|
+
return {
|
|
89
|
+
port,
|
|
90
|
+
isExistingServer: false,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// No ports available in the range
|
|
95
|
+
throw new Error(`No available ports in MCP range ${MCP_PORT_RANGE.start}-${MCP_PORT_RANGE.end}. ` +
|
|
96
|
+
'Please free up a port or use a different range.');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Lists all ports in the MCP range and their status
|
|
100
|
+
*/
|
|
101
|
+
export async function scanMcpPortRange() {
|
|
102
|
+
const results = [];
|
|
103
|
+
for (let port = MCP_PORT_RANGE.start; port <= MCP_PORT_RANGE.end; port++) {
|
|
104
|
+
const available = await isPortAvailable(port);
|
|
105
|
+
const mcpHealth = available ? 'not-running' : await checkMcpServerHealth(port);
|
|
106
|
+
results.push({
|
|
107
|
+
port,
|
|
108
|
+
available,
|
|
109
|
+
mcpHealth,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return results;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=port-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-utils.js","sourceRoot":"","sources":["../src/port-utils.ts"],"names":[],"mappings":"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"}
|