@ljoukov/llm 7.0.18 → 7.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/index.cjs +75 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +75 -22
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
package/dist/index.js
CHANGED
|
@@ -575,6 +575,10 @@ function resolveOpenAiImagePriceResolution(imageSize) {
|
|
|
575
575
|
import os2 from "os";
|
|
576
576
|
import { TextDecoder as TextDecoder2 } from "util";
|
|
577
577
|
|
|
578
|
+
// src/utils/env.ts
|
|
579
|
+
import fs from "fs";
|
|
580
|
+
import path from "path";
|
|
581
|
+
|
|
578
582
|
// src/utils/runtimeSingleton.ts
|
|
579
583
|
var runtimeSingletonStoreKey = /* @__PURE__ */ Symbol.for("@ljoukov/llm.runtimeSingletonStore");
|
|
580
584
|
function getRuntimeSingletonStore() {
|
|
@@ -603,16 +607,7 @@ function getRuntimeSingleton(key, create) {
|
|
|
603
607
|
return createdValue;
|
|
604
608
|
}
|
|
605
609
|
|
|
606
|
-
// src/openai/chatgpt-auth.ts
|
|
607
|
-
import { Buffer as Buffer2 } from "buffer";
|
|
608
|
-
import fs2 from "fs";
|
|
609
|
-
import os from "os";
|
|
610
|
-
import path2 from "path";
|
|
611
|
-
import { z } from "zod";
|
|
612
|
-
|
|
613
610
|
// src/utils/env.ts
|
|
614
|
-
import fs from "fs";
|
|
615
|
-
import path from "path";
|
|
616
611
|
var envState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.envState"), () => ({
|
|
617
612
|
envLoaded: false
|
|
618
613
|
}));
|
|
@@ -674,6 +669,11 @@ function parseEnvLine(line) {
|
|
|
674
669
|
}
|
|
675
670
|
|
|
676
671
|
// src/openai/chatgpt-auth.ts
|
|
672
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
673
|
+
import fs2 from "fs";
|
|
674
|
+
import os from "os";
|
|
675
|
+
import path2 from "path";
|
|
676
|
+
import { z } from "zod";
|
|
677
677
|
var CHATGPT_AUTH_TOKEN_PROVIDER_URL_ENV = "CHATGPT_AUTH_TOKEN_PROVIDER_URL";
|
|
678
678
|
var CHATGPT_AUTH_TOKEN_PROVIDER_STORE_ENV = "CHATGPT_AUTH_TOKEN_PROVIDER_STORE";
|
|
679
679
|
var CHATGPT_AUTH_API_KEY_ENV = "CHATGPT_AUTH_API_KEY";
|
|
@@ -1581,19 +1581,21 @@ function createAbortError(reason) {
|
|
|
1581
1581
|
|
|
1582
1582
|
// src/openai/chatgpt-codex.ts
|
|
1583
1583
|
var CHATGPT_CODEX_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses";
|
|
1584
|
+
var CHATGPT_CODEX_ENDPOINT_ENV = "CHATGPT_CODEX_ENDPOINT";
|
|
1585
|
+
var CHATGPT_CODEX_PROXY_URL_ENV = "CHATGPT_CODEX_PROXY_URL";
|
|
1586
|
+
var CHATGPT_CODEX_PROXY_API_KEY_ENV = "CHATGPT_CODEX_PROXY_API_KEY";
|
|
1584
1587
|
var CHATGPT_RESPONSES_EXPERIMENTAL_HEADER = "responses=experimental";
|
|
1585
1588
|
var chatGptCodexState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.chatGptCodexState"), () => ({
|
|
1586
1589
|
cachedResponsesWebSocketMode: null,
|
|
1587
1590
|
chatGptResponsesWebSocketDisabled: false
|
|
1588
1591
|
}));
|
|
1589
1592
|
async function streamChatGptCodexResponse(options) {
|
|
1590
|
-
const
|
|
1593
|
+
const endpointConfig = await resolveChatGptCodexEndpointConfig();
|
|
1591
1594
|
const mode = resolveChatGptResponsesWebSocketMode();
|
|
1592
1595
|
const fallbackStreamFactory = () => {
|
|
1593
1596
|
const streamPromise = streamChatGptCodexResponseSse({
|
|
1594
1597
|
request: options.request,
|
|
1595
|
-
|
|
1596
|
-
accountId,
|
|
1598
|
+
endpointConfig,
|
|
1597
1599
|
sessionId: options.sessionId,
|
|
1598
1600
|
signal: options.signal
|
|
1599
1601
|
});
|
|
@@ -1615,15 +1617,14 @@ async function streamChatGptCodexResponse(options) {
|
|
|
1615
1617
|
return fallbackStreamFactory();
|
|
1616
1618
|
}
|
|
1617
1619
|
const websocketHeaders = buildChatGptCodexHeaders({
|
|
1618
|
-
|
|
1619
|
-
accountId,
|
|
1620
|
+
endpointConfig,
|
|
1620
1621
|
sessionId: options.sessionId,
|
|
1621
1622
|
useWebSocket: true
|
|
1622
1623
|
});
|
|
1623
1624
|
return createAdaptiveResponsesStream({
|
|
1624
1625
|
mode,
|
|
1625
1626
|
createWebSocketStream: async () => await createResponsesWebSocketStream({
|
|
1626
|
-
url: toWebSocketUrl(
|
|
1627
|
+
url: toWebSocketUrl(endpointConfig.url),
|
|
1627
1628
|
headers: websocketHeaders,
|
|
1628
1629
|
request: options.request,
|
|
1629
1630
|
signal: options.signal
|
|
@@ -1636,14 +1637,13 @@ async function streamChatGptCodexResponse(options) {
|
|
|
1636
1637
|
}
|
|
1637
1638
|
async function streamChatGptCodexResponseSse(options) {
|
|
1638
1639
|
const headers = buildChatGptCodexHeaders({
|
|
1639
|
-
|
|
1640
|
-
accountId: options.accountId,
|
|
1640
|
+
endpointConfig: options.endpointConfig,
|
|
1641
1641
|
sessionId: options.sessionId,
|
|
1642
1642
|
useWebSocket: false
|
|
1643
1643
|
});
|
|
1644
1644
|
headers.Accept = "text/event-stream";
|
|
1645
1645
|
headers["Content-Type"] = "application/json";
|
|
1646
|
-
const response = await fetch(
|
|
1646
|
+
const response = await fetch(options.endpointConfig.url, {
|
|
1647
1647
|
method: "POST",
|
|
1648
1648
|
headers,
|
|
1649
1649
|
body: JSON.stringify(options.request),
|
|
@@ -1663,24 +1663,77 @@ function resolveChatGptResponsesWebSocketMode() {
|
|
|
1663
1663
|
if (chatGptCodexState.cachedResponsesWebSocketMode) {
|
|
1664
1664
|
return chatGptCodexState.cachedResponsesWebSocketMode;
|
|
1665
1665
|
}
|
|
1666
|
+
const explicitMode = process.env.CHATGPT_RESPONSES_WEBSOCKET_MODE ?? process.env.OPENAI_RESPONSES_WEBSOCKET_MODE;
|
|
1667
|
+
const defaultMode = resolveChatGptCodexProxyConfig() ? "off" : "auto";
|
|
1666
1668
|
chatGptCodexState.cachedResponsesWebSocketMode = resolveResponsesWebSocketMode(
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
+
explicitMode,
|
|
1670
|
+
defaultMode
|
|
1669
1671
|
);
|
|
1670
1672
|
return chatGptCodexState.cachedResponsesWebSocketMode;
|
|
1671
1673
|
}
|
|
1674
|
+
async function resolveChatGptCodexEndpointConfig() {
|
|
1675
|
+
const proxy = resolveChatGptCodexProxyConfig();
|
|
1676
|
+
if (proxy) {
|
|
1677
|
+
return proxy;
|
|
1678
|
+
}
|
|
1679
|
+
const { access, accountId } = await getChatGptAuthProfile();
|
|
1680
|
+
return {
|
|
1681
|
+
kind: "direct",
|
|
1682
|
+
url: resolveChatGptCodexEndpoint(),
|
|
1683
|
+
access,
|
|
1684
|
+
accountId
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
function resolveChatGptCodexEndpoint() {
|
|
1688
|
+
loadLocalEnv();
|
|
1689
|
+
return process.env[CHATGPT_CODEX_ENDPOINT_ENV]?.trim() || CHATGPT_CODEX_ENDPOINT;
|
|
1690
|
+
}
|
|
1691
|
+
function resolveChatGptCodexProxyConfig() {
|
|
1692
|
+
loadLocalEnv();
|
|
1693
|
+
const rawUrl = process.env[CHATGPT_CODEX_PROXY_URL_ENV]?.trim();
|
|
1694
|
+
if (!rawUrl) {
|
|
1695
|
+
return null;
|
|
1696
|
+
}
|
|
1697
|
+
const apiKey = process.env[CHATGPT_CODEX_PROXY_API_KEY_ENV]?.trim();
|
|
1698
|
+
if (!apiKey) {
|
|
1699
|
+
throw new Error(
|
|
1700
|
+
`${CHATGPT_CODEX_PROXY_API_KEY_ENV} must be provided when ${CHATGPT_CODEX_PROXY_URL_ENV} is set.`
|
|
1701
|
+
);
|
|
1702
|
+
}
|
|
1703
|
+
return {
|
|
1704
|
+
kind: "proxy",
|
|
1705
|
+
url: normalizeChatGptCodexProxyUrl(rawUrl),
|
|
1706
|
+
apiKey
|
|
1707
|
+
};
|
|
1708
|
+
}
|
|
1709
|
+
function normalizeChatGptCodexProxyUrl(rawUrl) {
|
|
1710
|
+
try {
|
|
1711
|
+
const url = new URL(rawUrl);
|
|
1712
|
+
if (url.pathname === "" || url.pathname === "/") {
|
|
1713
|
+
url.pathname = "/api/codex/responses";
|
|
1714
|
+
}
|
|
1715
|
+
return url.toString();
|
|
1716
|
+
} catch {
|
|
1717
|
+
return rawUrl;
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1672
1720
|
function buildChatGptCodexHeaders(options) {
|
|
1673
1721
|
const openAiBeta = options.useWebSocket ? mergeOpenAiBetaHeader(
|
|
1674
1722
|
CHATGPT_RESPONSES_EXPERIMENTAL_HEADER,
|
|
1675
1723
|
OPENAI_BETA_RESPONSES_WEBSOCKETS_V2
|
|
1676
1724
|
) : CHATGPT_RESPONSES_EXPERIMENTAL_HEADER;
|
|
1677
1725
|
const headers = {
|
|
1678
|
-
Authorization: `Bearer ${options.access}`,
|
|
1679
|
-
"chatgpt-account-id": options.accountId,
|
|
1680
1726
|
"OpenAI-Beta": openAiBeta,
|
|
1681
1727
|
originator: "llm",
|
|
1682
1728
|
"User-Agent": buildUserAgent()
|
|
1683
1729
|
};
|
|
1730
|
+
if (options.endpointConfig.kind === "proxy") {
|
|
1731
|
+
headers.Authorization = `Bearer ${options.endpointConfig.apiKey}`;
|
|
1732
|
+
headers["x-codex-proxy-auth"] = options.endpointConfig.apiKey;
|
|
1733
|
+
} else {
|
|
1734
|
+
headers.Authorization = `Bearer ${options.endpointConfig.access}`;
|
|
1735
|
+
headers["chatgpt-account-id"] = options.endpointConfig.accountId;
|
|
1736
|
+
}
|
|
1684
1737
|
if (options.sessionId) {
|
|
1685
1738
|
headers.session_id = options.sessionId;
|
|
1686
1739
|
}
|