@ljoukov/llm 4.0.7 → 4.0.8
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/index.cjs +187 -118
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +187 -118
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -441,6 +441,34 @@ function estimateCallCostUsd({
|
|
|
441
441
|
var import_node_os2 = __toESM(require("os"), 1);
|
|
442
442
|
var import_node_util = require("util");
|
|
443
443
|
|
|
444
|
+
// src/utils/runtimeSingleton.ts
|
|
445
|
+
var runtimeSingletonStoreKey = /* @__PURE__ */ Symbol.for("@ljoukov/llm.runtimeSingletonStore");
|
|
446
|
+
function getRuntimeSingletonStore() {
|
|
447
|
+
const globalObject = globalThis;
|
|
448
|
+
const existingStore = globalObject[runtimeSingletonStoreKey];
|
|
449
|
+
if (existingStore) {
|
|
450
|
+
return existingStore;
|
|
451
|
+
}
|
|
452
|
+
const store = /* @__PURE__ */ new Map();
|
|
453
|
+
Object.defineProperty(globalObject, runtimeSingletonStoreKey, {
|
|
454
|
+
value: store,
|
|
455
|
+
enumerable: false,
|
|
456
|
+
configurable: false,
|
|
457
|
+
writable: false
|
|
458
|
+
});
|
|
459
|
+
return store;
|
|
460
|
+
}
|
|
461
|
+
function getRuntimeSingleton(key, create) {
|
|
462
|
+
const store = getRuntimeSingletonStore();
|
|
463
|
+
const existingValue = store.get(key);
|
|
464
|
+
if (existingValue !== void 0) {
|
|
465
|
+
return existingValue;
|
|
466
|
+
}
|
|
467
|
+
const createdValue = create();
|
|
468
|
+
store.set(key, createdValue);
|
|
469
|
+
return createdValue;
|
|
470
|
+
}
|
|
471
|
+
|
|
444
472
|
// src/openai/chatgpt-auth.ts
|
|
445
473
|
var import_node_buffer = require("buffer");
|
|
446
474
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
@@ -451,14 +479,16 @@ var import_zod = require("zod");
|
|
|
451
479
|
// src/utils/env.ts
|
|
452
480
|
var import_node_fs = __toESM(require("fs"), 1);
|
|
453
481
|
var import_node_path = __toESM(require("path"), 1);
|
|
454
|
-
var
|
|
482
|
+
var envState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.envState"), () => ({
|
|
483
|
+
envLoaded: false
|
|
484
|
+
}));
|
|
455
485
|
function loadLocalEnv() {
|
|
456
|
-
if (envLoaded) {
|
|
486
|
+
if (envState.envLoaded) {
|
|
457
487
|
return;
|
|
458
488
|
}
|
|
459
489
|
const envPath = import_node_path.default.join(process.cwd(), ".env.local");
|
|
460
490
|
loadEnvFromFile(envPath, { override: false });
|
|
461
|
-
envLoaded = true;
|
|
491
|
+
envState.envLoaded = true;
|
|
462
492
|
}
|
|
463
493
|
function loadEnvFromFile(filePath, { override = false } = {}) {
|
|
464
494
|
let content;
|
|
@@ -544,8 +574,10 @@ var ExchangeResponseSchema = import_zod.z.object({
|
|
|
544
574
|
expires_in: import_zod.z.union([import_zod.z.number(), import_zod.z.string()]),
|
|
545
575
|
id_token: import_zod.z.string().optional()
|
|
546
576
|
});
|
|
547
|
-
var
|
|
548
|
-
|
|
577
|
+
var chatGptAuthState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.chatGptAuthState"), () => ({
|
|
578
|
+
cachedProfile: null,
|
|
579
|
+
refreshPromise: null
|
|
580
|
+
}));
|
|
549
581
|
async function fetchChatGptAuthProfileFromTokenProvider(options) {
|
|
550
582
|
const base = options.baseUrl.replace(/\/+$/u, "");
|
|
551
583
|
const store = options.store?.trim() ? options.store.trim() : "kv";
|
|
@@ -646,13 +678,13 @@ async function getChatGptAuthProfile() {
|
|
|
646
678
|
const tokenProviderUrl = process.env[CHATGPT_AUTH_TOKEN_PROVIDER_URL_ENV];
|
|
647
679
|
const tokenProviderKey = process.env[CHATGPT_AUTH_TOKEN_PROVIDER_API_KEY_ENV] ?? process.env[CHATGPT_AUTH_API_KEY_ENV];
|
|
648
680
|
if (tokenProviderUrl && tokenProviderUrl.trim().length > 0 && tokenProviderKey && tokenProviderKey.trim().length > 0) {
|
|
649
|
-
if (cachedProfile && !isExpired(cachedProfile)) {
|
|
650
|
-
return cachedProfile;
|
|
681
|
+
if (chatGptAuthState.cachedProfile && !isExpired(chatGptAuthState.cachedProfile)) {
|
|
682
|
+
return chatGptAuthState.cachedProfile;
|
|
651
683
|
}
|
|
652
|
-
if (refreshPromise) {
|
|
653
|
-
return refreshPromise;
|
|
684
|
+
if (chatGptAuthState.refreshPromise) {
|
|
685
|
+
return chatGptAuthState.refreshPromise;
|
|
654
686
|
}
|
|
655
|
-
refreshPromise = (async () => {
|
|
687
|
+
chatGptAuthState.refreshPromise = (async () => {
|
|
656
688
|
try {
|
|
657
689
|
const store = process.env[CHATGPT_AUTH_TOKEN_PROVIDER_STORE_ENV];
|
|
658
690
|
const profile = await fetchChatGptAuthProfileFromTokenProvider({
|
|
@@ -660,31 +692,31 @@ async function getChatGptAuthProfile() {
|
|
|
660
692
|
apiKey: tokenProviderKey,
|
|
661
693
|
store: store ?? void 0
|
|
662
694
|
});
|
|
663
|
-
cachedProfile = profile;
|
|
695
|
+
chatGptAuthState.cachedProfile = profile;
|
|
664
696
|
return profile;
|
|
665
697
|
} finally {
|
|
666
|
-
refreshPromise = null;
|
|
698
|
+
chatGptAuthState.refreshPromise = null;
|
|
667
699
|
}
|
|
668
700
|
})();
|
|
669
|
-
return refreshPromise;
|
|
701
|
+
return chatGptAuthState.refreshPromise;
|
|
670
702
|
}
|
|
671
|
-
if (cachedProfile && !isExpired(cachedProfile)) {
|
|
672
|
-
return cachedProfile;
|
|
703
|
+
if (chatGptAuthState.cachedProfile && !isExpired(chatGptAuthState.cachedProfile)) {
|
|
704
|
+
return chatGptAuthState.cachedProfile;
|
|
673
705
|
}
|
|
674
|
-
if (refreshPromise) {
|
|
675
|
-
return refreshPromise;
|
|
706
|
+
if (chatGptAuthState.refreshPromise) {
|
|
707
|
+
return chatGptAuthState.refreshPromise;
|
|
676
708
|
}
|
|
677
|
-
refreshPromise = (async () => {
|
|
709
|
+
chatGptAuthState.refreshPromise = (async () => {
|
|
678
710
|
try {
|
|
679
|
-
const baseProfile = cachedProfile ?? loadAuthProfileFromCodexStore();
|
|
711
|
+
const baseProfile = chatGptAuthState.cachedProfile ?? loadAuthProfileFromCodexStore();
|
|
680
712
|
const profile = isExpired(baseProfile) ? await refreshAndPersistCodexProfile(baseProfile) : baseProfile;
|
|
681
|
-
cachedProfile = profile;
|
|
713
|
+
chatGptAuthState.cachedProfile = profile;
|
|
682
714
|
return profile;
|
|
683
715
|
} finally {
|
|
684
|
-
refreshPromise = null;
|
|
716
|
+
chatGptAuthState.refreshPromise = null;
|
|
685
717
|
}
|
|
686
718
|
})();
|
|
687
|
-
return refreshPromise;
|
|
719
|
+
return chatGptAuthState.refreshPromise;
|
|
688
720
|
}
|
|
689
721
|
function resolveCodexHome() {
|
|
690
722
|
const codexHome = process.env.CODEX_HOME;
|
|
@@ -1416,8 +1448,10 @@ function createAbortError(reason) {
|
|
|
1416
1448
|
// src/openai/chatgpt-codex.ts
|
|
1417
1449
|
var CHATGPT_CODEX_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses";
|
|
1418
1450
|
var CHATGPT_RESPONSES_EXPERIMENTAL_HEADER = "responses=experimental";
|
|
1419
|
-
var
|
|
1420
|
-
|
|
1451
|
+
var chatGptCodexState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.chatGptCodexState"), () => ({
|
|
1452
|
+
cachedResponsesWebSocketMode: null,
|
|
1453
|
+
chatGptResponsesWebSocketDisabled: false
|
|
1454
|
+
}));
|
|
1421
1455
|
async function streamChatGptCodexResponse(options) {
|
|
1422
1456
|
const { access, accountId } = await getChatGptAuthProfile();
|
|
1423
1457
|
const mode = resolveChatGptResponsesWebSocketMode();
|
|
@@ -1443,7 +1477,7 @@ async function streamChatGptCodexResponse(options) {
|
|
|
1443
1477
|
}
|
|
1444
1478
|
};
|
|
1445
1479
|
};
|
|
1446
|
-
if (mode === "off" || chatGptResponsesWebSocketDisabled) {
|
|
1480
|
+
if (mode === "off" || chatGptCodexState.chatGptResponsesWebSocketDisabled) {
|
|
1447
1481
|
return fallbackStreamFactory();
|
|
1448
1482
|
}
|
|
1449
1483
|
const websocketHeaders = buildChatGptCodexHeaders({
|
|
@@ -1462,7 +1496,7 @@ async function streamChatGptCodexResponse(options) {
|
|
|
1462
1496
|
}),
|
|
1463
1497
|
createFallbackStream: fallbackStreamFactory,
|
|
1464
1498
|
onWebSocketFallback: () => {
|
|
1465
|
-
chatGptResponsesWebSocketDisabled = true;
|
|
1499
|
+
chatGptCodexState.chatGptResponsesWebSocketDisabled = true;
|
|
1466
1500
|
}
|
|
1467
1501
|
});
|
|
1468
1502
|
}
|
|
@@ -1492,14 +1526,14 @@ async function streamChatGptCodexResponseSse(options) {
|
|
|
1492
1526
|
return parseEventStream(body);
|
|
1493
1527
|
}
|
|
1494
1528
|
function resolveChatGptResponsesWebSocketMode() {
|
|
1495
|
-
if (cachedResponsesWebSocketMode) {
|
|
1496
|
-
return cachedResponsesWebSocketMode;
|
|
1529
|
+
if (chatGptCodexState.cachedResponsesWebSocketMode) {
|
|
1530
|
+
return chatGptCodexState.cachedResponsesWebSocketMode;
|
|
1497
1531
|
}
|
|
1498
|
-
cachedResponsesWebSocketMode = resolveResponsesWebSocketMode(
|
|
1532
|
+
chatGptCodexState.cachedResponsesWebSocketMode = resolveResponsesWebSocketMode(
|
|
1499
1533
|
process.env.CHATGPT_RESPONSES_WEBSOCKET_MODE ?? process.env.OPENAI_RESPONSES_WEBSOCKET_MODE,
|
|
1500
1534
|
"auto"
|
|
1501
1535
|
);
|
|
1502
|
-
return cachedResponsesWebSocketMode;
|
|
1536
|
+
return chatGptCodexState.cachedResponsesWebSocketMode;
|
|
1503
1537
|
}
|
|
1504
1538
|
function buildChatGptCodexHeaders(options) {
|
|
1505
1539
|
const openAiBeta = options.useWebSocket ? mergeOpenAiBetaHeader(
|
|
@@ -1537,8 +1571,8 @@ async function collectChatGptCodexResponse(options) {
|
|
|
1537
1571
|
}
|
|
1538
1572
|
});
|
|
1539
1573
|
} catch (error) {
|
|
1540
|
-
if (!sawAnyDelta && !retriedViaSseFallback && shouldRetryViaSseFallback(error) && !chatGptResponsesWebSocketDisabled) {
|
|
1541
|
-
chatGptResponsesWebSocketDisabled = true;
|
|
1574
|
+
if (!sawAnyDelta && !retriedViaSseFallback && shouldRetryViaSseFallback(error) && !chatGptCodexState.chatGptResponsesWebSocketDisabled) {
|
|
1575
|
+
chatGptCodexState.chatGptResponsesWebSocketDisabled = true;
|
|
1542
1576
|
retriedViaSseFallback = true;
|
|
1543
1577
|
continue;
|
|
1544
1578
|
}
|
|
@@ -1774,7 +1808,12 @@ var MODEL_CONCURRENCY_PROVIDERS = [
|
|
|
1774
1808
|
"google",
|
|
1775
1809
|
"fireworks"
|
|
1776
1810
|
];
|
|
1777
|
-
var
|
|
1811
|
+
var modelConcurrencyState = getRuntimeSingleton(
|
|
1812
|
+
/* @__PURE__ */ Symbol.for("@ljoukov/llm.modelConcurrencyState"),
|
|
1813
|
+
() => ({
|
|
1814
|
+
configuredModelConcurrency: normalizeModelConcurrencyConfig({})
|
|
1815
|
+
})
|
|
1816
|
+
);
|
|
1778
1817
|
function clampModelConcurrencyCap(value) {
|
|
1779
1818
|
if (!Number.isFinite(value)) {
|
|
1780
1819
|
return DEFAULT_MODEL_CONCURRENCY_CAP;
|
|
@@ -1848,14 +1887,14 @@ function resolveDefaultProviderCap(provider, modelId) {
|
|
|
1848
1887
|
return DEFAULT_FIREWORKS_MODEL_CONCURRENCY_CAP;
|
|
1849
1888
|
}
|
|
1850
1889
|
function configureModelConcurrency(config = {}) {
|
|
1851
|
-
configuredModelConcurrency = normalizeModelConcurrencyConfig(config);
|
|
1890
|
+
modelConcurrencyState.configuredModelConcurrency = normalizeModelConcurrencyConfig(config);
|
|
1852
1891
|
}
|
|
1853
1892
|
function resetModelConcurrencyConfig() {
|
|
1854
|
-
configuredModelConcurrency = normalizeModelConcurrencyConfig({});
|
|
1893
|
+
modelConcurrencyState.configuredModelConcurrency = normalizeModelConcurrencyConfig({});
|
|
1855
1894
|
}
|
|
1856
1895
|
function resolveModelConcurrencyCap(options) {
|
|
1857
1896
|
const modelId = options.modelId ? normalizeModelIdForConfig(options.modelId) : void 0;
|
|
1858
|
-
const config = options.config ? normalizeModelConcurrencyConfig(options.config) : configuredModelConcurrency;
|
|
1897
|
+
const config = options.config ? normalizeModelConcurrencyConfig(options.config) : modelConcurrencyState.configuredModelConcurrency;
|
|
1859
1898
|
const providerModelCap = modelId ? config.providerModelCaps[options.provider].get(modelId) : void 0;
|
|
1860
1899
|
if (providerModelCap !== void 0) {
|
|
1861
1900
|
return providerModelCap;
|
|
@@ -2089,32 +2128,37 @@ var import_openai = __toESM(require("openai"), 1);
|
|
|
2089
2128
|
var import_undici = require("undici");
|
|
2090
2129
|
var DEFAULT_FIREWORKS_BASE_URL = "https://api.fireworks.ai/inference/v1";
|
|
2091
2130
|
var DEFAULT_FIREWORKS_TIMEOUT_MS = 15 * 6e4;
|
|
2092
|
-
var
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2131
|
+
var fireworksClientState = getRuntimeSingleton(
|
|
2132
|
+
/* @__PURE__ */ Symbol.for("@ljoukov/llm.fireworksClientState"),
|
|
2133
|
+
() => ({
|
|
2134
|
+
cachedClient: null,
|
|
2135
|
+
cachedFetch: null,
|
|
2136
|
+
cachedBaseUrl: null,
|
|
2137
|
+
cachedApiKey: null,
|
|
2138
|
+
cachedTimeoutMs: null
|
|
2139
|
+
})
|
|
2140
|
+
);
|
|
2097
2141
|
function resolveTimeoutMs() {
|
|
2098
|
-
if (cachedTimeoutMs !== null) {
|
|
2099
|
-
return cachedTimeoutMs;
|
|
2142
|
+
if (fireworksClientState.cachedTimeoutMs !== null) {
|
|
2143
|
+
return fireworksClientState.cachedTimeoutMs;
|
|
2100
2144
|
}
|
|
2101
2145
|
const raw = process.env.FIREWORKS_TIMEOUT_MS;
|
|
2102
2146
|
const parsed = raw ? Number(raw) : Number.NaN;
|
|
2103
|
-
cachedTimeoutMs = Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_FIREWORKS_TIMEOUT_MS;
|
|
2104
|
-
return cachedTimeoutMs;
|
|
2147
|
+
fireworksClientState.cachedTimeoutMs = Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_FIREWORKS_TIMEOUT_MS;
|
|
2148
|
+
return fireworksClientState.cachedTimeoutMs;
|
|
2105
2149
|
}
|
|
2106
2150
|
function resolveBaseUrl() {
|
|
2107
|
-
if (cachedBaseUrl !== null) {
|
|
2108
|
-
return cachedBaseUrl;
|
|
2151
|
+
if (fireworksClientState.cachedBaseUrl !== null) {
|
|
2152
|
+
return fireworksClientState.cachedBaseUrl;
|
|
2109
2153
|
}
|
|
2110
2154
|
loadLocalEnv();
|
|
2111
2155
|
const raw = process.env.FIREWORKS_BASE_URL?.trim();
|
|
2112
|
-
cachedBaseUrl = raw && raw.length > 0 ? raw : DEFAULT_FIREWORKS_BASE_URL;
|
|
2113
|
-
return cachedBaseUrl;
|
|
2156
|
+
fireworksClientState.cachedBaseUrl = raw && raw.length > 0 ? raw : DEFAULT_FIREWORKS_BASE_URL;
|
|
2157
|
+
return fireworksClientState.cachedBaseUrl;
|
|
2114
2158
|
}
|
|
2115
2159
|
function resolveApiKey() {
|
|
2116
|
-
if (cachedApiKey !== null) {
|
|
2117
|
-
return cachedApiKey;
|
|
2160
|
+
if (fireworksClientState.cachedApiKey !== null) {
|
|
2161
|
+
return fireworksClientState.cachedApiKey;
|
|
2118
2162
|
}
|
|
2119
2163
|
loadLocalEnv();
|
|
2120
2164
|
const raw = process.env.FIREWORKS_TOKEN ?? process.env.FIREWORKS_API_KEY;
|
|
@@ -2124,46 +2168,51 @@ function resolveApiKey() {
|
|
|
2124
2168
|
"FIREWORKS_TOKEN (or FIREWORKS_API_KEY) must be provided to access Fireworks APIs."
|
|
2125
2169
|
);
|
|
2126
2170
|
}
|
|
2127
|
-
cachedApiKey = token;
|
|
2128
|
-
return cachedApiKey;
|
|
2171
|
+
fireworksClientState.cachedApiKey = token;
|
|
2172
|
+
return fireworksClientState.cachedApiKey;
|
|
2129
2173
|
}
|
|
2130
2174
|
function getFireworksFetch() {
|
|
2131
|
-
if (cachedFetch) {
|
|
2132
|
-
return cachedFetch;
|
|
2175
|
+
if (fireworksClientState.cachedFetch) {
|
|
2176
|
+
return fireworksClientState.cachedFetch;
|
|
2133
2177
|
}
|
|
2134
2178
|
const timeoutMs = resolveTimeoutMs();
|
|
2135
2179
|
const dispatcher = new import_undici.Agent({
|
|
2136
2180
|
bodyTimeout: timeoutMs,
|
|
2137
2181
|
headersTimeout: timeoutMs
|
|
2138
2182
|
});
|
|
2139
|
-
cachedFetch = ((input, init) => {
|
|
2183
|
+
fireworksClientState.cachedFetch = ((input, init) => {
|
|
2140
2184
|
return (0, import_undici.fetch)(input, {
|
|
2141
2185
|
...init ?? {},
|
|
2142
2186
|
dispatcher
|
|
2143
2187
|
});
|
|
2144
2188
|
});
|
|
2145
|
-
return cachedFetch;
|
|
2189
|
+
return fireworksClientState.cachedFetch;
|
|
2146
2190
|
}
|
|
2147
2191
|
function getFireworksClient() {
|
|
2148
|
-
if (cachedClient) {
|
|
2149
|
-
return cachedClient;
|
|
2192
|
+
if (fireworksClientState.cachedClient) {
|
|
2193
|
+
return fireworksClientState.cachedClient;
|
|
2150
2194
|
}
|
|
2151
|
-
cachedClient = new import_openai.default({
|
|
2195
|
+
fireworksClientState.cachedClient = new import_openai.default({
|
|
2152
2196
|
apiKey: resolveApiKey(),
|
|
2153
2197
|
baseURL: resolveBaseUrl(),
|
|
2154
2198
|
timeout: resolveTimeoutMs(),
|
|
2155
2199
|
fetch: getFireworksFetch()
|
|
2156
2200
|
});
|
|
2157
|
-
return cachedClient;
|
|
2201
|
+
return fireworksClientState.cachedClient;
|
|
2158
2202
|
}
|
|
2159
2203
|
|
|
2160
2204
|
// src/fireworks/calls.ts
|
|
2161
2205
|
var DEFAULT_SCHEDULER_KEY = "__default__";
|
|
2162
|
-
var
|
|
2206
|
+
var fireworksCallState = getRuntimeSingleton(
|
|
2207
|
+
/* @__PURE__ */ Symbol.for("@ljoukov/llm.fireworksCallState"),
|
|
2208
|
+
() => ({
|
|
2209
|
+
schedulerByModel: /* @__PURE__ */ new Map()
|
|
2210
|
+
})
|
|
2211
|
+
);
|
|
2163
2212
|
function getSchedulerForModel(modelId) {
|
|
2164
2213
|
const normalizedModelId = modelId?.trim();
|
|
2165
2214
|
const schedulerKey = normalizedModelId && normalizedModelId.length > 0 ? normalizedModelId : DEFAULT_SCHEDULER_KEY;
|
|
2166
|
-
const existing = schedulerByModel.get(schedulerKey);
|
|
2215
|
+
const existing = fireworksCallState.schedulerByModel.get(schedulerKey);
|
|
2167
2216
|
if (existing) {
|
|
2168
2217
|
return existing;
|
|
2169
2218
|
}
|
|
@@ -2175,7 +2224,7 @@ function getSchedulerForModel(modelId) {
|
|
|
2175
2224
|
minIntervalBetweenStartMs: 200,
|
|
2176
2225
|
startJitterMs: 200
|
|
2177
2226
|
});
|
|
2178
|
-
schedulerByModel.set(schedulerKey, created);
|
|
2227
|
+
fireworksCallState.schedulerByModel.set(schedulerKey, created);
|
|
2179
2228
|
return created;
|
|
2180
2229
|
}
|
|
2181
2230
|
async function runFireworksCall(fn, modelId, runOptions) {
|
|
@@ -2222,7 +2271,10 @@ var ServiceAccountSchema = import_zod2.z.object({
|
|
|
2222
2271
|
privateKey: private_key.replace(/\\n/g, "\n"),
|
|
2223
2272
|
tokenUri: token_uri
|
|
2224
2273
|
}));
|
|
2225
|
-
var
|
|
2274
|
+
var googleAuthState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.googleAuthState"), () => ({
|
|
2275
|
+
cachedServiceAccount: null,
|
|
2276
|
+
authClientCache: /* @__PURE__ */ new Map()
|
|
2277
|
+
}));
|
|
2226
2278
|
function parseGoogleServiceAccount(input) {
|
|
2227
2279
|
let parsed;
|
|
2228
2280
|
try {
|
|
@@ -2233,16 +2285,16 @@ function parseGoogleServiceAccount(input) {
|
|
|
2233
2285
|
return ServiceAccountSchema.parse(parsed);
|
|
2234
2286
|
}
|
|
2235
2287
|
function getGoogleServiceAccount() {
|
|
2236
|
-
if (cachedServiceAccount) {
|
|
2237
|
-
return cachedServiceAccount;
|
|
2288
|
+
if (googleAuthState.cachedServiceAccount) {
|
|
2289
|
+
return googleAuthState.cachedServiceAccount;
|
|
2238
2290
|
}
|
|
2239
2291
|
loadLocalEnv();
|
|
2240
2292
|
const raw = process.env.GOOGLE_SERVICE_ACCOUNT_JSON;
|
|
2241
2293
|
if (!raw || raw.trim().length === 0) {
|
|
2242
2294
|
throw new Error("GOOGLE_SERVICE_ACCOUNT_JSON must be provided for Google APIs access.");
|
|
2243
2295
|
}
|
|
2244
|
-
cachedServiceAccount = parseGoogleServiceAccount(raw);
|
|
2245
|
-
return cachedServiceAccount;
|
|
2296
|
+
googleAuthState.cachedServiceAccount = parseGoogleServiceAccount(raw);
|
|
2297
|
+
return googleAuthState.cachedServiceAccount;
|
|
2246
2298
|
}
|
|
2247
2299
|
function normaliseScopes(scopes) {
|
|
2248
2300
|
if (!scopes) {
|
|
@@ -2294,8 +2346,10 @@ function isGeminiImageModelId(value) {
|
|
|
2294
2346
|
}
|
|
2295
2347
|
var CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform";
|
|
2296
2348
|
var DEFAULT_VERTEX_LOCATION = "global";
|
|
2297
|
-
var
|
|
2298
|
-
|
|
2349
|
+
var geminiClientState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.geminiClientState"), () => ({
|
|
2350
|
+
geminiConfiguration: {},
|
|
2351
|
+
clientPromise: void 0
|
|
2352
|
+
}));
|
|
2299
2353
|
function normaliseConfigValue(value) {
|
|
2300
2354
|
if (value === void 0 || value === null) {
|
|
2301
2355
|
return void 0;
|
|
@@ -2306,14 +2360,14 @@ function normaliseConfigValue(value) {
|
|
|
2306
2360
|
function configureGemini(options = {}) {
|
|
2307
2361
|
const nextProjectId = normaliseConfigValue(options.projectId);
|
|
2308
2362
|
const nextLocation = normaliseConfigValue(options.location);
|
|
2309
|
-
geminiConfiguration = {
|
|
2310
|
-
projectId: nextProjectId !== void 0 ? nextProjectId : geminiConfiguration.projectId,
|
|
2311
|
-
location: nextLocation !== void 0 ? nextLocation : geminiConfiguration.location
|
|
2363
|
+
geminiClientState.geminiConfiguration = {
|
|
2364
|
+
projectId: nextProjectId !== void 0 ? nextProjectId : geminiClientState.geminiConfiguration.projectId,
|
|
2365
|
+
location: nextLocation !== void 0 ? nextLocation : geminiClientState.geminiConfiguration.location
|
|
2312
2366
|
};
|
|
2313
|
-
clientPromise = void 0;
|
|
2367
|
+
geminiClientState.clientPromise = void 0;
|
|
2314
2368
|
}
|
|
2315
2369
|
function resolveProjectId() {
|
|
2316
|
-
const override = geminiConfiguration.projectId;
|
|
2370
|
+
const override = geminiClientState.geminiConfiguration.projectId;
|
|
2317
2371
|
if (override) {
|
|
2318
2372
|
return override;
|
|
2319
2373
|
}
|
|
@@ -2321,15 +2375,15 @@ function resolveProjectId() {
|
|
|
2321
2375
|
return serviceAccount.projectId;
|
|
2322
2376
|
}
|
|
2323
2377
|
function resolveLocation() {
|
|
2324
|
-
const override = geminiConfiguration.location;
|
|
2378
|
+
const override = geminiClientState.geminiConfiguration.location;
|
|
2325
2379
|
if (override) {
|
|
2326
2380
|
return override;
|
|
2327
2381
|
}
|
|
2328
2382
|
return DEFAULT_VERTEX_LOCATION;
|
|
2329
2383
|
}
|
|
2330
2384
|
async function getGeminiClient() {
|
|
2331
|
-
if (!clientPromise) {
|
|
2332
|
-
clientPromise = Promise.resolve().then(() => {
|
|
2385
|
+
if (!geminiClientState.clientPromise) {
|
|
2386
|
+
geminiClientState.clientPromise = Promise.resolve().then(() => {
|
|
2333
2387
|
const projectId = resolveProjectId();
|
|
2334
2388
|
const location = resolveLocation();
|
|
2335
2389
|
const googleAuthOptions = getGoogleAuthOptions(CLOUD_PLATFORM_SCOPE);
|
|
@@ -2341,7 +2395,7 @@ async function getGeminiClient() {
|
|
|
2341
2395
|
});
|
|
2342
2396
|
});
|
|
2343
2397
|
}
|
|
2344
|
-
return clientPromise;
|
|
2398
|
+
return geminiClientState.clientPromise;
|
|
2345
2399
|
}
|
|
2346
2400
|
|
|
2347
2401
|
// src/google/calls.ts
|
|
@@ -2537,11 +2591,13 @@ function retryDelayMs(attempt) {
|
|
|
2537
2591
|
return base + jitter;
|
|
2538
2592
|
}
|
|
2539
2593
|
var DEFAULT_SCHEDULER_KEY2 = "__default__";
|
|
2540
|
-
var
|
|
2594
|
+
var googleCallState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.googleCallState"), () => ({
|
|
2595
|
+
schedulerByModel: /* @__PURE__ */ new Map()
|
|
2596
|
+
}));
|
|
2541
2597
|
function getSchedulerForModel2(modelId) {
|
|
2542
2598
|
const normalizedModelId = modelId?.trim();
|
|
2543
2599
|
const schedulerKey = normalizedModelId && normalizedModelId.length > 0 ? normalizedModelId : DEFAULT_SCHEDULER_KEY2;
|
|
2544
|
-
const existing =
|
|
2600
|
+
const existing = googleCallState.schedulerByModel.get(schedulerKey);
|
|
2545
2601
|
if (existing) {
|
|
2546
2602
|
return existing;
|
|
2547
2603
|
}
|
|
@@ -2564,7 +2620,7 @@ function getSchedulerForModel2(modelId) {
|
|
|
2564
2620
|
}
|
|
2565
2621
|
}
|
|
2566
2622
|
});
|
|
2567
|
-
|
|
2623
|
+
googleCallState.schedulerByModel.set(schedulerKey, created);
|
|
2568
2624
|
return created;
|
|
2569
2625
|
}
|
|
2570
2626
|
async function runGeminiCall(fn, modelId, runOptions) {
|
|
@@ -2574,53 +2630,55 @@ async function runGeminiCall(fn, modelId, runOptions) {
|
|
|
2574
2630
|
// src/openai/client.ts
|
|
2575
2631
|
var import_openai2 = __toESM(require("openai"), 1);
|
|
2576
2632
|
var import_undici2 = require("undici");
|
|
2577
|
-
var
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2633
|
+
var openAiClientState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.openAiClientState"), () => ({
|
|
2634
|
+
cachedApiKey: null,
|
|
2635
|
+
cachedClient: null,
|
|
2636
|
+
cachedFetch: null,
|
|
2637
|
+
cachedTimeoutMs: null,
|
|
2638
|
+
openAiResponsesWebSocketMode: null,
|
|
2639
|
+
openAiResponsesWebSocketDisabled: false
|
|
2640
|
+
}));
|
|
2583
2641
|
var DEFAULT_OPENAI_TIMEOUT_MS = 15 * 6e4;
|
|
2584
2642
|
function resolveOpenAiTimeoutMs() {
|
|
2585
|
-
if (
|
|
2586
|
-
return
|
|
2643
|
+
if (openAiClientState.cachedTimeoutMs !== null) {
|
|
2644
|
+
return openAiClientState.cachedTimeoutMs;
|
|
2587
2645
|
}
|
|
2588
2646
|
const raw = process.env.OPENAI_STREAM_TIMEOUT_MS ?? process.env.OPENAI_TIMEOUT_MS;
|
|
2589
2647
|
const parsed = raw ? Number(raw) : Number.NaN;
|
|
2590
|
-
|
|
2591
|
-
return
|
|
2648
|
+
openAiClientState.cachedTimeoutMs = Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_OPENAI_TIMEOUT_MS;
|
|
2649
|
+
return openAiClientState.cachedTimeoutMs;
|
|
2592
2650
|
}
|
|
2593
2651
|
function getOpenAiFetch() {
|
|
2594
|
-
if (
|
|
2595
|
-
return
|
|
2652
|
+
if (openAiClientState.cachedFetch) {
|
|
2653
|
+
return openAiClientState.cachedFetch;
|
|
2596
2654
|
}
|
|
2597
2655
|
const timeoutMs = resolveOpenAiTimeoutMs();
|
|
2598
2656
|
const dispatcher = new import_undici2.Agent({
|
|
2599
2657
|
bodyTimeout: timeoutMs,
|
|
2600
2658
|
headersTimeout: timeoutMs
|
|
2601
2659
|
});
|
|
2602
|
-
|
|
2660
|
+
openAiClientState.cachedFetch = ((input, init) => {
|
|
2603
2661
|
return (0, import_undici2.fetch)(input, {
|
|
2604
2662
|
...init ?? {},
|
|
2605
2663
|
dispatcher
|
|
2606
2664
|
});
|
|
2607
2665
|
});
|
|
2608
|
-
return
|
|
2666
|
+
return openAiClientState.cachedFetch;
|
|
2609
2667
|
}
|
|
2610
2668
|
function resolveOpenAiBaseUrl() {
|
|
2611
2669
|
loadLocalEnv();
|
|
2612
2670
|
return process.env.OPENAI_BASE_URL?.trim() || "https://api.openai.com/v1";
|
|
2613
2671
|
}
|
|
2614
2672
|
function resolveOpenAiResponsesWebSocketMode() {
|
|
2615
|
-
if (openAiResponsesWebSocketMode) {
|
|
2616
|
-
return openAiResponsesWebSocketMode;
|
|
2673
|
+
if (openAiClientState.openAiResponsesWebSocketMode) {
|
|
2674
|
+
return openAiClientState.openAiResponsesWebSocketMode;
|
|
2617
2675
|
}
|
|
2618
2676
|
loadLocalEnv();
|
|
2619
|
-
openAiResponsesWebSocketMode = resolveResponsesWebSocketMode(
|
|
2677
|
+
openAiClientState.openAiResponsesWebSocketMode = resolveResponsesWebSocketMode(
|
|
2620
2678
|
process.env.OPENAI_RESPONSES_WEBSOCKET_MODE,
|
|
2621
2679
|
"auto"
|
|
2622
2680
|
);
|
|
2623
|
-
return openAiResponsesWebSocketMode;
|
|
2681
|
+
return openAiClientState.openAiResponsesWebSocketMode;
|
|
2624
2682
|
}
|
|
2625
2683
|
function wrapFallbackStream(stream) {
|
|
2626
2684
|
return {
|
|
@@ -2673,7 +2731,7 @@ function installResponsesWebSocketTransport(client, apiKey) {
|
|
|
2673
2731
|
responsesApi.stream = (request, options) => {
|
|
2674
2732
|
const mode = resolveOpenAiResponsesWebSocketMode();
|
|
2675
2733
|
const fallbackStreamFactory = () => wrapFallbackStream(originalStream(request, options));
|
|
2676
|
-
if (mode === "off" || openAiResponsesWebSocketDisabled) {
|
|
2734
|
+
if (mode === "off" || openAiClientState.openAiResponsesWebSocketDisabled) {
|
|
2677
2735
|
return fallbackStreamFactory();
|
|
2678
2736
|
}
|
|
2679
2737
|
const signal = options && typeof options === "object" ? options.signal ?? void 0 : void 0;
|
|
@@ -2692,15 +2750,15 @@ function installResponsesWebSocketTransport(client, apiKey) {
|
|
|
2692
2750
|
createFallbackStream: fallbackStreamFactory,
|
|
2693
2751
|
onWebSocketFallback: (error) => {
|
|
2694
2752
|
if (isResponsesWebSocketUnsupportedError(error)) {
|
|
2695
|
-
openAiResponsesWebSocketDisabled = true;
|
|
2753
|
+
openAiClientState.openAiResponsesWebSocketDisabled = true;
|
|
2696
2754
|
}
|
|
2697
2755
|
}
|
|
2698
2756
|
});
|
|
2699
2757
|
};
|
|
2700
2758
|
}
|
|
2701
2759
|
function getOpenAiApiKey() {
|
|
2702
|
-
if (
|
|
2703
|
-
return
|
|
2760
|
+
if (openAiClientState.cachedApiKey !== null) {
|
|
2761
|
+
return openAiClientState.cachedApiKey;
|
|
2704
2762
|
}
|
|
2705
2763
|
loadLocalEnv();
|
|
2706
2764
|
const raw = process.env.OPENAI_API_KEY;
|
|
@@ -2708,33 +2766,35 @@ function getOpenAiApiKey() {
|
|
|
2708
2766
|
if (!value) {
|
|
2709
2767
|
throw new Error("OPENAI_API_KEY must be provided to access OpenAI APIs.");
|
|
2710
2768
|
}
|
|
2711
|
-
|
|
2712
|
-
return
|
|
2769
|
+
openAiClientState.cachedApiKey = value;
|
|
2770
|
+
return openAiClientState.cachedApiKey;
|
|
2713
2771
|
}
|
|
2714
2772
|
function getOpenAiClient() {
|
|
2715
|
-
if (
|
|
2716
|
-
return
|
|
2773
|
+
if (openAiClientState.cachedClient) {
|
|
2774
|
+
return openAiClientState.cachedClient;
|
|
2717
2775
|
}
|
|
2718
2776
|
loadLocalEnv();
|
|
2719
2777
|
const apiKey = getOpenAiApiKey();
|
|
2720
2778
|
const timeoutMs = resolveOpenAiTimeoutMs();
|
|
2721
|
-
|
|
2779
|
+
openAiClientState.cachedClient = new import_openai2.default({
|
|
2722
2780
|
apiKey,
|
|
2723
2781
|
fetch: getOpenAiFetch(),
|
|
2724
2782
|
timeout: timeoutMs
|
|
2725
2783
|
});
|
|
2726
|
-
installResponsesWebSocketTransport(
|
|
2727
|
-
return
|
|
2784
|
+
installResponsesWebSocketTransport(openAiClientState.cachedClient, apiKey);
|
|
2785
|
+
return openAiClientState.cachedClient;
|
|
2728
2786
|
}
|
|
2729
2787
|
|
|
2730
2788
|
// src/openai/calls.ts
|
|
2731
2789
|
var DEFAULT_OPENAI_REASONING_EFFORT = "medium";
|
|
2732
2790
|
var DEFAULT_SCHEDULER_KEY3 = "__default__";
|
|
2733
|
-
var
|
|
2791
|
+
var openAiCallState = getRuntimeSingleton(/* @__PURE__ */ Symbol.for("@ljoukov/llm.openAiCallState"), () => ({
|
|
2792
|
+
schedulerByModel: /* @__PURE__ */ new Map()
|
|
2793
|
+
}));
|
|
2734
2794
|
function getSchedulerForModel3(modelId) {
|
|
2735
2795
|
const normalizedModelId = modelId?.trim();
|
|
2736
2796
|
const schedulerKey = normalizedModelId && normalizedModelId.length > 0 ? normalizedModelId : DEFAULT_SCHEDULER_KEY3;
|
|
2737
|
-
const existing =
|
|
2797
|
+
const existing = openAiCallState.schedulerByModel.get(schedulerKey);
|
|
2738
2798
|
if (existing) {
|
|
2739
2799
|
return existing;
|
|
2740
2800
|
}
|
|
@@ -2746,7 +2806,7 @@ function getSchedulerForModel3(modelId) {
|
|
|
2746
2806
|
minIntervalBetweenStartMs: 200,
|
|
2747
2807
|
startJitterMs: 200
|
|
2748
2808
|
});
|
|
2749
|
-
|
|
2809
|
+
openAiCallState.schedulerByModel.set(schedulerKey, created);
|
|
2750
2810
|
return created;
|
|
2751
2811
|
}
|
|
2752
2812
|
async function runOpenAiCall(fn, modelId, runOptions) {
|
|
@@ -3232,7 +3292,10 @@ var AgentLoggingSessionImpl = class {
|
|
|
3232
3292
|
}
|
|
3233
3293
|
}
|
|
3234
3294
|
};
|
|
3235
|
-
var loggingSessionStorage =
|
|
3295
|
+
var loggingSessionStorage = getRuntimeSingleton(
|
|
3296
|
+
/* @__PURE__ */ Symbol.for("@ljoukov/llm.agentLogging.sessionStorage"),
|
|
3297
|
+
() => new import_node_async_hooks.AsyncLocalStorage()
|
|
3298
|
+
);
|
|
3236
3299
|
function createAgentLoggingSession(config) {
|
|
3237
3300
|
return new AgentLoggingSessionImpl(config);
|
|
3238
3301
|
}
|
|
@@ -3247,7 +3310,10 @@ function getCurrentAgentLoggingSession() {
|
|
|
3247
3310
|
}
|
|
3248
3311
|
|
|
3249
3312
|
// src/llm.ts
|
|
3250
|
-
var toolCallContextStorage =
|
|
3313
|
+
var toolCallContextStorage = getRuntimeSingleton(
|
|
3314
|
+
/* @__PURE__ */ Symbol.for("@ljoukov/llm.toolCallContextStorage"),
|
|
3315
|
+
() => new import_node_async_hooks2.AsyncLocalStorage()
|
|
3316
|
+
);
|
|
3251
3317
|
function getCurrentToolCallContext() {
|
|
3252
3318
|
return toolCallContextStorage.getStore() ?? null;
|
|
3253
3319
|
}
|
|
@@ -5915,7 +5981,10 @@ var DEFAULT_TOOL_LOOP_MAX_STEPS = 8;
|
|
|
5915
5981
|
function resolveToolLoopContents(input) {
|
|
5916
5982
|
return resolveTextContents(input);
|
|
5917
5983
|
}
|
|
5918
|
-
var toolLoopSteeringInternals =
|
|
5984
|
+
var toolLoopSteeringInternals = getRuntimeSingleton(
|
|
5985
|
+
/* @__PURE__ */ Symbol.for("@ljoukov/llm.toolLoopSteeringInternals"),
|
|
5986
|
+
() => /* @__PURE__ */ new WeakMap()
|
|
5987
|
+
);
|
|
5919
5988
|
function createToolLoopSteeringChannel() {
|
|
5920
5989
|
const pending = [];
|
|
5921
5990
|
let closed = false;
|