@caupulican/pi-ai 0.93.13 → 0.93.15
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xai.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/xai.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAIlC,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"xai.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/xai.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAIlC,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAiLhG,wBAAsB,QAAQ,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CASxF;AAED,wBAAsB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAQrF;AAED,eAAO,MAAM,gBAAgB,EAAE,sBA2B9B,CAAC"}
|
package/dist/utils/oauth/xai.js
CHANGED
|
@@ -9,6 +9,7 @@ const DEFAULT_TOKEN_LIFETIME_SECONDS = 3600;
|
|
|
9
9
|
const XAI_CLI_PROXY_BASE_URL = "https://cli-chat-proxy.grok.com/v1";
|
|
10
10
|
const XAI_CLI_PROXY_HEADERS = {
|
|
11
11
|
"X-XAI-Token-Auth": "xai-grok-cli",
|
|
12
|
+
"x-authenticateresponse": "authenticate-response",
|
|
12
13
|
"x-grok-client-version": "1.0.5",
|
|
13
14
|
"x-grok-client-identifier": "grok-shell",
|
|
14
15
|
"x-grok-client-mode": "headless",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xai.js","sourceRoot":"","sources":["../../../src/utils/oauth/xai.ts"],"names":[],"mappings":"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","sourcesContent":["/** xAI OAuth device-code flow. */\n\nimport type { Api, Model } from \"../../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from \"./types.ts\";\n\nconst XAI_CLIENT_ID = \"b1a00492-073a-47ea-816f-4c329264a828\";\nconst XAI_SCOPE = \"openid profile email offline_access grok-cli:access api:access\";\nconst XAI_DEVICE_CODE_URL = \"https://auth.x.ai/oauth2/device/code\";\nconst XAI_TOKEN_URL = \"https://auth.x.ai/oauth2/token\";\nconst REFRESH_SKEW_MS = 5 * 60 * 1000;\nconst DEFAULT_TOKEN_LIFETIME_SECONDS = 3600;\nconst XAI_CLI_PROXY_BASE_URL = \"https://cli-chat-proxy.grok.com/v1\";\nconst XAI_CLI_PROXY_HEADERS = {\n\t\"X-XAI-Token-Auth\": \"xai-grok-cli\",\n\t\"x-grok-client-version\": \"1.0.5\",\n\t\"x-grok-client-identifier\": \"grok-shell\",\n\t\"x-grok-client-mode\": \"headless\",\n} as const;\n\ntype JsonObject = Record<string, unknown>;\n\ntype OAuthHttpResponse = {\n\tok: boolean;\n\tstatus: number;\n\tbody: JsonObject;\n};\n\ntype XaiDeviceCode = {\n\tdeviceCode: string;\n\tuserCode: string;\n\tverificationUri: string;\n\tverificationUriComplete?: string;\n\tintervalSeconds?: number;\n\texpiresInSeconds: number;\n};\n\nfunction requiredString(body: JsonObject, field: string): string {\n\tconst value = body[field];\n\tif (typeof value !== \"string\" || value.length === 0) {\n\t\tthrow new Error(`Invalid xAI OAuth response field: ${field}`);\n\t}\n\treturn value;\n}\n\nfunction positiveNumber(body: JsonObject, field: string): number {\n\tconst value = body[field];\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n\t\tthrow new Error(`Invalid xAI OAuth response field: ${field}`);\n\t}\n\treturn value;\n}\n\nfunction validateVerificationUri(raw: string): string {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(raw);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification URI in xAI OAuth response\");\n\t}\n\tif (url.protocol !== \"https:\") {\n\t\tthrow new Error(\"Untrusted verification URI in xAI OAuth response\");\n\t}\n\treturn url.href;\n}\n\nasync function postForm(url: string, fields: Record<string, string>, signal?: AbortSignal): Promise<OAuthHttpResponse> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams(fields),\n\t\t\tsignal,\n\t\t});\n\t} catch (error) {\n\t\tif (signal?.aborted) throw new Error(\"Login cancelled\");\n\t\tthrow error;\n\t}\n\n\tlet body: JsonObject;\n\ttry {\n\t\tconst parsed = (await response.json()) as unknown;\n\t\tbody = parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as JsonObject) : {};\n\t} catch {\n\t\tif (signal?.aborted) throw new Error(\"Login cancelled\");\n\t\tthrow new Error(`xAI OAuth returned invalid JSON (HTTP ${response.status})`);\n\t}\n\treturn { ok: response.ok, status: response.status, body };\n}\n\nfunction requestFailure(action: string, response: OAuthHttpResponse): Error {\n\tconst error = typeof response.body.error === \"string\" ? response.body.error : undefined;\n\tconst description =\n\t\ttypeof response.body.error_description === \"string\" ? response.body.error_description : undefined;\n\tconst detail = [error, description].filter(Boolean).join(\": \");\n\treturn new Error(`xAI OAuth ${action} failed (HTTP ${response.status})${detail ? `: ${detail}` : \"\"}`);\n}\n\nfunction parseDeviceCode(body: JsonObject): XaiDeviceCode {\n\tconst interval = body.interval;\n\tconst verificationUriComplete = body.verification_uri_complete;\n\treturn {\n\t\tdeviceCode: requiredString(body, \"device_code\"),\n\t\tuserCode: requiredString(body, \"user_code\"),\n\t\tverificationUri: validateVerificationUri(requiredString(body, \"verification_uri\")),\n\t\tverificationUriComplete:\n\t\t\ttypeof verificationUriComplete === \"string\" && verificationUriComplete.length > 0\n\t\t\t\t? validateVerificationUri(verificationUriComplete)\n\t\t\t\t: undefined,\n\t\tintervalSeconds: typeof interval === \"number\" && Number.isFinite(interval) && interval > 0 ? interval : undefined,\n\t\texpiresInSeconds: positiveNumber(body, \"expires_in\"),\n\t};\n}\n\nfunction credentialsFromTokenResponse(body: JsonObject, previousRefreshToken?: string): OAuthCredentials {\n\tconst access = requiredString(body, \"access_token\");\n\tconst refresh =\n\t\tbody.refresh_token === undefined && previousRefreshToken\n\t\t\t? previousRefreshToken\n\t\t\t: requiredString(body, \"refresh_token\");\n\tconst expiresInSeconds =\n\t\tbody.expires_in === undefined ? DEFAULT_TOKEN_LIFETIME_SECONDS : positiveNumber(body, \"expires_in\");\n\treturn {\n\t\taccess,\n\t\trefresh,\n\t\texpires: Date.now() + expiresInSeconds * 1000 - REFRESH_SKEW_MS,\n\t};\n}\n\nasync function requestDeviceCode(signal?: AbortSignal): Promise<XaiDeviceCode> {\n\tconst response = await postForm(\n\t\tXAI_DEVICE_CODE_URL,\n\t\t{ client_id: XAI_CLIENT_ID, scope: XAI_SCOPE, referrer: \"pi\" },\n\t\tsignal,\n\t);\n\tif (!response.ok) throw requestFailure(\"device authorization\", response);\n\treturn parseDeviceCode(response.body);\n}\n\nasync function pollForTokens(device: XaiDeviceCode, signal?: AbortSignal): Promise<OAuthCredentials> {\n\treturn pollOAuthDeviceCodeFlow<OAuthCredentials>({\n\t\tintervalSeconds: device.intervalSeconds,\n\t\texpiresInSeconds: device.expiresInSeconds,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst response = await postForm(\n\t\t\t\tXAI_TOKEN_URL,\n\t\t\t\t{\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t\tclient_id: XAI_CLIENT_ID,\n\t\t\t\t\tdevice_code: device.deviceCode,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (response.ok) return { status: \"complete\", value: credentialsFromTokenResponse(response.body) };\n\n\t\t\tconst error = response.body.error;\n\t\t\tif (error === \"authorization_pending\") return { status: \"pending\" };\n\t\t\tif (error === \"slow_down\") {\n\t\t\t\tconst interval = response.body.interval;\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"slow_down\",\n\t\t\t\t\tintervalSeconds:\n\t\t\t\t\t\ttypeof interval === \"number\" && Number.isFinite(interval) && interval > 0 ? interval : undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (error === \"access_denied\" || error === \"authorization_denied\") {\n\t\t\t\treturn { status: \"failed\", message: \"xAI device authorization was denied\" };\n\t\t\t}\n\t\t\tif (error === \"expired_token\") return { status: \"failed\", message: \"xAI device code expired\" };\n\t\t\treturn { status: \"failed\", message: requestFailure(\"device token polling\", response).message };\n\t\t},\n\t});\n}\n\nexport async function loginXai(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n\tconst device = await requestDeviceCode(callbacks.signal);\n\tcallbacks.onDeviceCode({\n\t\tuserCode: device.userCode,\n\t\tverificationUri: device.verificationUriComplete ?? device.verificationUri,\n\t\tintervalSeconds: device.intervalSeconds,\n\t\texpiresInSeconds: device.expiresInSeconds,\n\t});\n\treturn pollForTokens(device, callbacks.signal);\n}\n\nexport async function refreshXaiToken(refreshToken: string): Promise<OAuthCredentials> {\n\tconst response = await postForm(XAI_TOKEN_URL, {\n\t\tgrant_type: \"refresh_token\",\n\t\tclient_id: XAI_CLIENT_ID,\n\t\trefresh_token: refreshToken,\n\t});\n\tif (!response.ok) throw requestFailure(\"token refresh\", response);\n\treturn credentialsFromTokenResponse(response.body, refreshToken);\n}\n\nexport const xaiOAuthProvider: OAuthProviderInterface = {\n\tid: \"xai\",\n\tname: \"xAI (Grok/X subscription)\",\n\tisSubscription: true,\n\tloginLabel: \"Sign in with SuperGrok or X Premium\",\n\tlogin: loginXai,\n\trefreshToken: (credentials) => refreshXaiToken(credentials.refresh),\n\tgetApiKey: (credentials) => credentials.access,\n\tmodifyModels(models: Model<Api>[]): Model<Api>[] {\n\t\treturn models.map((model) => {\n\t\t\tif (model.provider !== \"xai\" || model.api !== \"openai-responses\") return model;\n\t\t\treturn {\n\t\t\t\t...model,\n\t\t\t\tbaseUrl: XAI_CLI_PROXY_BASE_URL,\n\t\t\t\theaders: {\n\t\t\t\t\t...model.headers,\n\t\t\t\t\t...XAI_CLI_PROXY_HEADERS,\n\t\t\t\t\t\"x-grok-model-override\": model.id,\n\t\t\t\t},\n\t\t\t\tcompat: {\n\t\t\t\t\t...model.compat,\n\t\t\t\t\trequestFormat: \"xai-cli\",\n\t\t\t\t\tsupportsLongCacheRetention: false,\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t},\n};\n"]}
|
|
1
|
+
{"version":3,"file":"xai.js","sourceRoot":"","sources":["../../../src/utils/oauth/xai.ts"],"names":[],"mappings":"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","sourcesContent":["/** xAI OAuth device-code flow. */\n\nimport type { Api, Model } from \"../../types.ts\";\nimport { pollOAuthDeviceCodeFlow } from \"./device-code.ts\";\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from \"./types.ts\";\n\nconst XAI_CLIENT_ID = \"b1a00492-073a-47ea-816f-4c329264a828\";\nconst XAI_SCOPE = \"openid profile email offline_access grok-cli:access api:access\";\nconst XAI_DEVICE_CODE_URL = \"https://auth.x.ai/oauth2/device/code\";\nconst XAI_TOKEN_URL = \"https://auth.x.ai/oauth2/token\";\nconst REFRESH_SKEW_MS = 5 * 60 * 1000;\nconst DEFAULT_TOKEN_LIFETIME_SECONDS = 3600;\nconst XAI_CLI_PROXY_BASE_URL = \"https://cli-chat-proxy.grok.com/v1\";\nconst XAI_CLI_PROXY_HEADERS = {\n\t\"X-XAI-Token-Auth\": \"xai-grok-cli\",\n\t\"x-authenticateresponse\": \"authenticate-response\",\n\t\"x-grok-client-version\": \"1.0.5\",\n\t\"x-grok-client-identifier\": \"grok-shell\",\n\t\"x-grok-client-mode\": \"headless\",\n} as const;\n\ntype JsonObject = Record<string, unknown>;\n\ntype OAuthHttpResponse = {\n\tok: boolean;\n\tstatus: number;\n\tbody: JsonObject;\n};\n\ntype XaiDeviceCode = {\n\tdeviceCode: string;\n\tuserCode: string;\n\tverificationUri: string;\n\tverificationUriComplete?: string;\n\tintervalSeconds?: number;\n\texpiresInSeconds: number;\n};\n\nfunction requiredString(body: JsonObject, field: string): string {\n\tconst value = body[field];\n\tif (typeof value !== \"string\" || value.length === 0) {\n\t\tthrow new Error(`Invalid xAI OAuth response field: ${field}`);\n\t}\n\treturn value;\n}\n\nfunction positiveNumber(body: JsonObject, field: string): number {\n\tconst value = body[field];\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n\t\tthrow new Error(`Invalid xAI OAuth response field: ${field}`);\n\t}\n\treturn value;\n}\n\nfunction validateVerificationUri(raw: string): string {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(raw);\n\t} catch {\n\t\tthrow new Error(\"Untrusted verification URI in xAI OAuth response\");\n\t}\n\tif (url.protocol !== \"https:\") {\n\t\tthrow new Error(\"Untrusted verification URI in xAI OAuth response\");\n\t}\n\treturn url.href;\n}\n\nasync function postForm(url: string, fields: Record<string, string>, signal?: AbortSignal): Promise<OAuthHttpResponse> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams(fields),\n\t\t\tsignal,\n\t\t});\n\t} catch (error) {\n\t\tif (signal?.aborted) throw new Error(\"Login cancelled\");\n\t\tthrow error;\n\t}\n\n\tlet body: JsonObject;\n\ttry {\n\t\tconst parsed = (await response.json()) as unknown;\n\t\tbody = parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as JsonObject) : {};\n\t} catch {\n\t\tif (signal?.aborted) throw new Error(\"Login cancelled\");\n\t\tthrow new Error(`xAI OAuth returned invalid JSON (HTTP ${response.status})`);\n\t}\n\treturn { ok: response.ok, status: response.status, body };\n}\n\nfunction requestFailure(action: string, response: OAuthHttpResponse): Error {\n\tconst error = typeof response.body.error === \"string\" ? response.body.error : undefined;\n\tconst description =\n\t\ttypeof response.body.error_description === \"string\" ? response.body.error_description : undefined;\n\tconst detail = [error, description].filter(Boolean).join(\": \");\n\treturn new Error(`xAI OAuth ${action} failed (HTTP ${response.status})${detail ? `: ${detail}` : \"\"}`);\n}\n\nfunction parseDeviceCode(body: JsonObject): XaiDeviceCode {\n\tconst interval = body.interval;\n\tconst verificationUriComplete = body.verification_uri_complete;\n\treturn {\n\t\tdeviceCode: requiredString(body, \"device_code\"),\n\t\tuserCode: requiredString(body, \"user_code\"),\n\t\tverificationUri: validateVerificationUri(requiredString(body, \"verification_uri\")),\n\t\tverificationUriComplete:\n\t\t\ttypeof verificationUriComplete === \"string\" && verificationUriComplete.length > 0\n\t\t\t\t? validateVerificationUri(verificationUriComplete)\n\t\t\t\t: undefined,\n\t\tintervalSeconds: typeof interval === \"number\" && Number.isFinite(interval) && interval > 0 ? interval : undefined,\n\t\texpiresInSeconds: positiveNumber(body, \"expires_in\"),\n\t};\n}\n\nfunction credentialsFromTokenResponse(body: JsonObject, previousRefreshToken?: string): OAuthCredentials {\n\tconst access = requiredString(body, \"access_token\");\n\tconst refresh =\n\t\tbody.refresh_token === undefined && previousRefreshToken\n\t\t\t? previousRefreshToken\n\t\t\t: requiredString(body, \"refresh_token\");\n\tconst expiresInSeconds =\n\t\tbody.expires_in === undefined ? DEFAULT_TOKEN_LIFETIME_SECONDS : positiveNumber(body, \"expires_in\");\n\treturn {\n\t\taccess,\n\t\trefresh,\n\t\texpires: Date.now() + expiresInSeconds * 1000 - REFRESH_SKEW_MS,\n\t};\n}\n\nasync function requestDeviceCode(signal?: AbortSignal): Promise<XaiDeviceCode> {\n\tconst response = await postForm(\n\t\tXAI_DEVICE_CODE_URL,\n\t\t{ client_id: XAI_CLIENT_ID, scope: XAI_SCOPE, referrer: \"pi\" },\n\t\tsignal,\n\t);\n\tif (!response.ok) throw requestFailure(\"device authorization\", response);\n\treturn parseDeviceCode(response.body);\n}\n\nasync function pollForTokens(device: XaiDeviceCode, signal?: AbortSignal): Promise<OAuthCredentials> {\n\treturn pollOAuthDeviceCodeFlow<OAuthCredentials>({\n\t\tintervalSeconds: device.intervalSeconds,\n\t\texpiresInSeconds: device.expiresInSeconds,\n\t\twaitBeforeFirstPoll: true,\n\t\tsignal,\n\t\tpoll: async () => {\n\t\t\tconst response = await postForm(\n\t\t\t\tXAI_TOKEN_URL,\n\t\t\t\t{\n\t\t\t\t\tgrant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n\t\t\t\t\tclient_id: XAI_CLIENT_ID,\n\t\t\t\t\tdevice_code: device.deviceCode,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (response.ok) return { status: \"complete\", value: credentialsFromTokenResponse(response.body) };\n\n\t\t\tconst error = response.body.error;\n\t\t\tif (error === \"authorization_pending\") return { status: \"pending\" };\n\t\t\tif (error === \"slow_down\") {\n\t\t\t\tconst interval = response.body.interval;\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"slow_down\",\n\t\t\t\t\tintervalSeconds:\n\t\t\t\t\t\ttypeof interval === \"number\" && Number.isFinite(interval) && interval > 0 ? interval : undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (error === \"access_denied\" || error === \"authorization_denied\") {\n\t\t\t\treturn { status: \"failed\", message: \"xAI device authorization was denied\" };\n\t\t\t}\n\t\t\tif (error === \"expired_token\") return { status: \"failed\", message: \"xAI device code expired\" };\n\t\t\treturn { status: \"failed\", message: requestFailure(\"device token polling\", response).message };\n\t\t},\n\t});\n}\n\nexport async function loginXai(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n\tconst device = await requestDeviceCode(callbacks.signal);\n\tcallbacks.onDeviceCode({\n\t\tuserCode: device.userCode,\n\t\tverificationUri: device.verificationUriComplete ?? device.verificationUri,\n\t\tintervalSeconds: device.intervalSeconds,\n\t\texpiresInSeconds: device.expiresInSeconds,\n\t});\n\treturn pollForTokens(device, callbacks.signal);\n}\n\nexport async function refreshXaiToken(refreshToken: string): Promise<OAuthCredentials> {\n\tconst response = await postForm(XAI_TOKEN_URL, {\n\t\tgrant_type: \"refresh_token\",\n\t\tclient_id: XAI_CLIENT_ID,\n\t\trefresh_token: refreshToken,\n\t});\n\tif (!response.ok) throw requestFailure(\"token refresh\", response);\n\treturn credentialsFromTokenResponse(response.body, refreshToken);\n}\n\nexport const xaiOAuthProvider: OAuthProviderInterface = {\n\tid: \"xai\",\n\tname: \"xAI (Grok/X subscription)\",\n\tisSubscription: true,\n\tloginLabel: \"Sign in with SuperGrok or X Premium\",\n\tlogin: loginXai,\n\trefreshToken: (credentials) => refreshXaiToken(credentials.refresh),\n\tgetApiKey: (credentials) => credentials.access,\n\tmodifyModels(models: Model<Api>[]): Model<Api>[] {\n\t\treturn models.map((model) => {\n\t\t\tif (model.provider !== \"xai\" || model.api !== \"openai-responses\") return model;\n\t\t\treturn {\n\t\t\t\t...model,\n\t\t\t\tbaseUrl: XAI_CLI_PROXY_BASE_URL,\n\t\t\t\theaders: {\n\t\t\t\t\t...model.headers,\n\t\t\t\t\t...XAI_CLI_PROXY_HEADERS,\n\t\t\t\t\t\"x-grok-model-override\": model.id,\n\t\t\t\t},\n\t\t\t\tcompat: {\n\t\t\t\t\t...model.compat,\n\t\t\t\t\trequestFormat: \"xai-cli\",\n\t\t\t\t\tsupportsLongCacheRetention: false,\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\t},\n};\n"]}
|