opencode-cursor-proxy 1.0.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/LICENSE +21 -0
- package/README.md +139 -0
- package/README.zh-CN.md +136 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api/agent-service.d.ts +136 -0
- package/dist/lib/api/agent-service.js +938 -0
- package/dist/lib/api/agent-service.js.map +1 -0
- package/dist/lib/api/ai-service.d.ts +26 -0
- package/dist/lib/api/ai-service.js +38 -0
- package/dist/lib/api/ai-service.js.map +1 -0
- package/dist/lib/api/cursor-client.d.ts +119 -0
- package/dist/lib/api/cursor-client.js +511 -0
- package/dist/lib/api/cursor-client.js.map +1 -0
- package/dist/lib/api/cursor-models.d.ts +13 -0
- package/dist/lib/api/cursor-models.js +34 -0
- package/dist/lib/api/cursor-models.js.map +1 -0
- package/dist/lib/api/openai-compat.d.ts +10 -0
- package/dist/lib/api/openai-compat.js +262 -0
- package/dist/lib/api/openai-compat.js.map +1 -0
- package/dist/lib/api/proto/agent-messages.d.ts +25 -0
- package/dist/lib/api/proto/agent-messages.js +132 -0
- package/dist/lib/api/proto/agent-messages.js.map +1 -0
- package/dist/lib/api/proto/bidi.d.ts +17 -0
- package/dist/lib/api/proto/bidi.js +24 -0
- package/dist/lib/api/proto/bidi.js.map +1 -0
- package/dist/lib/api/proto/decoding.d.ts +19 -0
- package/dist/lib/api/proto/decoding.js +118 -0
- package/dist/lib/api/proto/decoding.js.map +1 -0
- package/dist/lib/api/proto/encoding.d.ts +64 -0
- package/dist/lib/api/proto/encoding.js +180 -0
- package/dist/lib/api/proto/encoding.js.map +1 -0
- package/dist/lib/api/proto/exec.d.ts +12 -0
- package/dist/lib/api/proto/exec.js +383 -0
- package/dist/lib/api/proto/exec.js.map +1 -0
- package/dist/lib/api/proto/index.d.ts +13 -0
- package/dist/lib/api/proto/index.js +10 -0
- package/dist/lib/api/proto/index.js.map +1 -0
- package/dist/lib/api/proto/interaction.d.ts +15 -0
- package/dist/lib/api/proto/interaction.js +99 -0
- package/dist/lib/api/proto/interaction.js.map +1 -0
- package/dist/lib/api/proto/kv.d.ts +52 -0
- package/dist/lib/api/proto/kv.js +156 -0
- package/dist/lib/api/proto/kv.js.map +1 -0
- package/dist/lib/api/proto/tool-calls.d.ts +9 -0
- package/dist/lib/api/proto/tool-calls.js +144 -0
- package/dist/lib/api/proto/tool-calls.js.map +1 -0
- package/dist/lib/api/proto/types.d.ts +201 -0
- package/dist/lib/api/proto/types.js +10 -0
- package/dist/lib/api/proto/types.js.map +1 -0
- package/dist/lib/auth/helpers.d.ts +40 -0
- package/dist/lib/auth/helpers.js +103 -0
- package/dist/lib/auth/helpers.js.map +1 -0
- package/dist/lib/auth/index.d.ts +7 -0
- package/dist/lib/auth/index.js +10 -0
- package/dist/lib/auth/index.js.map +1 -0
- package/dist/lib/auth/login.d.ts +55 -0
- package/dist/lib/auth/login.js +184 -0
- package/dist/lib/auth/login.js.map +1 -0
- package/dist/lib/config.d.ts +153 -0
- package/dist/lib/config.js +182 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/openai-compat/handler.d.ts +40 -0
- package/dist/lib/openai-compat/handler.js +808 -0
- package/dist/lib/openai-compat/handler.js.map +1 -0
- package/dist/lib/openai-compat/index.d.ts +9 -0
- package/dist/lib/openai-compat/index.js +13 -0
- package/dist/lib/openai-compat/index.js.map +1 -0
- package/dist/lib/openai-compat/types.d.ts +127 -0
- package/dist/lib/openai-compat/types.js +6 -0
- package/dist/lib/openai-compat/types.js.map +1 -0
- package/dist/lib/openai-compat/utils.d.ts +143 -0
- package/dist/lib/openai-compat/utils.js +348 -0
- package/dist/lib/openai-compat/utils.js.map +1 -0
- package/dist/lib/session-reuse.d.ts +88 -0
- package/dist/lib/session-reuse.js +198 -0
- package/dist/lib/session-reuse.js.map +1 -0
- package/dist/lib/storage.d.ts +55 -0
- package/dist/lib/storage.js +159 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/lib/utils/cache.d.ts +131 -0
- package/dist/lib/utils/cache.js +297 -0
- package/dist/lib/utils/cache.js.map +1 -0
- package/dist/lib/utils/fetch.d.ts +84 -0
- package/dist/lib/utils/fetch.js +261 -0
- package/dist/lib/utils/fetch.js.map +1 -0
- package/dist/lib/utils/index.d.ts +13 -0
- package/dist/lib/utils/index.js +22 -0
- package/dist/lib/utils/index.js.map +1 -0
- package/dist/lib/utils/jwt.d.ts +40 -0
- package/dist/lib/utils/jwt.js +102 -0
- package/dist/lib/utils/jwt.js.map +1 -0
- package/dist/lib/utils/logger.d.ts +107 -0
- package/dist/lib/utils/logger.js +227 -0
- package/dist/lib/utils/logger.js.map +1 -0
- package/dist/lib/utils/model-resolver.d.ts +49 -0
- package/dist/lib/utils/model-resolver.js +503 -0
- package/dist/lib/utils/model-resolver.js.map +1 -0
- package/dist/lib/utils/request-pool.d.ts +38 -0
- package/dist/lib/utils/request-pool.js +105 -0
- package/dist/lib/utils/request-pool.js.map +1 -0
- package/dist/lib/utils/request-transformer.d.ts +87 -0
- package/dist/lib/utils/request-transformer.js +154 -0
- package/dist/lib/utils/request-transformer.js.map +1 -0
- package/dist/lib/utils/tokenizer.d.ts +14 -0
- package/dist/lib/utils/tokenizer.js +76 -0
- package/dist/lib/utils/tokenizer.js.map +1 -0
- package/dist/plugin/index.d.ts +8 -0
- package/dist/plugin/index.js +9 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/plugin.d.ts +21 -0
- package/dist/plugin/plugin.js +309 -0
- package/dist/plugin/plugin.js.map +1 -0
- package/dist/plugin/types.d.ts +120 -0
- package/dist/plugin/types.js +7 -0
- package/dist/plugin/types.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.js +95 -0
- package/dist/server.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch Utilities with Retry Support
|
|
3
|
+
*
|
|
4
|
+
* Provides robust HTTP request handling with:
|
|
5
|
+
* - Exponential backoff retry
|
|
6
|
+
* - Timeout support
|
|
7
|
+
* - Transient error detection
|
|
8
|
+
* - Request/response logging
|
|
9
|
+
*/
|
|
10
|
+
import { type Logger } from "./logger";
|
|
11
|
+
export interface RetryOptions {
|
|
12
|
+
/** Maximum number of retry attempts (default: from config) */
|
|
13
|
+
maxRetries?: number;
|
|
14
|
+
/** Base delay for exponential backoff in ms (default: from config) */
|
|
15
|
+
baseDelayMs?: number;
|
|
16
|
+
/** Maximum delay between retries in ms (default: from config) */
|
|
17
|
+
maxDelayMs?: number;
|
|
18
|
+
/** Request timeout in ms (default: from config) */
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
/** Custom retry condition (default: retry on 5xx and network errors) */
|
|
21
|
+
shouldRetry?: (error: Error, attempt: number, response?: Response) => boolean;
|
|
22
|
+
/** Logger instance for this request */
|
|
23
|
+
logger?: Logger;
|
|
24
|
+
}
|
|
25
|
+
export interface FetchWithRetryResult {
|
|
26
|
+
response: Response;
|
|
27
|
+
attempts: number;
|
|
28
|
+
totalTimeMs: number;
|
|
29
|
+
}
|
|
30
|
+
export declare class FetchTimeoutError extends Error {
|
|
31
|
+
constructor(timeoutMs: number);
|
|
32
|
+
}
|
|
33
|
+
export declare class FetchRetryExhaustedError extends Error {
|
|
34
|
+
lastError: Error;
|
|
35
|
+
attempts: number;
|
|
36
|
+
constructor(lastError: Error, attempts: number);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Sleep for a specified duration
|
|
40
|
+
*/
|
|
41
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Calculate delay with exponential backoff and jitter
|
|
44
|
+
*/
|
|
45
|
+
export declare function calculateBackoffDelay(attempt: number, baseDelayMs: number, maxDelayMs: number): number;
|
|
46
|
+
/**
|
|
47
|
+
* Check if an error is a transient network error that should be retried
|
|
48
|
+
*/
|
|
49
|
+
export declare function isTransientError(error: Error): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Check if a response status code indicates a retryable error
|
|
52
|
+
*/
|
|
53
|
+
export declare function isRetryableStatus(status: number): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Default retry condition
|
|
56
|
+
*/
|
|
57
|
+
export declare function defaultShouldRetry(error: Error, _attempt: number, response?: Response): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Fetch with automatic retry and timeout support
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* // Basic usage
|
|
64
|
+
* const { response } = await fetchWithRetry("https://api.example.com/data");
|
|
65
|
+
*
|
|
66
|
+
* // With options
|
|
67
|
+
* const { response, attempts } = await fetchWithRetry("https://api.example.com/data", {
|
|
68
|
+
* method: "POST",
|
|
69
|
+
* body: JSON.stringify({ data: "value" }),
|
|
70
|
+
* }, {
|
|
71
|
+
* maxRetries: 5,
|
|
72
|
+
* timeoutMs: 30000,
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare function fetchWithRetry(input: string | URL | Request, init?: RequestInit, options?: RetryOptions): Promise<FetchWithRetryResult>;
|
|
77
|
+
/**
|
|
78
|
+
* Simple fetch wrapper that respects retry config but returns just the Response
|
|
79
|
+
*/
|
|
80
|
+
export declare function robustFetch(input: string | URL | Request, init?: RequestInit, options?: RetryOptions): Promise<Response>;
|
|
81
|
+
/**
|
|
82
|
+
* Fetch JSON with retry support
|
|
83
|
+
*/
|
|
84
|
+
export declare function fetchJson<T>(input: string | URL | Request, init?: RequestInit, options?: RetryOptions): Promise<T>;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch Utilities with Retry Support
|
|
3
|
+
*
|
|
4
|
+
* Provides robust HTTP request handling with:
|
|
5
|
+
* - Exponential backoff retry
|
|
6
|
+
* - Timeout support
|
|
7
|
+
* - Transient error detection
|
|
8
|
+
* - Request/response logging
|
|
9
|
+
*/
|
|
10
|
+
import { config } from "../config";
|
|
11
|
+
import { createLogger, createTimer } from "./logger";
|
|
12
|
+
const logger = createLogger("fetch");
|
|
13
|
+
// --- Error Types ---
|
|
14
|
+
export class FetchTimeoutError extends Error {
|
|
15
|
+
constructor(timeoutMs) {
|
|
16
|
+
super(`Request timed out after ${timeoutMs}ms`);
|
|
17
|
+
this.name = "FetchTimeoutError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class FetchRetryExhaustedError extends Error {
|
|
21
|
+
lastError;
|
|
22
|
+
attempts;
|
|
23
|
+
constructor(lastError, attempts) {
|
|
24
|
+
super(`Request failed after ${attempts} attempts: ${lastError.message}`);
|
|
25
|
+
this.name = "FetchRetryExhaustedError";
|
|
26
|
+
this.lastError = lastError;
|
|
27
|
+
this.attempts = attempts;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// --- Utility Functions ---
|
|
31
|
+
/**
|
|
32
|
+
* Sleep for a specified duration
|
|
33
|
+
*/
|
|
34
|
+
export function sleep(ms) {
|
|
35
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Calculate delay with exponential backoff and jitter
|
|
39
|
+
*/
|
|
40
|
+
export function calculateBackoffDelay(attempt, baseDelayMs, maxDelayMs) {
|
|
41
|
+
// Exponential backoff: baseDelay * 2^attempt
|
|
42
|
+
const exponentialDelay = baseDelayMs * Math.pow(2, attempt);
|
|
43
|
+
// Add jitter (0-25% of delay)
|
|
44
|
+
const jitter = exponentialDelay * Math.random() * 0.25;
|
|
45
|
+
// Cap at max delay
|
|
46
|
+
return Math.min(exponentialDelay + jitter, maxDelayMs);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if an error is a transient network error that should be retried
|
|
50
|
+
*/
|
|
51
|
+
export function isTransientError(error) {
|
|
52
|
+
const transientCodes = [
|
|
53
|
+
"ECONNRESET",
|
|
54
|
+
"ECONNREFUSED",
|
|
55
|
+
"ETIMEDOUT",
|
|
56
|
+
"ENOTFOUND",
|
|
57
|
+
"EAI_AGAIN",
|
|
58
|
+
"EPIPE",
|
|
59
|
+
"EHOSTUNREACH",
|
|
60
|
+
"ENETUNREACH",
|
|
61
|
+
];
|
|
62
|
+
const message = error.message.toLowerCase();
|
|
63
|
+
const name = error.name;
|
|
64
|
+
// Check for known transient error codes
|
|
65
|
+
if (transientCodes.some((code) => message.includes(code.toLowerCase()))) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
// Check for fetch-specific errors
|
|
69
|
+
if (name === "FetchError" || name === "AbortError") {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
// Check for timeout
|
|
73
|
+
if (name === "FetchTimeoutError") {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Check if a response status code indicates a retryable error
|
|
80
|
+
*/
|
|
81
|
+
export function isRetryableStatus(status) {
|
|
82
|
+
// Retry on server errors (5xx) except 501 (Not Implemented)
|
|
83
|
+
if (status >= 500 && status !== 501) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
// Retry on rate limiting
|
|
87
|
+
if (status === 429) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
// Retry on request timeout
|
|
91
|
+
if (status === 408) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Default retry condition
|
|
98
|
+
*/
|
|
99
|
+
export function defaultShouldRetry(error, _attempt, response) {
|
|
100
|
+
// Always retry transient network errors
|
|
101
|
+
if (isTransientError(error)) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
// Retry on retryable status codes
|
|
105
|
+
if (response && isRetryableStatus(response.status)) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
// --- Main Fetch Function ---
|
|
111
|
+
/**
|
|
112
|
+
* Fetch with automatic retry and timeout support
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* // Basic usage
|
|
117
|
+
* const { response } = await fetchWithRetry("https://api.example.com/data");
|
|
118
|
+
*
|
|
119
|
+
* // With options
|
|
120
|
+
* const { response, attempts } = await fetchWithRetry("https://api.example.com/data", {
|
|
121
|
+
* method: "POST",
|
|
122
|
+
* body: JSON.stringify({ data: "value" }),
|
|
123
|
+
* }, {
|
|
124
|
+
* maxRetries: 5,
|
|
125
|
+
* timeoutMs: 30000,
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export async function fetchWithRetry(input, init, options) {
|
|
130
|
+
const { maxRetries = config.network.maxRetries, baseDelayMs = config.network.retryBaseDelayMs, maxDelayMs = config.network.retryMaxDelayMs, timeoutMs = config.network.requestTimeoutMs, shouldRetry = defaultShouldRetry, logger: requestLogger = logger, } = options ?? {};
|
|
131
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
132
|
+
const method = init?.method ?? "GET";
|
|
133
|
+
const timer = createTimer();
|
|
134
|
+
let lastError = new Error("No attempts made");
|
|
135
|
+
let lastResponse;
|
|
136
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
137
|
+
const controller = new AbortController();
|
|
138
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
139
|
+
try {
|
|
140
|
+
requestLogger.debug(`Attempt ${attempt + 1}/${maxRetries + 1}`, {
|
|
141
|
+
method,
|
|
142
|
+
url: url.substring(0, 100),
|
|
143
|
+
});
|
|
144
|
+
const response = await fetch(input, {
|
|
145
|
+
...init,
|
|
146
|
+
signal: controller.signal,
|
|
147
|
+
});
|
|
148
|
+
clearTimeout(timeoutId);
|
|
149
|
+
// Success - return immediately
|
|
150
|
+
if (response.ok) {
|
|
151
|
+
requestLogger.debug(`Request succeeded`, {
|
|
152
|
+
method,
|
|
153
|
+
status: response.status,
|
|
154
|
+
attempts: attempt + 1,
|
|
155
|
+
durationMs: timer(),
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
response,
|
|
159
|
+
attempts: attempt + 1,
|
|
160
|
+
totalTimeMs: timer(),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
// Non-OK response - check if retryable
|
|
164
|
+
lastResponse = response;
|
|
165
|
+
lastError = new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
166
|
+
if (!shouldRetry(lastError, attempt, response) || attempt === maxRetries) {
|
|
167
|
+
// Don't retry - return the response as-is
|
|
168
|
+
requestLogger.debug(`Request returned non-OK status`, {
|
|
169
|
+
method,
|
|
170
|
+
status: response.status,
|
|
171
|
+
attempts: attempt + 1,
|
|
172
|
+
willRetry: false,
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
response,
|
|
176
|
+
attempts: attempt + 1,
|
|
177
|
+
totalTimeMs: timer(),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// Will retry - log and continue
|
|
181
|
+
requestLogger.warn(`Request failed, will retry`, {
|
|
182
|
+
method,
|
|
183
|
+
status: response.status,
|
|
184
|
+
attempt: attempt + 1,
|
|
185
|
+
maxRetries,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
clearTimeout(timeoutId);
|
|
190
|
+
// Handle abort (timeout)
|
|
191
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
192
|
+
lastError = new FetchTimeoutError(timeoutMs);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
196
|
+
}
|
|
197
|
+
// Check if should retry
|
|
198
|
+
if (!shouldRetry(lastError, attempt, undefined) || attempt === maxRetries) {
|
|
199
|
+
requestLogger.error(`Request failed`, {
|
|
200
|
+
method,
|
|
201
|
+
error: lastError.message,
|
|
202
|
+
attempts: attempt + 1,
|
|
203
|
+
willRetry: false,
|
|
204
|
+
});
|
|
205
|
+
throw new FetchRetryExhaustedError(lastError, attempt + 1);
|
|
206
|
+
}
|
|
207
|
+
requestLogger.warn(`Request error, will retry`, {
|
|
208
|
+
method,
|
|
209
|
+
error: lastError.message,
|
|
210
|
+
attempt: attempt + 1,
|
|
211
|
+
maxRetries,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
// Calculate and wait for backoff delay
|
|
215
|
+
if (attempt < maxRetries) {
|
|
216
|
+
const delay = calculateBackoffDelay(attempt, baseDelayMs, maxDelayMs);
|
|
217
|
+
requestLogger.debug(`Waiting before retry`, { delayMs: Math.round(delay) });
|
|
218
|
+
await sleep(delay);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Should not reach here, but just in case
|
|
222
|
+
throw new FetchRetryExhaustedError(lastError, maxRetries + 1);
|
|
223
|
+
}
|
|
224
|
+
// --- Convenience Functions ---
|
|
225
|
+
/**
|
|
226
|
+
* Simple fetch wrapper that respects retry config but returns just the Response
|
|
227
|
+
*/
|
|
228
|
+
export async function robustFetch(input, init, options) {
|
|
229
|
+
if (!config.network.retryEnabled) {
|
|
230
|
+
// Retry disabled - use standard fetch with timeout only
|
|
231
|
+
const timeoutMs = options?.timeoutMs ?? config.network.requestTimeoutMs;
|
|
232
|
+
const controller = new AbortController();
|
|
233
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
234
|
+
try {
|
|
235
|
+
const response = await fetch(input, { ...init, signal: controller.signal });
|
|
236
|
+
clearTimeout(timeoutId);
|
|
237
|
+
return response;
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
clearTimeout(timeoutId);
|
|
241
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
242
|
+
throw new FetchTimeoutError(timeoutMs);
|
|
243
|
+
}
|
|
244
|
+
throw err;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const { response } = await fetchWithRetry(input, init, options);
|
|
248
|
+
return response;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Fetch JSON with retry support
|
|
252
|
+
*/
|
|
253
|
+
export async function fetchJson(input, init, options) {
|
|
254
|
+
const response = await robustFetch(input, init, options);
|
|
255
|
+
if (!response.ok) {
|
|
256
|
+
const text = await response.text();
|
|
257
|
+
throw new Error(`HTTP ${response.status}: ${text}`);
|
|
258
|
+
}
|
|
259
|
+
return response.json();
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/lib/utils/fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities Module Index
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all utility modules for convenient importing.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./jwt";
|
|
7
|
+
export * from "./tokenizer";
|
|
8
|
+
export * from "./logger";
|
|
9
|
+
export * from "./fetch";
|
|
10
|
+
export * from "./cache";
|
|
11
|
+
export * from "./model-resolver";
|
|
12
|
+
export * from "./request-pool";
|
|
13
|
+
export * from "./request-transformer";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities Module Index
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all utility modules for convenient importing.
|
|
5
|
+
*/
|
|
6
|
+
// JWT utilities
|
|
7
|
+
export * from "./jwt";
|
|
8
|
+
// Tokenizer utilities
|
|
9
|
+
export * from "./tokenizer";
|
|
10
|
+
// Logger utilities
|
|
11
|
+
export * from "./logger";
|
|
12
|
+
// Fetch utilities with retry
|
|
13
|
+
export * from "./fetch";
|
|
14
|
+
// Cache utilities
|
|
15
|
+
export * from "./cache";
|
|
16
|
+
// Model resolver utilities
|
|
17
|
+
export * from "./model-resolver";
|
|
18
|
+
// Request pool utilities
|
|
19
|
+
export * from "./request-pool";
|
|
20
|
+
// Request transformer utilities
|
|
21
|
+
export * from "./request-transformer";
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/utils/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gBAAgB;AAChB,cAAc,OAAO,CAAC;AAEtB,sBAAsB;AACtB,cAAc,aAAa,CAAC;AAE5B,mBAAmB;AACnB,cAAc,UAAU,CAAC;AAEzB,6BAA6B;AAC7B,cAAc,SAAS,CAAC;AAExB,kBAAkB;AAClB,cAAc,SAAS,CAAC;AAExB,2BAA2B;AAC3B,cAAc,kBAAkB,CAAC;AAEjC,yBAAyB;AACzB,cAAc,gBAAgB,CAAC;AAE/B,gCAAgC;AAChC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JWT Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides functions for decoding and validating JWT tokens.
|
|
5
|
+
* NOTE: These functions do NOT verify signatures - they are for
|
|
6
|
+
* expiration checking and display purposes only.
|
|
7
|
+
*/
|
|
8
|
+
export interface JwtPayload {
|
|
9
|
+
sub?: string;
|
|
10
|
+
exp?: number;
|
|
11
|
+
iat?: number;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Decode JWT payload without signature verification.
|
|
16
|
+
* ONLY for expiration checking and display purposes.
|
|
17
|
+
*/
|
|
18
|
+
export declare function decodeJwtPayload(token: string): JwtPayload | null;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a token is expiring soon (within threshold seconds).
|
|
21
|
+
* Default threshold is 5 minutes (300 seconds).
|
|
22
|
+
*/
|
|
23
|
+
export declare function isTokenExpiringSoon(token: string, thresholdSeconds?: number): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Check if a token has expired.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isTokenExpired(token: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Get the time remaining until token expiration in seconds.
|
|
30
|
+
* Returns negative value if expired.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getTokenTimeRemaining(token: string): number;
|
|
33
|
+
/**
|
|
34
|
+
* Format seconds into human-readable duration.
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatDuration(seconds: number): string;
|
|
37
|
+
/**
|
|
38
|
+
* Mask sensitive token data for display.
|
|
39
|
+
*/
|
|
40
|
+
export declare function maskToken(token: string | undefined): string;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JWT Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides functions for decoding and validating JWT tokens.
|
|
5
|
+
* NOTE: These functions do NOT verify signatures - they are for
|
|
6
|
+
* expiration checking and display purposes only.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Decode JWT payload without signature verification.
|
|
10
|
+
* ONLY for expiration checking and display purposes.
|
|
11
|
+
*/
|
|
12
|
+
export function decodeJwtPayload(token) {
|
|
13
|
+
try {
|
|
14
|
+
const parts = token.split(".");
|
|
15
|
+
if (parts.length !== 3)
|
|
16
|
+
return null;
|
|
17
|
+
const base64Payload = parts[1];
|
|
18
|
+
if (!base64Payload)
|
|
19
|
+
return null;
|
|
20
|
+
// Handle base64url encoding
|
|
21
|
+
const base64 = base64Payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
22
|
+
const payloadBuffer = Buffer.from(base64, "base64");
|
|
23
|
+
return JSON.parse(payloadBuffer.toString("utf-8"));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if a token is expiring soon (within threshold seconds).
|
|
31
|
+
* Default threshold is 5 minutes (300 seconds).
|
|
32
|
+
*/
|
|
33
|
+
export function isTokenExpiringSoon(token, thresholdSeconds = 300) {
|
|
34
|
+
try {
|
|
35
|
+
const decoded = decodeJwtPayload(token);
|
|
36
|
+
if (!decoded || typeof decoded.exp !== "number")
|
|
37
|
+
return true;
|
|
38
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
39
|
+
const expirationTime = decoded.exp;
|
|
40
|
+
const timeLeft = expirationTime - currentTime;
|
|
41
|
+
return timeLeft < thresholdSeconds;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if a token has expired.
|
|
49
|
+
*/
|
|
50
|
+
export function isTokenExpired(token) {
|
|
51
|
+
try {
|
|
52
|
+
const decoded = decodeJwtPayload(token);
|
|
53
|
+
if (!decoded || typeof decoded.exp !== "number")
|
|
54
|
+
return true;
|
|
55
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
56
|
+
return decoded.exp < currentTime;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get the time remaining until token expiration in seconds.
|
|
64
|
+
* Returns negative value if expired.
|
|
65
|
+
*/
|
|
66
|
+
export function getTokenTimeRemaining(token) {
|
|
67
|
+
try {
|
|
68
|
+
const decoded = decodeJwtPayload(token);
|
|
69
|
+
if (!decoded || typeof decoded.exp !== "number")
|
|
70
|
+
return -1;
|
|
71
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
72
|
+
return decoded.exp - currentTime;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return -1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Format seconds into human-readable duration.
|
|
80
|
+
*/
|
|
81
|
+
export function formatDuration(seconds) {
|
|
82
|
+
if (seconds < 0)
|
|
83
|
+
return "expired";
|
|
84
|
+
if (seconds < 60)
|
|
85
|
+
return `${seconds}s`;
|
|
86
|
+
if (seconds < 3600)
|
|
87
|
+
return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
|
|
88
|
+
const hours = Math.floor(seconds / 3600);
|
|
89
|
+
const mins = Math.floor((seconds % 3600) / 60);
|
|
90
|
+
return `${hours}h ${mins}m`;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Mask sensitive token data for display.
|
|
94
|
+
*/
|
|
95
|
+
export function maskToken(token) {
|
|
96
|
+
if (!token)
|
|
97
|
+
return "(not set)";
|
|
98
|
+
if (token.length < 20)
|
|
99
|
+
return "***";
|
|
100
|
+
return `${token.substring(0, 10)}...${token.substring(token.length - 10)}`;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=jwt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../../src/lib/utils/jwt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured Logger Module
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent logging across the application with:
|
|
5
|
+
* - Log levels (error, warn, info, debug)
|
|
6
|
+
* - Structured metadata
|
|
7
|
+
* - Optional JSON output
|
|
8
|
+
* - Child loggers with context
|
|
9
|
+
*/
|
|
10
|
+
export type LogLevel = "error" | "warn" | "info" | "debug";
|
|
11
|
+
export interface LogMeta {
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface Logger {
|
|
15
|
+
error(message: string, meta?: LogMeta): void;
|
|
16
|
+
warn(message: string, meta?: LogMeta): void;
|
|
17
|
+
info(message: string, meta?: LogMeta): void;
|
|
18
|
+
debug(message: string, meta?: LogMeta): void;
|
|
19
|
+
child(bindings: LogMeta): Logger;
|
|
20
|
+
timing(label: string, durationMs: number, meta?: LogMeta): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a new logger instance
|
|
24
|
+
*/
|
|
25
|
+
export declare function createLogger(name?: string, bindings?: LogMeta): Logger;
|
|
26
|
+
/**
|
|
27
|
+
* Create a child logger with additional context
|
|
28
|
+
*/
|
|
29
|
+
export declare function createChildLogger(parent: Logger, bindings: LogMeta): Logger;
|
|
30
|
+
/**
|
|
31
|
+
* Default logger instance for general use
|
|
32
|
+
*/
|
|
33
|
+
export declare const logger: Logger;
|
|
34
|
+
/**
|
|
35
|
+
* Logger for API operations
|
|
36
|
+
*/
|
|
37
|
+
export declare const apiLogger: Logger;
|
|
38
|
+
/**
|
|
39
|
+
* Logger for authentication operations
|
|
40
|
+
*/
|
|
41
|
+
export declare const authLogger: Logger;
|
|
42
|
+
/**
|
|
43
|
+
* Logger for OpenAI compatibility layer
|
|
44
|
+
*/
|
|
45
|
+
export declare const openaiLogger: Logger;
|
|
46
|
+
/**
|
|
47
|
+
* Logger for session management
|
|
48
|
+
*/
|
|
49
|
+
export declare const sessionLogger: Logger;
|
|
50
|
+
/**
|
|
51
|
+
* Logger for request transformation
|
|
52
|
+
*/
|
|
53
|
+
export declare const transformLogger: Logger;
|
|
54
|
+
export interface TransformLogData {
|
|
55
|
+
originalCount: number;
|
|
56
|
+
filteredCount: number;
|
|
57
|
+
itemReferencesFiltered: number;
|
|
58
|
+
idsStripped: number;
|
|
59
|
+
strippedIds?: string[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Log request transformation statistics
|
|
63
|
+
* Only logs when CURSOR_LOG_FILTERED_IDS or CURSOR_DEBUG is enabled
|
|
64
|
+
*/
|
|
65
|
+
export declare function logRequestTransform(data: TransformLogData): void;
|
|
66
|
+
export interface MultimodalLogData {
|
|
67
|
+
messageIndex: number;
|
|
68
|
+
imageCount: number;
|
|
69
|
+
hasBase64: boolean;
|
|
70
|
+
modelSupportsVision: boolean;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Log multimodal content detection
|
|
74
|
+
* Only logs when CURSOR_LOG_MULTIMODAL or CURSOR_DEBUG is enabled
|
|
75
|
+
*/
|
|
76
|
+
export declare function logMultimodalContent(data: MultimodalLogData): void;
|
|
77
|
+
/**
|
|
78
|
+
* Log incoming request details
|
|
79
|
+
* Only logs when CURSOR_REQUEST_LOGGING or CURSOR_DEBUG is enabled
|
|
80
|
+
*/
|
|
81
|
+
export declare function logRequest(method: string, path: string, body?: {
|
|
82
|
+
model?: string;
|
|
83
|
+
messageCount?: number;
|
|
84
|
+
hasTools?: boolean;
|
|
85
|
+
stream?: boolean;
|
|
86
|
+
}): void;
|
|
87
|
+
/**
|
|
88
|
+
* Log response details
|
|
89
|
+
* Only logs when CURSOR_REQUEST_LOGGING or CURSOR_DEBUG is enabled
|
|
90
|
+
*/
|
|
91
|
+
export declare function logResponse(status: number, durationMs: number, details?: {
|
|
92
|
+
model?: string;
|
|
93
|
+
finishReason?: string;
|
|
94
|
+
tokenUsage?: {
|
|
95
|
+
prompt: number;
|
|
96
|
+
completion: number;
|
|
97
|
+
total: number;
|
|
98
|
+
};
|
|
99
|
+
}): void;
|
|
100
|
+
/**
|
|
101
|
+
* Create a timer for measuring operation duration
|
|
102
|
+
*/
|
|
103
|
+
export declare function createTimer(): () => number;
|
|
104
|
+
/**
|
|
105
|
+
* Measure and log the duration of an async operation
|
|
106
|
+
*/
|
|
107
|
+
export declare function withTiming<T>(logger: Logger, label: string, operation: () => Promise<T>, meta?: LogMeta): Promise<T>;
|