@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.
Files changed (47) hide show
  1. package/dist/lib/auth/auth.d.ts +72 -0
  2. package/dist/lib/auth/auth.d.ts.map +1 -0
  3. package/dist/lib/auth/auth.js +212 -0
  4. package/dist/lib/auth/auth.js.map +1 -0
  5. package/dist/lib/auth/browser-session.d.ts +49 -0
  6. package/dist/lib/auth/browser-session.d.ts.map +1 -0
  7. package/dist/lib/auth/browser-session.js +211 -0
  8. package/dist/lib/auth/browser-session.js.map +1 -0
  9. package/dist/lib/auth/browser.d.ts +17 -0
  10. package/dist/lib/auth/browser.d.ts.map +1 -0
  11. package/dist/lib/auth/browser.js +86 -0
  12. package/dist/lib/auth/browser.js.map +1 -0
  13. package/dist/lib/auth/server.d.ts +14 -0
  14. package/dist/lib/auth/server.d.ts.map +1 -0
  15. package/dist/lib/auth/server.js +253 -0
  16. package/dist/lib/auth/server.js.map +1 -0
  17. package/dist/lib/config.d.ts +28 -0
  18. package/dist/lib/config.d.ts.map +1 -0
  19. package/dist/lib/config.js +67 -0
  20. package/dist/lib/config.js.map +1 -0
  21. package/dist/lib/constants.d.ts +77 -0
  22. package/dist/lib/constants.d.ts.map +1 -0
  23. package/dist/lib/constants.js +109 -0
  24. package/dist/lib/constants.js.map +1 -0
  25. package/dist/lib/logger.d.ts +49 -0
  26. package/dist/lib/logger.d.ts.map +1 -0
  27. package/dist/lib/logger.js +56 -0
  28. package/dist/lib/logger.js.map +1 -0
  29. package/dist/lib/oauth-success.html +83 -0
  30. package/dist/lib/request/fetch-helpers.d.ts +66 -0
  31. package/dist/lib/request/fetch-helpers.d.ts.map +1 -0
  32. package/dist/lib/request/fetch-helpers.js +193 -0
  33. package/dist/lib/request/fetch-helpers.js.map +1 -0
  34. package/dist/lib/request/request-transformer.d.ts +27 -0
  35. package/dist/lib/request/request-transformer.d.ts.map +1 -0
  36. package/dist/lib/request/request-transformer.js +159 -0
  37. package/dist/lib/request/request-transformer.js.map +1 -0
  38. package/dist/lib/request/response-handler.d.ts +32 -0
  39. package/dist/lib/request/response-handler.d.ts.map +1 -0
  40. package/dist/lib/request/response-handler.js +176 -0
  41. package/dist/lib/request/response-handler.js.map +1 -0
  42. package/dist/lib/types.d.ts +159 -0
  43. package/dist/lib/types.d.ts.map +1 -0
  44. package/dist/lib/types.js +5 -0
  45. package/dist/lib/types.js.map +1 -0
  46. package/iamtoricool-opencool-qwen-auth-0.0.1-alpha.tgz +0 -0
  47. 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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"}