@iamtoricool/opencool-qwen-auth 0.0.1-alpha → 0.0.3-alpha
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/lib/auth/auth.d.ts +72 -0
- package/dist/lib/auth/auth.d.ts.map +1 -0
- package/dist/lib/auth/auth.js +212 -0
- package/dist/lib/auth/auth.js.map +1 -0
- package/dist/lib/auth/browser-session.d.ts +49 -0
- package/dist/lib/auth/browser-session.d.ts.map +1 -0
- package/dist/lib/auth/browser-session.js +211 -0
- package/dist/lib/auth/browser-session.js.map +1 -0
- package/dist/lib/auth/browser.d.ts +17 -0
- package/dist/lib/auth/browser.d.ts.map +1 -0
- package/dist/lib/auth/browser.js +86 -0
- package/dist/lib/auth/browser.js.map +1 -0
- package/dist/lib/auth/server.d.ts +14 -0
- package/dist/lib/auth/server.d.ts.map +1 -0
- package/dist/lib/auth/server.js +253 -0
- package/dist/lib/auth/server.js.map +1 -0
- package/dist/lib/config.d.ts +28 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +67 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +77 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +109 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/logger.d.ts +49 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +56 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/oauth-success.html +83 -0
- package/dist/lib/request/fetch-helpers.d.ts +66 -0
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -0
- package/dist/lib/request/fetch-helpers.js +193 -0
- package/dist/lib/request/fetch-helpers.js.map +1 -0
- package/dist/lib/request/request-transformer.d.ts +27 -0
- package/dist/lib/request/request-transformer.d.ts.map +1 -0
- package/dist/lib/request/request-transformer.js +159 -0
- package/dist/lib/request/request-transformer.js.map +1 -0
- package/dist/lib/request/response-handler.d.ts +32 -0
- package/dist/lib/request/response-handler.d.ts.map +1 -0
- package/dist/lib/request/response-handler.js +176 -0
- package/dist/lib/request/response-handler.js.map +1 -0
- package/dist/lib/types.d.ts +159 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +5 -0
- package/dist/lib/types.js.map +1 -0
- package/iamtoricool-opencool-qwen-auth-0.0.1-alpha.tgz +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging utilities for the Qwen Auth Plugin
|
|
3
|
+
*/
|
|
4
|
+
import type { PluginConfig } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Logger instance for the plugin
|
|
7
|
+
*/
|
|
8
|
+
export interface Logger {
|
|
9
|
+
debug: (message: string, ...args: unknown[]) => void;
|
|
10
|
+
info: (message: string, ...args: unknown[]) => void;
|
|
11
|
+
warn: (message: string, ...args: unknown[]) => void;
|
|
12
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Initialize the logger with plugin configuration
|
|
16
|
+
* @param config - Plugin configuration
|
|
17
|
+
*/
|
|
18
|
+
export declare function initLogger(config: PluginConfig): void;
|
|
19
|
+
/**
|
|
20
|
+
* Log a debug message (only in debug mode)
|
|
21
|
+
* @param message - Message to log
|
|
22
|
+
* @param args - Additional arguments
|
|
23
|
+
*/
|
|
24
|
+
export declare function logDebug(message: string, ...args: unknown[]): void;
|
|
25
|
+
/**
|
|
26
|
+
* Log an info message
|
|
27
|
+
* @param message - Message to log
|
|
28
|
+
* @param args - Additional arguments
|
|
29
|
+
*/
|
|
30
|
+
export declare function logInfo(message: string, ...args: unknown[]): void;
|
|
31
|
+
/**
|
|
32
|
+
* Log a warning message
|
|
33
|
+
* @param message - Message to log
|
|
34
|
+
* @param args - Additional arguments
|
|
35
|
+
*/
|
|
36
|
+
export declare function logWarn(message: string, ...args: unknown[]): void;
|
|
37
|
+
/**
|
|
38
|
+
* Log an error message
|
|
39
|
+
* @param message - Message to log
|
|
40
|
+
* @param args - Additional arguments
|
|
41
|
+
*/
|
|
42
|
+
export declare function logError(message: string, ...args: unknown[]): void;
|
|
43
|
+
/**
|
|
44
|
+
* Log a request at a specific stage
|
|
45
|
+
* @param stage - The stage of the request (before-transform, after-transform, response, error-response)
|
|
46
|
+
* @param data - Data to log
|
|
47
|
+
*/
|
|
48
|
+
export declare function logRequest(stage: string, data: Record<string, unknown>): void;
|
|
49
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../lib/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACtD;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAErD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAIlE;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAElE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,IAAI,CAEN"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging utilities for the Qwen Auth Plugin
|
|
3
|
+
*/
|
|
4
|
+
import { PLUGIN_NAME } from "./constants.js";
|
|
5
|
+
import { getDebugMode } from "./config.js";
|
|
6
|
+
let pluginConfig = { debug: false };
|
|
7
|
+
/**
|
|
8
|
+
* Initialize the logger with plugin configuration
|
|
9
|
+
* @param config - Plugin configuration
|
|
10
|
+
*/
|
|
11
|
+
export function initLogger(config) {
|
|
12
|
+
pluginConfig = config;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Log a debug message (only in debug mode)
|
|
16
|
+
* @param message - Message to log
|
|
17
|
+
* @param args - Additional arguments
|
|
18
|
+
*/
|
|
19
|
+
export function logDebug(message, ...args) {
|
|
20
|
+
if (getDebugMode(pluginConfig)) {
|
|
21
|
+
console.debug(`[${PLUGIN_NAME}] ${message}`, ...args);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Log an info message
|
|
26
|
+
* @param message - Message to log
|
|
27
|
+
* @param args - Additional arguments
|
|
28
|
+
*/
|
|
29
|
+
export function logInfo(message, ...args) {
|
|
30
|
+
console.info(`[${PLUGIN_NAME}] ${message}`, ...args);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Log a warning message
|
|
34
|
+
* @param message - Message to log
|
|
35
|
+
* @param args - Additional arguments
|
|
36
|
+
*/
|
|
37
|
+
export function logWarn(message, ...args) {
|
|
38
|
+
console.warn(`[${PLUGIN_NAME}] ${message}`, ...args);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Log an error message
|
|
42
|
+
* @param message - Message to log
|
|
43
|
+
* @param args - Additional arguments
|
|
44
|
+
*/
|
|
45
|
+
export function logError(message, ...args) {
|
|
46
|
+
console.error(`[${PLUGIN_NAME}] ${message}`, ...args);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Log a request at a specific stage
|
|
50
|
+
* @param stage - The stage of the request (before-transform, after-transform, response, error-response)
|
|
51
|
+
* @param data - Data to log
|
|
52
|
+
*/
|
|
53
|
+
export function logRequest(stage, data) {
|
|
54
|
+
logDebug(`[${stage}]`, data);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../lib/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAY3C,IAAI,YAAY,GAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,YAAY,GAAG,MAAM,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,GAAG,IAAe;IAC1D,IAAI,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,IAAI,WAAW,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACxD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe,EAAE,GAAG,IAAe;IACzD,OAAO,CAAC,IAAI,CAAC,IAAI,WAAW,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe,EAAE,GAAG,IAAe;IACzD,OAAO,CAAC,IAAI,CAAC,IAAI,WAAW,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,GAAG,IAAe;IAC1D,OAAO,CAAC,KAAK,CAAC,IAAI,WAAW,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,KAAa,EACb,IAA6B;IAE7B,QAAQ,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Authentication Successful - Qwen AI</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
body {
|
|
14
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|
|
15
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
padding: 20px;
|
|
21
|
+
}
|
|
22
|
+
.container {
|
|
23
|
+
background: white;
|
|
24
|
+
border-radius: 16px;
|
|
25
|
+
padding: 48px;
|
|
26
|
+
text-align: center;
|
|
27
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
28
|
+
max-width: 400px;
|
|
29
|
+
width: 100%;
|
|
30
|
+
}
|
|
31
|
+
.success-icon {
|
|
32
|
+
width: 80px;
|
|
33
|
+
height: 80px;
|
|
34
|
+
background: linear-gradient(135deg, #10a37f 0%, #0d8c6d 100%);
|
|
35
|
+
border-radius: 50%;
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
margin: 0 auto 24px;
|
|
40
|
+
}
|
|
41
|
+
.success-icon::after {
|
|
42
|
+
content: "✓";
|
|
43
|
+
color: white;
|
|
44
|
+
font-size: 40px;
|
|
45
|
+
font-weight: bold;
|
|
46
|
+
}
|
|
47
|
+
h1 {
|
|
48
|
+
color: #1a1a1a;
|
|
49
|
+
font-size: 28px;
|
|
50
|
+
margin-bottom: 12px;
|
|
51
|
+
font-weight: 600;
|
|
52
|
+
}
|
|
53
|
+
p {
|
|
54
|
+
color: #666;
|
|
55
|
+
font-size: 16px;
|
|
56
|
+
line-height: 1.6;
|
|
57
|
+
margin-bottom: 8px;
|
|
58
|
+
}
|
|
59
|
+
.provider {
|
|
60
|
+
color: #667eea;
|
|
61
|
+
font-weight: 600;
|
|
62
|
+
}
|
|
63
|
+
.close-hint {
|
|
64
|
+
margin-top: 24px;
|
|
65
|
+
padding-top: 24px;
|
|
66
|
+
border-top: 1px solid #eee;
|
|
67
|
+
color: #999;
|
|
68
|
+
font-size: 14px;
|
|
69
|
+
}
|
|
70
|
+
</style>
|
|
71
|
+
</head>
|
|
72
|
+
<body>
|
|
73
|
+
<div class="container">
|
|
74
|
+
<div class="success-icon"></div>
|
|
75
|
+
<h1>Authentication Successful</h1>
|
|
76
|
+
<p>You have successfully authenticated with</p>
|
|
77
|
+
<p class="provider">Qwen AI</p>
|
|
78
|
+
<div class="close-hint">
|
|
79
|
+
You can close this window and return to your terminal.
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper functions for the custom fetch implementation
|
|
3
|
+
* These functions break down the complex fetch logic into manageable, testable units
|
|
4
|
+
*/
|
|
5
|
+
import type { Auth } from "@opencode-ai/sdk";
|
|
6
|
+
import type { OpencodeClient } from "@opencode-ai/sdk";
|
|
7
|
+
import type { UserConfig, RequestBody } from "../types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Determines if the current auth token needs to be refreshed
|
|
10
|
+
* @param auth - Current authentication state
|
|
11
|
+
* @returns True if token is expired or invalid
|
|
12
|
+
*/
|
|
13
|
+
export declare function shouldRefreshToken(auth: Auth): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Refreshes the OAuth token and updates stored credentials
|
|
16
|
+
* @param currentAuth - Current auth state
|
|
17
|
+
* @param client - Opencode client for updating stored credentials
|
|
18
|
+
* @returns Updated auth (throws on failure)
|
|
19
|
+
*/
|
|
20
|
+
export declare function refreshAndUpdateToken(currentAuth: Auth, client: OpencodeClient): Promise<Auth>;
|
|
21
|
+
/**
|
|
22
|
+
* Extracts URL string from various request input types
|
|
23
|
+
* @param input - Request input (string, URL, or Request object)
|
|
24
|
+
* @returns URL string
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractRequestUrl(input: Request | string | URL): string;
|
|
27
|
+
/**
|
|
28
|
+
* Rewrites OpenAI-compatible API URLs to Qwen backend URLs
|
|
29
|
+
* @param url - Original URL
|
|
30
|
+
* @returns Rewritten URL for Qwen backend
|
|
31
|
+
*/
|
|
32
|
+
export declare function rewriteUrlForQwen(url: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Transforms request body and logs the transformation
|
|
35
|
+
* @param init - Request init options
|
|
36
|
+
* @param url - Request URL
|
|
37
|
+
* @param userConfig - User configuration
|
|
38
|
+
* @returns Transformed body and updated init, or undefined if no body
|
|
39
|
+
*/
|
|
40
|
+
export declare function transformRequestForQwen(init: RequestInit | undefined, url: string, userConfig: UserConfig): Promise<{
|
|
41
|
+
body: RequestBody;
|
|
42
|
+
updatedInit: RequestInit;
|
|
43
|
+
} | undefined>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates headers for Qwen API requests
|
|
46
|
+
* @param init - Request init options
|
|
47
|
+
* @param accessToken - OAuth access token
|
|
48
|
+
* @returns Headers object with all required Qwen headers
|
|
49
|
+
*/
|
|
50
|
+
export declare function createQwenHeaders(init: RequestInit | undefined, accessToken: string): Headers;
|
|
51
|
+
/**
|
|
52
|
+
* Handles error responses from the Qwen API
|
|
53
|
+
* @param response - Error response from API
|
|
54
|
+
* @returns Original response or mapped response
|
|
55
|
+
*/
|
|
56
|
+
export declare function handleErrorResponse(response: Response): Promise<Response>;
|
|
57
|
+
/**
|
|
58
|
+
* Handles successful responses from the Qwen API
|
|
59
|
+
* Converts SSE to JSON for non-streaming requests
|
|
60
|
+
* Passes through SSE for streaming requests
|
|
61
|
+
* @param response - Success response from API
|
|
62
|
+
* @param isStreaming - Whether this is a streaming request
|
|
63
|
+
* @returns Processed response
|
|
64
|
+
*/
|
|
65
|
+
export declare function handleSuccessResponse(response: Response, isStreaming: boolean): Promise<Response>;
|
|
66
|
+
//# sourceMappingURL=fetch-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-helpers.d.ts","sourceRoot":"","sources":["../../../lib/request/fetch-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAW3D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAEtD;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,IAAI,EACjB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,CAIvE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBrD;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,WAAW,GAAG,SAAS,EAC7B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GAAG,SAAS,CAAC,CA2CtE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,WAAW,GAAG,SAAS,EAC7B,WAAW,EAAE,MAAM,GAClB,OAAO,CAsBT;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,QAAQ,CAAC,CAkBnB;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,QAAQ,CAAC,CAcnB"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper functions for the custom fetch implementation
|
|
3
|
+
* These functions break down the complex fetch logic into manageable, testable units
|
|
4
|
+
*/
|
|
5
|
+
import { refreshAccessToken } from "../auth/auth.js";
|
|
6
|
+
import { logRequest, logDebug } from "../logger.js";
|
|
7
|
+
import { transformRequestBody, normalizeModel } from "./request-transformer.js";
|
|
8
|
+
import { convertSseToJson, ensureContentType } from "./response-handler.js";
|
|
9
|
+
import { PLUGIN_NAME, ERROR_MESSAGES, LOG_STAGES, } from "../constants.js";
|
|
10
|
+
/**
|
|
11
|
+
* Determines if the current auth token needs to be refreshed
|
|
12
|
+
* @param auth - Current authentication state
|
|
13
|
+
* @returns True if token is expired or invalid
|
|
14
|
+
*/
|
|
15
|
+
export function shouldRefreshToken(auth) {
|
|
16
|
+
return auth.type !== "oauth" || !auth.access || auth.expires < Date.now();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Refreshes the OAuth token and updates stored credentials
|
|
20
|
+
* @param currentAuth - Current auth state
|
|
21
|
+
* @param client - Opencode client for updating stored credentials
|
|
22
|
+
* @returns Updated auth (throws on failure)
|
|
23
|
+
*/
|
|
24
|
+
export async function refreshAndUpdateToken(currentAuth, client) {
|
|
25
|
+
const refreshToken = currentAuth.type === "oauth" ? currentAuth.refresh : "";
|
|
26
|
+
const refreshResult = await refreshAccessToken(refreshToken);
|
|
27
|
+
if (refreshResult.type === "failed") {
|
|
28
|
+
throw new Error(ERROR_MESSAGES.TOKEN_REFRESH_FAILED);
|
|
29
|
+
}
|
|
30
|
+
// Update stored credentials
|
|
31
|
+
await client.auth.set({
|
|
32
|
+
path: { id: "qwen" },
|
|
33
|
+
body: {
|
|
34
|
+
type: "oauth",
|
|
35
|
+
access: refreshResult.access,
|
|
36
|
+
refresh: refreshResult.refresh,
|
|
37
|
+
expires: refreshResult.expires,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
// Update current auth reference if it's OAuth type
|
|
41
|
+
if (currentAuth.type === "oauth") {
|
|
42
|
+
currentAuth.access = refreshResult.access;
|
|
43
|
+
currentAuth.refresh = refreshResult.refresh;
|
|
44
|
+
currentAuth.expires = refreshResult.expires;
|
|
45
|
+
}
|
|
46
|
+
return currentAuth;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extracts URL string from various request input types
|
|
50
|
+
* @param input - Request input (string, URL, or Request object)
|
|
51
|
+
* @returns URL string
|
|
52
|
+
*/
|
|
53
|
+
export function extractRequestUrl(input) {
|
|
54
|
+
if (typeof input === "string")
|
|
55
|
+
return input;
|
|
56
|
+
if (input instanceof URL)
|
|
57
|
+
return input.toString();
|
|
58
|
+
return input.url;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Rewrites OpenAI-compatible API URLs to Qwen backend URLs
|
|
62
|
+
* @param url - Original URL
|
|
63
|
+
* @returns Rewritten URL for Qwen backend
|
|
64
|
+
*/
|
|
65
|
+
export function rewriteUrlForQwen(url) {
|
|
66
|
+
// Parse the original URL
|
|
67
|
+
const parsedUrl = new URL(url);
|
|
68
|
+
// Replace the host with Qwen's backend
|
|
69
|
+
parsedUrl.host = "chat.qwen.ai";
|
|
70
|
+
parsedUrl.protocol = "https:";
|
|
71
|
+
parsedUrl.port = "";
|
|
72
|
+
// Qwen API is at /api (not /backend-api)
|
|
73
|
+
// Paths like /v1/chat/completions become /api/v1/chat/completions
|
|
74
|
+
if (!parsedUrl.pathname.startsWith("/api")) {
|
|
75
|
+
parsedUrl.pathname = `/api${parsedUrl.pathname}`;
|
|
76
|
+
}
|
|
77
|
+
return parsedUrl.toString();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Transforms request body and logs the transformation
|
|
81
|
+
* @param init - Request init options
|
|
82
|
+
* @param url - Request URL
|
|
83
|
+
* @param userConfig - User configuration
|
|
84
|
+
* @returns Transformed body and updated init, or undefined if no body
|
|
85
|
+
*/
|
|
86
|
+
export async function transformRequestForQwen(init, url, userConfig) {
|
|
87
|
+
if (!init?.body)
|
|
88
|
+
return undefined;
|
|
89
|
+
try {
|
|
90
|
+
const body = JSON.parse(init.body);
|
|
91
|
+
const originalModel = body.model;
|
|
92
|
+
// Normalize model name
|
|
93
|
+
const normalizedModel = normalizeModel(originalModel);
|
|
94
|
+
// Log original request
|
|
95
|
+
logRequest(LOG_STAGES.BEFORE_TRANSFORM, {
|
|
96
|
+
url,
|
|
97
|
+
originalModel,
|
|
98
|
+
model: body.model,
|
|
99
|
+
hasMessages: !!body.messages,
|
|
100
|
+
messageCount: body.messages?.length,
|
|
101
|
+
stream: body.stream,
|
|
102
|
+
body: body,
|
|
103
|
+
});
|
|
104
|
+
// Transform request body
|
|
105
|
+
const transformedBody = transformRequestBody(body, normalizedModel, userConfig);
|
|
106
|
+
// Log transformed request
|
|
107
|
+
logRequest(LOG_STAGES.AFTER_TRANSFORM, {
|
|
108
|
+
url,
|
|
109
|
+
originalModel,
|
|
110
|
+
normalizedModel: transformedBody.model,
|
|
111
|
+
hasMessages: !!transformedBody.messages,
|
|
112
|
+
messageCount: transformedBody.messages?.length,
|
|
113
|
+
stream: transformedBody.stream,
|
|
114
|
+
body: transformedBody,
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
body: transformedBody,
|
|
118
|
+
updatedInit: { ...init, body: JSON.stringify(transformedBody) },
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
console.error(`[${PLUGIN_NAME}] ${ERROR_MESSAGES.REQUEST_PARSE_ERROR}:`, e);
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Creates headers for Qwen API requests
|
|
128
|
+
* @param init - Request init options
|
|
129
|
+
* @param accessToken - OAuth access token
|
|
130
|
+
* @returns Headers object with all required Qwen headers
|
|
131
|
+
*/
|
|
132
|
+
export function createQwenHeaders(init, accessToken) {
|
|
133
|
+
const headers = new Headers(init?.headers ?? {});
|
|
134
|
+
// Remove any existing API key headers
|
|
135
|
+
headers.delete("x-api-key");
|
|
136
|
+
headers.delete("X-Api-Key");
|
|
137
|
+
// Set Authorization with OAuth token
|
|
138
|
+
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
139
|
+
// Set content type if not already set
|
|
140
|
+
if (!headers.has("Content-Type")) {
|
|
141
|
+
headers.set("Content-Type", "application/json");
|
|
142
|
+
}
|
|
143
|
+
// Set Accept header for SSE if streaming
|
|
144
|
+
const acceptValue = headers.get("Accept");
|
|
145
|
+
if (!acceptValue || acceptValue === "*/*") {
|
|
146
|
+
headers.set("Accept", "text/event-stream, application/json");
|
|
147
|
+
}
|
|
148
|
+
return headers;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Handles error responses from the Qwen API
|
|
152
|
+
* @param response - Error response from API
|
|
153
|
+
* @returns Original response or mapped response
|
|
154
|
+
*/
|
|
155
|
+
export async function handleErrorResponse(response) {
|
|
156
|
+
logRequest(LOG_STAGES.ERROR_RESPONSE, {
|
|
157
|
+
status: response.status,
|
|
158
|
+
statusText: response.statusText,
|
|
159
|
+
});
|
|
160
|
+
// Clone to read body without consuming original
|
|
161
|
+
const clone = response.clone();
|
|
162
|
+
let errorBody = "";
|
|
163
|
+
try {
|
|
164
|
+
errorBody = await clone.text();
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// Ignore read errors
|
|
168
|
+
}
|
|
169
|
+
logDebug("Error response body:", errorBody);
|
|
170
|
+
return response;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Handles successful responses from the Qwen API
|
|
174
|
+
* Converts SSE to JSON for non-streaming requests
|
|
175
|
+
* Passes through SSE for streaming requests
|
|
176
|
+
* @param response - Success response from API
|
|
177
|
+
* @param isStreaming - Whether this is a streaming request
|
|
178
|
+
* @returns Processed response
|
|
179
|
+
*/
|
|
180
|
+
export async function handleSuccessResponse(response, isStreaming) {
|
|
181
|
+
const responseHeaders = ensureContentType(response.headers);
|
|
182
|
+
// For non-streaming requests, convert SSE to JSON
|
|
183
|
+
if (!isStreaming) {
|
|
184
|
+
return await convertSseToJson(response, responseHeaders);
|
|
185
|
+
}
|
|
186
|
+
// For streaming requests, return stream as-is
|
|
187
|
+
return new Response(response.body, {
|
|
188
|
+
status: response.status,
|
|
189
|
+
statusText: response.statusText,
|
|
190
|
+
headers: responseHeaders,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=fetch-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-helpers.js","sourceRoot":"","sources":["../../../lib/request/fetch-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request body transformation utilities
|
|
3
|
+
* Handles model normalization and request body modifications for Qwen API
|
|
4
|
+
*/
|
|
5
|
+
import type { RequestBody, UserConfig } from "../types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Normalize model name by removing provider prefix if present
|
|
8
|
+
* @param model - Original model name (e.g., "qwen/qwen3-max" or "qwen3-max")
|
|
9
|
+
* @returns Normalized model name (e.g., "qwen3-max")
|
|
10
|
+
*/
|
|
11
|
+
export declare function normalizeModel(model: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Get the full model ID for Qwen API
|
|
14
|
+
* Some APIs require the full model path
|
|
15
|
+
* @param model - Normalized model name
|
|
16
|
+
* @returns Full model ID for API
|
|
17
|
+
*/
|
|
18
|
+
export declare function getFullModelId(model: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Transform request body for Qwen API
|
|
21
|
+
* @param body - Original request body
|
|
22
|
+
* @param normalizedModel - Normalized model name
|
|
23
|
+
* @param userConfig - User configuration
|
|
24
|
+
* @returns Transformed request body
|
|
25
|
+
*/
|
|
26
|
+
export declare function transformRequestBody(body: RequestBody, normalizedModel: string, userConfig: UserConfig): RequestBody;
|
|
27
|
+
//# sourceMappingURL=request-transformer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-transformer.d.ts","sourceRoot":"","sources":["../../../lib/request/request-transformer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAa,MAAM,aAAa,CAAC;AAGtE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASpD;AAsED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,WAAW,EACjB,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,UAAU,GACrB,WAAW,CAiEb"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request body transformation utilities
|
|
3
|
+
* Handles model normalization and request body modifications for Qwen API
|
|
4
|
+
*/
|
|
5
|
+
import { QWEN_MODELS } from "../constants.js";
|
|
6
|
+
/**
|
|
7
|
+
* Normalize model name by removing provider prefix if present
|
|
8
|
+
* @param model - Original model name (e.g., "qwen/qwen3-max" or "qwen3-max")
|
|
9
|
+
* @returns Normalized model name (e.g., "qwen3-max")
|
|
10
|
+
*/
|
|
11
|
+
export function normalizeModel(model) {
|
|
12
|
+
if (!model)
|
|
13
|
+
return "qwen3-max"; // Default model
|
|
14
|
+
// Remove provider prefix (e.g., "qwen/" -> "")
|
|
15
|
+
if (model.startsWith("qwen/")) {
|
|
16
|
+
return model.substring(5);
|
|
17
|
+
}
|
|
18
|
+
return model;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the full model ID for Qwen API
|
|
22
|
+
* Some APIs require the full model path
|
|
23
|
+
* @param model - Normalized model name
|
|
24
|
+
* @returns Full model ID for API
|
|
25
|
+
*/
|
|
26
|
+
export function getFullModelId(model) {
|
|
27
|
+
// Qwen API typically uses the model ID directly
|
|
28
|
+
// but we might need to map aliases here
|
|
29
|
+
const modelDef = QWEN_MODELS[model];
|
|
30
|
+
if (modelDef) {
|
|
31
|
+
return modelDef.id;
|
|
32
|
+
}
|
|
33
|
+
return model;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Apply user configuration options to the request body
|
|
37
|
+
* @param body - Request body
|
|
38
|
+
* @param userConfig - User configuration
|
|
39
|
+
*/
|
|
40
|
+
function applyUserConfig(body, userConfig) {
|
|
41
|
+
const model = body.model;
|
|
42
|
+
// Apply global options
|
|
43
|
+
if (userConfig.global) {
|
|
44
|
+
if (userConfig.global.max_tokens !== undefined && body.max_tokens === undefined) {
|
|
45
|
+
body.max_tokens = userConfig.global.max_tokens;
|
|
46
|
+
}
|
|
47
|
+
if (userConfig.global.temperature !== undefined && body.temperature === undefined) {
|
|
48
|
+
body.temperature = userConfig.global.temperature;
|
|
49
|
+
}
|
|
50
|
+
if (userConfig.global.top_p !== undefined && body.top_p === undefined) {
|
|
51
|
+
body.top_p = userConfig.global.top_p;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Apply model-specific options
|
|
55
|
+
const modelConfig = userConfig.models?.[model];
|
|
56
|
+
if (modelConfig?.options) {
|
|
57
|
+
if (modelConfig.options.max_tokens !== undefined && body.max_tokens === undefined) {
|
|
58
|
+
body.max_tokens = modelConfig.options.max_tokens;
|
|
59
|
+
}
|
|
60
|
+
if (modelConfig.options.temperature !== undefined && body.temperature === undefined) {
|
|
61
|
+
body.temperature = modelConfig.options.temperature;
|
|
62
|
+
}
|
|
63
|
+
if (modelConfig.options.top_p !== undefined && body.top_p === undefined) {
|
|
64
|
+
body.top_p = modelConfig.options.top_p;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Transform messages to ensure proper format
|
|
70
|
+
* @param messages - Input messages
|
|
71
|
+
* @returns Transformed messages
|
|
72
|
+
*/
|
|
73
|
+
function transformMessages(messages) {
|
|
74
|
+
return messages.map((msg) => {
|
|
75
|
+
// Ensure content is properly formatted
|
|
76
|
+
if (typeof msg.content === "string") {
|
|
77
|
+
return msg;
|
|
78
|
+
}
|
|
79
|
+
// If content is an array (multimodal), ensure it's valid
|
|
80
|
+
if (Array.isArray(msg.content)) {
|
|
81
|
+
return {
|
|
82
|
+
...msg,
|
|
83
|
+
content: msg.content.map((part) => {
|
|
84
|
+
if (typeof part === "string") {
|
|
85
|
+
return { type: "text", text: part };
|
|
86
|
+
}
|
|
87
|
+
return part;
|
|
88
|
+
}),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return msg;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Transform request body for Qwen API
|
|
96
|
+
* @param body - Original request body
|
|
97
|
+
* @param normalizedModel - Normalized model name
|
|
98
|
+
* @param userConfig - User configuration
|
|
99
|
+
* @returns Transformed request body
|
|
100
|
+
*/
|
|
101
|
+
export function transformRequestBody(body, normalizedModel, userConfig) {
|
|
102
|
+
const transformedBody = { ...body };
|
|
103
|
+
// Set normalized model
|
|
104
|
+
transformedBody.model = getFullModelId(normalizedModel);
|
|
105
|
+
// Transform messages if present
|
|
106
|
+
if (transformedBody.messages) {
|
|
107
|
+
transformedBody.messages = transformMessages(transformedBody.messages);
|
|
108
|
+
}
|
|
109
|
+
// Apply user configuration
|
|
110
|
+
applyUserConfig(transformedBody, userConfig);
|
|
111
|
+
// Ensure max_tokens is set (Qwen has limits)
|
|
112
|
+
const modelDef = QWEN_MODELS[normalizedModel];
|
|
113
|
+
if (transformedBody.max_tokens === undefined && modelDef?.maxTokens) {
|
|
114
|
+
transformedBody.max_tokens = modelDef.maxTokens;
|
|
115
|
+
}
|
|
116
|
+
// Remove undefined values to keep request clean
|
|
117
|
+
const cleanedBody = {
|
|
118
|
+
model: transformedBody.model,
|
|
119
|
+
};
|
|
120
|
+
// Only add defined properties
|
|
121
|
+
if (transformedBody.messages !== undefined) {
|
|
122
|
+
cleanedBody.messages = transformedBody.messages;
|
|
123
|
+
}
|
|
124
|
+
if (transformedBody.stream !== undefined) {
|
|
125
|
+
cleanedBody.stream = transformedBody.stream;
|
|
126
|
+
}
|
|
127
|
+
if (transformedBody.max_tokens !== undefined) {
|
|
128
|
+
cleanedBody.max_tokens = transformedBody.max_tokens;
|
|
129
|
+
}
|
|
130
|
+
if (transformedBody.max_completion_tokens !== undefined) {
|
|
131
|
+
cleanedBody.max_completion_tokens = transformedBody.max_completion_tokens;
|
|
132
|
+
}
|
|
133
|
+
if (transformedBody.temperature !== undefined) {
|
|
134
|
+
cleanedBody.temperature = transformedBody.temperature;
|
|
135
|
+
}
|
|
136
|
+
if (transformedBody.top_p !== undefined) {
|
|
137
|
+
cleanedBody.top_p = transformedBody.top_p;
|
|
138
|
+
}
|
|
139
|
+
if (transformedBody.stop !== undefined) {
|
|
140
|
+
cleanedBody.stop = transformedBody.stop;
|
|
141
|
+
}
|
|
142
|
+
if (transformedBody.tools !== undefined) {
|
|
143
|
+
cleanedBody.tools = transformedBody.tools;
|
|
144
|
+
}
|
|
145
|
+
if (transformedBody.tool_choice !== undefined) {
|
|
146
|
+
cleanedBody.tool_choice = transformedBody.tool_choice;
|
|
147
|
+
}
|
|
148
|
+
if (transformedBody.store !== undefined) {
|
|
149
|
+
cleanedBody.store = transformedBody.store;
|
|
150
|
+
}
|
|
151
|
+
// Preserve any other properties
|
|
152
|
+
for (const [key, value] of Object.entries(transformedBody)) {
|
|
153
|
+
if (!(key in cleanedBody) && value !== undefined) {
|
|
154
|
+
cleanedBody[key] = value;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return cleanedBody;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=request-transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-transformer.js","sourceRoot":"","sources":["../../../lib/request/request-transformer.ts"],"names":[],"mappings":"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"}
|