@ljoukov/llm 7.0.17 → 7.0.19
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 +93 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +93 -28
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
package/dist/index.d.cts
CHANGED
|
@@ -15,8 +15,9 @@ type LlmUsageTokens = {
|
|
|
15
15
|
readonly totalTokens?: number;
|
|
16
16
|
readonly toolUsePromptTokens?: number;
|
|
17
17
|
};
|
|
18
|
-
declare function estimateCallCostUsd({ modelId, tokens, responseImages, imageSize, imageQuality, }: {
|
|
18
|
+
declare function estimateCallCostUsd({ modelId, pricingModelId, tokens, responseImages, imageSize, imageQuality, }: {
|
|
19
19
|
modelId: string;
|
|
20
|
+
pricingModelId?: string;
|
|
20
21
|
tokens: LlmUsageTokens | undefined;
|
|
21
22
|
responseImages: number;
|
|
22
23
|
imageSize?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -15,8 +15,9 @@ type LlmUsageTokens = {
|
|
|
15
15
|
readonly totalTokens?: number;
|
|
16
16
|
readonly toolUsePromptTokens?: number;
|
|
17
17
|
};
|
|
18
|
-
declare function estimateCallCostUsd({ modelId, tokens, responseImages, imageSize, imageQuality, }: {
|
|
18
|
+
declare function estimateCallCostUsd({ modelId, pricingModelId, tokens, responseImages, imageSize, imageQuality, }: {
|
|
19
19
|
modelId: string;
|
|
20
|
+
pricingModelId?: string;
|
|
20
21
|
tokens: LlmUsageTokens | undefined;
|
|
21
22
|
responseImages: number;
|
|
22
23
|
imageSize?: string;
|
package/dist/index.js
CHANGED
|
@@ -344,6 +344,7 @@ function resolveChatGptServiceTier(model) {
|
|
|
344
344
|
// src/openai/pricing.ts
|
|
345
345
|
var OPENAI_GPT_55_FAST_MODEL_IDS = ["gpt-5.5-fast", "chatgpt-gpt-5.5-fast"];
|
|
346
346
|
var OPENAI_GPT_55_STANDARD_MODEL_IDS = ["gpt-5.5", "chatgpt-gpt-5.5"];
|
|
347
|
+
var OPENAI_GPT_55_CONCRETE_MODEL_ID_RE = /^(?:chatgpt-)?gpt-5\.5-\d{4}-\d{2}-\d{2}$/u;
|
|
347
348
|
var OPENAI_GPT_54_FAST_MODEL_IDS = ["gpt-5.4-fast", "chatgpt-gpt-5.4-fast"];
|
|
348
349
|
var OPENAI_GPT_54_MINI_MODEL_IDS = ["gpt-5.4-mini", "chatgpt-gpt-5.4-mini"];
|
|
349
350
|
var OPENAI_GPT_54_NANO_MODEL_IDS = ["gpt-5.4-nano"];
|
|
@@ -410,7 +411,7 @@ function getOpenAiPricing(modelId) {
|
|
|
410
411
|
if (OPENAI_GPT_55_FAST_MODEL_IDS.includes(modelId)) {
|
|
411
412
|
return OPENAI_GPT_55_PRIORITY_PRICING;
|
|
412
413
|
}
|
|
413
|
-
if (OPENAI_GPT_55_STANDARD_MODEL_IDS.includes(modelId)) {
|
|
414
|
+
if (OPENAI_GPT_55_STANDARD_MODEL_IDS.includes(modelId) || OPENAI_GPT_55_CONCRETE_MODEL_ID_RE.test(modelId)) {
|
|
414
415
|
return OPENAI_GPT_55_PRICING;
|
|
415
416
|
}
|
|
416
417
|
if (OPENAI_GPT_54_FAST_MODEL_IDS.includes(modelId)) {
|
|
@@ -443,12 +444,14 @@ function resolveUsageNumber(value) {
|
|
|
443
444
|
}
|
|
444
445
|
function estimateCallCostUsd({
|
|
445
446
|
modelId,
|
|
447
|
+
pricingModelId,
|
|
446
448
|
tokens,
|
|
447
449
|
responseImages,
|
|
448
450
|
imageSize,
|
|
449
451
|
imageQuality
|
|
450
452
|
}) {
|
|
451
|
-
const
|
|
453
|
+
const pricingModelIds = resolvePricingModelIds(modelId, pricingModelId);
|
|
454
|
+
const openAiImagePricing = resolvePricing(pricingModelIds, getOpenAiImagePricing);
|
|
452
455
|
if (openAiImagePricing) {
|
|
453
456
|
return estimateOpenAiImageCostUsd({
|
|
454
457
|
pricing: openAiImagePricing,
|
|
@@ -468,7 +471,7 @@ function estimateCallCostUsd({
|
|
|
468
471
|
const toolUsePromptTokens = resolveUsageNumber(tokens.toolUsePromptTokens);
|
|
469
472
|
const promptTokenTotal = promptTokens + toolUsePromptTokens;
|
|
470
473
|
const nonCachedPrompt = Math.max(0, promptTokenTotal - cachedTokens);
|
|
471
|
-
const imagePreviewPricing = getGeminiImagePricing
|
|
474
|
+
const imagePreviewPricing = resolvePricing(pricingModelIds, getGeminiImagePricing);
|
|
472
475
|
if (imagePreviewPricing) {
|
|
473
476
|
const resolvedImageSize = imageSize && imagePreviewPricing.imagePrices[imageSize] ? imageSize : "2K";
|
|
474
477
|
const imageRate = imagePreviewPricing.imagePrices[resolvedImageSize] ?? 0;
|
|
@@ -488,7 +491,7 @@ function estimateCallCostUsd({
|
|
|
488
491
|
const imageOutputCost = imageTokensForPricing * imagePreviewPricing.outputImageRate;
|
|
489
492
|
return inputCost + cachedCost + textOutputCost + imageOutputCost;
|
|
490
493
|
}
|
|
491
|
-
const geminiPricing = getGeminiProPricing
|
|
494
|
+
const geminiPricing = resolvePricing(pricingModelIds, getGeminiProPricing);
|
|
492
495
|
if (geminiPricing) {
|
|
493
496
|
const useHighTier = promptTokenTotal > geminiPricing.threshold;
|
|
494
497
|
const inputRate = useHighTier ? geminiPricing.inputRateHigh : geminiPricing.inputRateLow;
|
|
@@ -500,7 +503,7 @@ function estimateCallCostUsd({
|
|
|
500
503
|
const outputCost = outputTokens * outputRate;
|
|
501
504
|
return inputCost + cachedCost + outputCost;
|
|
502
505
|
}
|
|
503
|
-
const fireworksPricing = getFireworksPricing
|
|
506
|
+
const fireworksPricing = resolvePricing(pricingModelIds, getFireworksPricing);
|
|
504
507
|
if (fireworksPricing) {
|
|
505
508
|
const inputCost = nonCachedPrompt * fireworksPricing.inputRate;
|
|
506
509
|
const cachedCost = cachedTokens * fireworksPricing.cachedRate;
|
|
@@ -508,7 +511,7 @@ function estimateCallCostUsd({
|
|
|
508
511
|
const outputCost = outputTokens * fireworksPricing.outputRate;
|
|
509
512
|
return inputCost + cachedCost + outputCost;
|
|
510
513
|
}
|
|
511
|
-
const openAiPricing = getOpenAiPricing
|
|
514
|
+
const openAiPricing = resolvePricing(pricingModelIds, getOpenAiPricing);
|
|
512
515
|
if (openAiPricing) {
|
|
513
516
|
const inputCost = nonCachedPrompt * openAiPricing.inputRate;
|
|
514
517
|
const cachedCost = cachedTokens * openAiPricing.cachedRate;
|
|
@@ -518,6 +521,21 @@ function estimateCallCostUsd({
|
|
|
518
521
|
}
|
|
519
522
|
return 0;
|
|
520
523
|
}
|
|
524
|
+
function resolvePricingModelIds(modelId, pricingModelId) {
|
|
525
|
+
if (pricingModelId && pricingModelId !== modelId) {
|
|
526
|
+
return [pricingModelId, modelId];
|
|
527
|
+
}
|
|
528
|
+
return [modelId];
|
|
529
|
+
}
|
|
530
|
+
function resolvePricing(modelIds, resolve) {
|
|
531
|
+
for (const modelId of modelIds) {
|
|
532
|
+
const pricing = resolve(modelId);
|
|
533
|
+
if (pricing) {
|
|
534
|
+
return pricing;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return void 0;
|
|
538
|
+
}
|
|
521
539
|
function estimateOpenAiImageCostUsd({
|
|
522
540
|
pricing,
|
|
523
541
|
responseImages,
|
|
@@ -557,6 +575,10 @@ function resolveOpenAiImagePriceResolution(imageSize) {
|
|
|
557
575
|
import os2 from "os";
|
|
558
576
|
import { TextDecoder as TextDecoder2 } from "util";
|
|
559
577
|
|
|
578
|
+
// src/utils/env.ts
|
|
579
|
+
import fs from "fs";
|
|
580
|
+
import path from "path";
|
|
581
|
+
|
|
560
582
|
// src/utils/runtimeSingleton.ts
|
|
561
583
|
var runtimeSingletonStoreKey = /* @__PURE__ */ Symbol.for("@ljoukov/llm.runtimeSingletonStore");
|
|
562
584
|
function getRuntimeSingletonStore() {
|
|
@@ -585,16 +607,7 @@ function getRuntimeSingleton(key, create) {
|
|
|
585
607
|
return createdValue;
|
|
586
608
|
}
|
|
587
609
|
|
|
588
|
-
// src/openai/chatgpt-auth.ts
|
|
589
|
-
import { Buffer as Buffer2 } from "buffer";
|
|
590
|
-
import fs2 from "fs";
|
|
591
|
-
import os from "os";
|
|
592
|
-
import path2 from "path";
|
|
593
|
-
import { z } from "zod";
|
|
594
|
-
|
|
595
610
|
// src/utils/env.ts
|
|
596
|
-
import fs from "fs";
|
|
597
|
-
import path from "path";
|
|
598
611
|
var envState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.envState"), () => ({
|
|
599
612
|
envLoaded: false
|
|
600
613
|
}));
|
|
@@ -656,6 +669,11 @@ function parseEnvLine(line) {
|
|
|
656
669
|
}
|
|
657
670
|
|
|
658
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";
|
|
659
677
|
var CHATGPT_AUTH_TOKEN_PROVIDER_URL_ENV = "CHATGPT_AUTH_TOKEN_PROVIDER_URL";
|
|
660
678
|
var CHATGPT_AUTH_TOKEN_PROVIDER_STORE_ENV = "CHATGPT_AUTH_TOKEN_PROVIDER_STORE";
|
|
661
679
|
var CHATGPT_AUTH_API_KEY_ENV = "CHATGPT_AUTH_API_KEY";
|
|
@@ -1563,19 +1581,21 @@ function createAbortError(reason) {
|
|
|
1563
1581
|
|
|
1564
1582
|
// src/openai/chatgpt-codex.ts
|
|
1565
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";
|
|
1566
1587
|
var CHATGPT_RESPONSES_EXPERIMENTAL_HEADER = "responses=experimental";
|
|
1567
1588
|
var chatGptCodexState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.chatGptCodexState"), () => ({
|
|
1568
1589
|
cachedResponsesWebSocketMode: null,
|
|
1569
1590
|
chatGptResponsesWebSocketDisabled: false
|
|
1570
1591
|
}));
|
|
1571
1592
|
async function streamChatGptCodexResponse(options) {
|
|
1572
|
-
const
|
|
1593
|
+
const endpointConfig = await resolveChatGptCodexEndpointConfig();
|
|
1573
1594
|
const mode = resolveChatGptResponsesWebSocketMode();
|
|
1574
1595
|
const fallbackStreamFactory = () => {
|
|
1575
1596
|
const streamPromise = streamChatGptCodexResponseSse({
|
|
1576
1597
|
request: options.request,
|
|
1577
|
-
|
|
1578
|
-
accountId,
|
|
1598
|
+
endpointConfig,
|
|
1579
1599
|
sessionId: options.sessionId,
|
|
1580
1600
|
signal: options.signal
|
|
1581
1601
|
});
|
|
@@ -1597,15 +1617,14 @@ async function streamChatGptCodexResponse(options) {
|
|
|
1597
1617
|
return fallbackStreamFactory();
|
|
1598
1618
|
}
|
|
1599
1619
|
const websocketHeaders = buildChatGptCodexHeaders({
|
|
1600
|
-
|
|
1601
|
-
accountId,
|
|
1620
|
+
endpointConfig,
|
|
1602
1621
|
sessionId: options.sessionId,
|
|
1603
1622
|
useWebSocket: true
|
|
1604
1623
|
});
|
|
1605
1624
|
return createAdaptiveResponsesStream({
|
|
1606
1625
|
mode,
|
|
1607
1626
|
createWebSocketStream: async () => await createResponsesWebSocketStream({
|
|
1608
|
-
url: toWebSocketUrl(
|
|
1627
|
+
url: toWebSocketUrl(endpointConfig.url),
|
|
1609
1628
|
headers: websocketHeaders,
|
|
1610
1629
|
request: options.request,
|
|
1611
1630
|
signal: options.signal
|
|
@@ -1618,14 +1637,13 @@ async function streamChatGptCodexResponse(options) {
|
|
|
1618
1637
|
}
|
|
1619
1638
|
async function streamChatGptCodexResponseSse(options) {
|
|
1620
1639
|
const headers = buildChatGptCodexHeaders({
|
|
1621
|
-
|
|
1622
|
-
accountId: options.accountId,
|
|
1640
|
+
endpointConfig: options.endpointConfig,
|
|
1623
1641
|
sessionId: options.sessionId,
|
|
1624
1642
|
useWebSocket: false
|
|
1625
1643
|
});
|
|
1626
1644
|
headers.Accept = "text/event-stream";
|
|
1627
1645
|
headers["Content-Type"] = "application/json";
|
|
1628
|
-
const response = await fetch(
|
|
1646
|
+
const response = await fetch(options.endpointConfig.url, {
|
|
1629
1647
|
method: "POST",
|
|
1630
1648
|
headers,
|
|
1631
1649
|
body: JSON.stringify(options.request),
|
|
@@ -1645,24 +1663,66 @@ function resolveChatGptResponsesWebSocketMode() {
|
|
|
1645
1663
|
if (chatGptCodexState.cachedResponsesWebSocketMode) {
|
|
1646
1664
|
return chatGptCodexState.cachedResponsesWebSocketMode;
|
|
1647
1665
|
}
|
|
1666
|
+
const explicitMode = process.env.CHATGPT_RESPONSES_WEBSOCKET_MODE ?? process.env.OPENAI_RESPONSES_WEBSOCKET_MODE;
|
|
1667
|
+
const defaultMode = resolveChatGptCodexProxyConfig() ? "off" : "auto";
|
|
1648
1668
|
chatGptCodexState.cachedResponsesWebSocketMode = resolveResponsesWebSocketMode(
|
|
1649
|
-
|
|
1650
|
-
|
|
1669
|
+
explicitMode,
|
|
1670
|
+
defaultMode
|
|
1651
1671
|
);
|
|
1652
1672
|
return chatGptCodexState.cachedResponsesWebSocketMode;
|
|
1653
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 url = process.env[CHATGPT_CODEX_PROXY_URL_ENV]?.trim();
|
|
1694
|
+
if (!url) {
|
|
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,
|
|
1706
|
+
apiKey
|
|
1707
|
+
};
|
|
1708
|
+
}
|
|
1654
1709
|
function buildChatGptCodexHeaders(options) {
|
|
1655
1710
|
const openAiBeta = options.useWebSocket ? mergeOpenAiBetaHeader(
|
|
1656
1711
|
CHATGPT_RESPONSES_EXPERIMENTAL_HEADER,
|
|
1657
1712
|
OPENAI_BETA_RESPONSES_WEBSOCKETS_V2
|
|
1658
1713
|
) : CHATGPT_RESPONSES_EXPERIMENTAL_HEADER;
|
|
1659
1714
|
const headers = {
|
|
1660
|
-
Authorization: `Bearer ${options.access}`,
|
|
1661
|
-
"chatgpt-account-id": options.accountId,
|
|
1662
1715
|
"OpenAI-Beta": openAiBeta,
|
|
1663
1716
|
originator: "llm",
|
|
1664
1717
|
"User-Agent": buildUserAgent()
|
|
1665
1718
|
};
|
|
1719
|
+
if (options.endpointConfig.kind === "proxy") {
|
|
1720
|
+
headers.Authorization = `Bearer ${options.endpointConfig.apiKey}`;
|
|
1721
|
+
headers["x-codex-proxy-auth"] = options.endpointConfig.apiKey;
|
|
1722
|
+
} else {
|
|
1723
|
+
headers.Authorization = `Bearer ${options.endpointConfig.access}`;
|
|
1724
|
+
headers["chatgpt-account-id"] = options.endpointConfig.accountId;
|
|
1725
|
+
}
|
|
1666
1726
|
if (options.sessionId) {
|
|
1667
1727
|
headers.session_id = options.sessionId;
|
|
1668
1728
|
}
|
|
@@ -8329,6 +8389,7 @@ async function runTextCall(params) {
|
|
|
8329
8389
|
const outputAttachments = collectLoggedAttachmentsFromLlmParts(mergedParts, "output");
|
|
8330
8390
|
const costUsd = estimateCallCostUsd({
|
|
8331
8391
|
modelId: modelVersion,
|
|
8392
|
+
pricingModelId: request.model,
|
|
8332
8393
|
tokens: latestUsage,
|
|
8333
8394
|
responseImages,
|
|
8334
8395
|
imageSize: request.imageSize
|
|
@@ -9072,6 +9133,7 @@ async function runToolLoop(request) {
|
|
|
9072
9133
|
const modelCompletedAtMs = Date.now();
|
|
9073
9134
|
const stepCostUsd = estimateCallCostUsd({
|
|
9074
9135
|
modelId: modelVersion,
|
|
9136
|
+
pricingModelId: request.model,
|
|
9075
9137
|
tokens: usageTokens,
|
|
9076
9138
|
responseImages: 0
|
|
9077
9139
|
});
|
|
@@ -9403,6 +9465,7 @@ async function runToolLoop(request) {
|
|
|
9403
9465
|
usageTokens = extractChatGptUsageTokens(response.usage);
|
|
9404
9466
|
const stepCostUsd = estimateCallCostUsd({
|
|
9405
9467
|
modelId: modelVersion,
|
|
9468
|
+
pricingModelId: request.model,
|
|
9406
9469
|
tokens: usageTokens,
|
|
9407
9470
|
responseImages: 0
|
|
9408
9471
|
});
|
|
@@ -9731,6 +9794,7 @@ async function runToolLoop(request) {
|
|
|
9731
9794
|
usageTokens = extractFireworksUsageTokens(response.usage);
|
|
9732
9795
|
const stepCostUsd = estimateCallCostUsd({
|
|
9733
9796
|
modelId: modelVersion,
|
|
9797
|
+
pricingModelId: request.model,
|
|
9734
9798
|
tokens: usageTokens,
|
|
9735
9799
|
responseImages: 0
|
|
9736
9800
|
});
|
|
@@ -10093,6 +10157,7 @@ async function runToolLoop(request) {
|
|
|
10093
10157
|
);
|
|
10094
10158
|
const stepCostUsd = estimateCallCostUsd({
|
|
10095
10159
|
modelId: modelVersion,
|
|
10160
|
+
pricingModelId: request.model,
|
|
10096
10161
|
tokens: usageTokens,
|
|
10097
10162
|
responseImages: 0
|
|
10098
10163
|
});
|