@theokit/sdk 4.9.0 → 4.10.0
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/{cron-D_0p_gXd.d.ts → cron-BF_AI5NP.d.ts} +31 -0
- package/dist/{cron-26WH1n7o.d.cts → cron-DXEhagMa.d.cts} +31 -0
- package/dist/cron.cjs +184 -169
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +1 -1
- package/dist/cron.d.ts +1 -1
- package/dist/cron.js +184 -169
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +184 -169
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +184 -169
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +184 -169
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +184 -169
- package/dist/index.js.map +1 -1
- package/dist/types/provider-profile.d.ts +31 -0
- package/package.json +1 -1
package/dist/eval.js
CHANGED
|
@@ -12945,6 +12945,172 @@ function assistantMessage(message) {
|
|
|
12945
12945
|
return result;
|
|
12946
12946
|
}
|
|
12947
12947
|
|
|
12948
|
+
// src/internal/llm/pool-aware-client.ts
|
|
12949
|
+
init_errors();
|
|
12950
|
+
|
|
12951
|
+
// src/internal/resilience/circuit-breaker.ts
|
|
12952
|
+
var DEFAULT_MAX_TIMEOUTS = 3;
|
|
12953
|
+
var DEFAULT_COOLDOWN_MS2 = 6e4;
|
|
12954
|
+
var CircuitBreaker = class {
|
|
12955
|
+
constructor(opts = {}) {
|
|
12956
|
+
this.opts = opts;
|
|
12957
|
+
}
|
|
12958
|
+
opts;
|
|
12959
|
+
states = /* @__PURE__ */ new Map();
|
|
12960
|
+
/** @returns true when the breaker is open and the call should be skipped. */
|
|
12961
|
+
shouldSkip(key) {
|
|
12962
|
+
const state2 = this.states.get(key);
|
|
12963
|
+
if (state2 === void 0) return false;
|
|
12964
|
+
if (state2.cooldownUntilMs === 0) return false;
|
|
12965
|
+
if (this.now() < state2.cooldownUntilMs) return true;
|
|
12966
|
+
state2.cooldownUntilMs = 0;
|
|
12967
|
+
state2.consecutiveTimeouts = 0;
|
|
12968
|
+
return false;
|
|
12969
|
+
}
|
|
12970
|
+
recordSuccess(key) {
|
|
12971
|
+
const state2 = this.states.get(key);
|
|
12972
|
+
if (state2 === void 0) return;
|
|
12973
|
+
state2.consecutiveTimeouts = 0;
|
|
12974
|
+
state2.cooldownUntilMs = 0;
|
|
12975
|
+
}
|
|
12976
|
+
recordTimeout(key) {
|
|
12977
|
+
const state2 = this.states.get(key) ?? { consecutiveTimeouts: 0, cooldownUntilMs: 0 };
|
|
12978
|
+
state2.consecutiveTimeouts += 1;
|
|
12979
|
+
if (state2.consecutiveTimeouts >= (this.opts.maxTimeouts ?? DEFAULT_MAX_TIMEOUTS)) {
|
|
12980
|
+
state2.cooldownUntilMs = this.now() + (this.opts.cooldownMs ?? DEFAULT_COOLDOWN_MS2);
|
|
12981
|
+
}
|
|
12982
|
+
this.states.set(key, state2);
|
|
12983
|
+
}
|
|
12984
|
+
/** @internal — tests inspect counter state. */
|
|
12985
|
+
inspect(key) {
|
|
12986
|
+
return this.states.get(key) ?? { consecutiveTimeouts: 0, cooldownUntilMs: 0 };
|
|
12987
|
+
}
|
|
12988
|
+
now() {
|
|
12989
|
+
return this.opts.now?.() ?? Date.now();
|
|
12990
|
+
}
|
|
12991
|
+
};
|
|
12992
|
+
|
|
12993
|
+
// src/internal/llm/pool-aware-client.ts
|
|
12994
|
+
init_retry();
|
|
12995
|
+
var PoolAwareLlmClient = class {
|
|
12996
|
+
constructor(pool, buildClient2, waitForAvailableMs = 3e4, resilience = {}) {
|
|
12997
|
+
this.pool = pool;
|
|
12998
|
+
this.buildClient = buildClient2;
|
|
12999
|
+
this.waitForAvailableMs = waitForAvailableMs;
|
|
13000
|
+
this.name = `pool-aware:${pool.provider}`;
|
|
13001
|
+
this.breaker = resilience.breaker ?? new CircuitBreaker();
|
|
13002
|
+
this.backoffBaseMs = resilience.backoffBaseMs;
|
|
13003
|
+
this.rng = resilience.rng;
|
|
13004
|
+
this.onRateLimit = resilience.onRateLimit;
|
|
13005
|
+
}
|
|
13006
|
+
pool;
|
|
13007
|
+
buildClient;
|
|
13008
|
+
waitForAvailableMs;
|
|
13009
|
+
name;
|
|
13010
|
+
onRateLimit;
|
|
13011
|
+
/** M2 #60 — provider-level circuit breaker (consecutive-failure). */
|
|
13012
|
+
breaker;
|
|
13013
|
+
backoffBaseMs;
|
|
13014
|
+
rng;
|
|
13015
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: stream() must serialize pool-select → build client → first-event probe → classify → retry/rotate/propagate. Extracting helpers fragments the linear narrative; the comments above each branch keep it readable.
|
|
13016
|
+
async *stream(request, signal) {
|
|
13017
|
+
if (this.breaker.shouldSkip(this.pool.provider)) {
|
|
13018
|
+
throw new NetworkError(`${this.pool.provider} circuit open \u2014 failing fast`, {
|
|
13019
|
+
code: "circuit_open"
|
|
13020
|
+
});
|
|
13021
|
+
}
|
|
13022
|
+
let hasRetried429 = false;
|
|
13023
|
+
while (true) {
|
|
13024
|
+
if (signal.aborted) throw abortError2(signal);
|
|
13025
|
+
let entry = await this.pool.select();
|
|
13026
|
+
if (entry === null) {
|
|
13027
|
+
if (this.waitForAvailableMs > 0) {
|
|
13028
|
+
const available = await this.pool.waitForAvailable(signal, {
|
|
13029
|
+
maxWaitMs: this.waitForAvailableMs
|
|
13030
|
+
});
|
|
13031
|
+
if (available) {
|
|
13032
|
+
entry = await this.pool.select();
|
|
13033
|
+
}
|
|
13034
|
+
}
|
|
13035
|
+
if (entry === null) {
|
|
13036
|
+
this.breaker.recordTimeout(this.pool.provider);
|
|
13037
|
+
throw new CredentialPoolExhaustedError(
|
|
13038
|
+
`All ${this.pool.provider} credentials exhausted; next retry available at ${this.nextRetryHint() ?? "unknown"}`,
|
|
13039
|
+
{ provider: this.pool.provider, nextRetryAt: this.nextRetryHint() }
|
|
13040
|
+
);
|
|
13041
|
+
}
|
|
13042
|
+
}
|
|
13043
|
+
const realClient = this.buildClient(entry.accessToken);
|
|
13044
|
+
const attempt = await tryFirstEvent(realClient, request, signal);
|
|
13045
|
+
if (attempt.kind === "ok") {
|
|
13046
|
+
this.breaker.recordSuccess(this.pool.provider);
|
|
13047
|
+
return yield* relayStream(attempt.generator, attempt.firstResult);
|
|
13048
|
+
}
|
|
13049
|
+
const decision = classifyAndDecide(attempt.error, hasRetried429);
|
|
13050
|
+
if (decision === "retry") {
|
|
13051
|
+
const backoffMs = computeBackoffMs({
|
|
13052
|
+
attempt: 0,
|
|
13053
|
+
...this.backoffBaseMs !== void 0 ? { baseMs: this.backoffBaseMs } : {},
|
|
13054
|
+
...this.rng !== void 0 ? { rng: this.rng } : {}
|
|
13055
|
+
});
|
|
13056
|
+
this.onRateLimit?.({ attempt: 1, retryAfterMs: backoffMs });
|
|
13057
|
+
await sleepWithAbort(backoffMs, signal);
|
|
13058
|
+
hasRetried429 = true;
|
|
13059
|
+
continue;
|
|
13060
|
+
}
|
|
13061
|
+
if (decision === "rotate") {
|
|
13062
|
+
try {
|
|
13063
|
+
await this.pool.markExhaustedAndRotate({
|
|
13064
|
+
entryId: entry.id,
|
|
13065
|
+
statusCode: attempt.error.metadata?.statusCode ?? inferStatusCode(attempt.error),
|
|
13066
|
+
...parseRetryAfterMs(attempt.error) !== void 0 ? { resetAtMs: parseRetryAfterMs(attempt.error) } : {}
|
|
13067
|
+
});
|
|
13068
|
+
} catch (persistErr) {
|
|
13069
|
+
process.stderr.write(
|
|
13070
|
+
`[theokit-sdk] credential-pool: persist failed during rotate; continuing in-memory: ${persistErr instanceof Error ? persistErr.message : String(persistErr)}
|
|
13071
|
+
`
|
|
13072
|
+
);
|
|
13073
|
+
}
|
|
13074
|
+
hasRetried429 = false;
|
|
13075
|
+
continue;
|
|
13076
|
+
}
|
|
13077
|
+
this.breaker.recordTimeout(this.pool.provider);
|
|
13078
|
+
throw attempt.error;
|
|
13079
|
+
}
|
|
13080
|
+
}
|
|
13081
|
+
/**
|
|
13082
|
+
* Earliest epoch ms among entries' `lastErrorResetAt` — best estimate
|
|
13083
|
+
* for the caller's `CredentialPoolExhaustedError.nextRetryAt`.
|
|
13084
|
+
*/
|
|
13085
|
+
nextRetryHint() {
|
|
13086
|
+
const resets = this.pool.list().map((e) => e.lastErrorResetAt).filter((v) => v !== void 0);
|
|
13087
|
+
return resets.length === 0 ? void 0 : Math.min(...resets);
|
|
13088
|
+
}
|
|
13089
|
+
};
|
|
13090
|
+
function classifyAndDecide(error, hasRetried429) {
|
|
13091
|
+
if (error instanceof NetworkError) return "propagate";
|
|
13092
|
+
if (error instanceof AuthenticationError) return "rotate";
|
|
13093
|
+
const status = error.metadata?.statusCode ?? 429;
|
|
13094
|
+
if (status === 402) return "rotate";
|
|
13095
|
+
return hasRetried429 ? "rotate" : "retry";
|
|
13096
|
+
}
|
|
13097
|
+
function parseRetryAfterMs(error) {
|
|
13098
|
+
const seconds = error.metadata?.retryAfter;
|
|
13099
|
+
if (typeof seconds === "number" && seconds > 0) {
|
|
13100
|
+
return Date.now() + seconds * 1e3;
|
|
13101
|
+
}
|
|
13102
|
+
return void 0;
|
|
13103
|
+
}
|
|
13104
|
+
function inferStatusCode(error) {
|
|
13105
|
+
if (error instanceof AuthenticationError) return 401;
|
|
13106
|
+
if (error instanceof RateLimitError) return 429;
|
|
13107
|
+
return 0;
|
|
13108
|
+
}
|
|
13109
|
+
function abortError2(signal) {
|
|
13110
|
+
if (signal.reason instanceof Error) return signal.reason;
|
|
13111
|
+
return new Error("AbortError");
|
|
13112
|
+
}
|
|
13113
|
+
|
|
12948
13114
|
// src/internal/llm/responses.ts
|
|
12949
13115
|
function messageToInputItems(message) {
|
|
12950
13116
|
const items = [];
|
|
@@ -12993,7 +13159,9 @@ function buildResponsesBody(request) {
|
|
|
12993
13159
|
for (const message of request.messages) {
|
|
12994
13160
|
for (const item of messageToInputItems(message)) input.push(item);
|
|
12995
13161
|
}
|
|
12996
|
-
const
|
|
13162
|
+
const slash = request.model.lastIndexOf("/");
|
|
13163
|
+
const model = slash >= 0 ? request.model.slice(slash + 1) : request.model;
|
|
13164
|
+
const body = { model, input, stream: true, store: false };
|
|
12997
13165
|
const instructions = collapseSystemText(request.system);
|
|
12998
13166
|
if (instructions.length > 0) body.instructions = instructions;
|
|
12999
13167
|
if (request.maxTokens !== void 0) body.max_output_tokens = request.maxTokens;
|
|
@@ -13127,175 +13295,16 @@ var ResponsesApiClient = class {
|
|
|
13127
13295
|
}
|
|
13128
13296
|
if (toolCalls.length > 0 && stopReason === "end_turn") stopReason = "tool_use";
|
|
13129
13297
|
yield { type: "stop", reason: stopReason };
|
|
13130
|
-
return makeLlmFinish({
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
|
|
13138
|
-
var DEFAULT_MAX_TIMEOUTS = 3;
|
|
13139
|
-
var DEFAULT_COOLDOWN_MS2 = 6e4;
|
|
13140
|
-
var CircuitBreaker = class {
|
|
13141
|
-
constructor(opts = {}) {
|
|
13142
|
-
this.opts = opts;
|
|
13143
|
-
}
|
|
13144
|
-
opts;
|
|
13145
|
-
states = /* @__PURE__ */ new Map();
|
|
13146
|
-
/** @returns true when the breaker is open and the call should be skipped. */
|
|
13147
|
-
shouldSkip(key) {
|
|
13148
|
-
const state2 = this.states.get(key);
|
|
13149
|
-
if (state2 === void 0) return false;
|
|
13150
|
-
if (state2.cooldownUntilMs === 0) return false;
|
|
13151
|
-
if (this.now() < state2.cooldownUntilMs) return true;
|
|
13152
|
-
state2.cooldownUntilMs = 0;
|
|
13153
|
-
state2.consecutiveTimeouts = 0;
|
|
13154
|
-
return false;
|
|
13155
|
-
}
|
|
13156
|
-
recordSuccess(key) {
|
|
13157
|
-
const state2 = this.states.get(key);
|
|
13158
|
-
if (state2 === void 0) return;
|
|
13159
|
-
state2.consecutiveTimeouts = 0;
|
|
13160
|
-
state2.cooldownUntilMs = 0;
|
|
13161
|
-
}
|
|
13162
|
-
recordTimeout(key) {
|
|
13163
|
-
const state2 = this.states.get(key) ?? { consecutiveTimeouts: 0, cooldownUntilMs: 0 };
|
|
13164
|
-
state2.consecutiveTimeouts += 1;
|
|
13165
|
-
if (state2.consecutiveTimeouts >= (this.opts.maxTimeouts ?? DEFAULT_MAX_TIMEOUTS)) {
|
|
13166
|
-
state2.cooldownUntilMs = this.now() + (this.opts.cooldownMs ?? DEFAULT_COOLDOWN_MS2);
|
|
13167
|
-
}
|
|
13168
|
-
this.states.set(key, state2);
|
|
13169
|
-
}
|
|
13170
|
-
/** @internal — tests inspect counter state. */
|
|
13171
|
-
inspect(key) {
|
|
13172
|
-
return this.states.get(key) ?? { consecutiveTimeouts: 0, cooldownUntilMs: 0 };
|
|
13173
|
-
}
|
|
13174
|
-
now() {
|
|
13175
|
-
return this.opts.now?.() ?? Date.now();
|
|
13176
|
-
}
|
|
13177
|
-
};
|
|
13178
|
-
|
|
13179
|
-
// src/internal/llm/pool-aware-client.ts
|
|
13180
|
-
init_retry();
|
|
13181
|
-
var PoolAwareLlmClient = class {
|
|
13182
|
-
constructor(pool, buildClient2, waitForAvailableMs = 3e4, resilience = {}) {
|
|
13183
|
-
this.pool = pool;
|
|
13184
|
-
this.buildClient = buildClient2;
|
|
13185
|
-
this.waitForAvailableMs = waitForAvailableMs;
|
|
13186
|
-
this.name = `pool-aware:${pool.provider}`;
|
|
13187
|
-
this.breaker = resilience.breaker ?? new CircuitBreaker();
|
|
13188
|
-
this.backoffBaseMs = resilience.backoffBaseMs;
|
|
13189
|
-
this.rng = resilience.rng;
|
|
13190
|
-
this.onRateLimit = resilience.onRateLimit;
|
|
13191
|
-
}
|
|
13192
|
-
pool;
|
|
13193
|
-
buildClient;
|
|
13194
|
-
waitForAvailableMs;
|
|
13195
|
-
name;
|
|
13196
|
-
onRateLimit;
|
|
13197
|
-
/** M2 #60 — provider-level circuit breaker (consecutive-failure). */
|
|
13198
|
-
breaker;
|
|
13199
|
-
backoffBaseMs;
|
|
13200
|
-
rng;
|
|
13201
|
-
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: stream() must serialize pool-select → build client → first-event probe → classify → retry/rotate/propagate. Extracting helpers fragments the linear narrative; the comments above each branch keep it readable.
|
|
13202
|
-
async *stream(request, signal) {
|
|
13203
|
-
if (this.breaker.shouldSkip(this.pool.provider)) {
|
|
13204
|
-
throw new NetworkError(`${this.pool.provider} circuit open \u2014 failing fast`, {
|
|
13205
|
-
code: "circuit_open"
|
|
13206
|
-
});
|
|
13207
|
-
}
|
|
13208
|
-
let hasRetried429 = false;
|
|
13209
|
-
while (true) {
|
|
13210
|
-
if (signal.aborted) throw abortError2(signal);
|
|
13211
|
-
let entry = await this.pool.select();
|
|
13212
|
-
if (entry === null) {
|
|
13213
|
-
if (this.waitForAvailableMs > 0) {
|
|
13214
|
-
const available = await this.pool.waitForAvailable(signal, {
|
|
13215
|
-
maxWaitMs: this.waitForAvailableMs
|
|
13216
|
-
});
|
|
13217
|
-
if (available) {
|
|
13218
|
-
entry = await this.pool.select();
|
|
13219
|
-
}
|
|
13220
|
-
}
|
|
13221
|
-
if (entry === null) {
|
|
13222
|
-
this.breaker.recordTimeout(this.pool.provider);
|
|
13223
|
-
throw new CredentialPoolExhaustedError(
|
|
13224
|
-
`All ${this.pool.provider} credentials exhausted; next retry available at ${this.nextRetryHint() ?? "unknown"}`,
|
|
13225
|
-
{ provider: this.pool.provider, nextRetryAt: this.nextRetryHint() }
|
|
13226
|
-
);
|
|
13227
|
-
}
|
|
13228
|
-
}
|
|
13229
|
-
const realClient = this.buildClient(entry.accessToken);
|
|
13230
|
-
const attempt = await tryFirstEvent(realClient, request, signal);
|
|
13231
|
-
if (attempt.kind === "ok") {
|
|
13232
|
-
this.breaker.recordSuccess(this.pool.provider);
|
|
13233
|
-
return yield* relayStream(attempt.generator, attempt.firstResult);
|
|
13234
|
-
}
|
|
13235
|
-
const decision = classifyAndDecide(attempt.error, hasRetried429);
|
|
13236
|
-
if (decision === "retry") {
|
|
13237
|
-
const backoffMs = computeBackoffMs({
|
|
13238
|
-
attempt: 0,
|
|
13239
|
-
...this.backoffBaseMs !== void 0 ? { baseMs: this.backoffBaseMs } : {},
|
|
13240
|
-
...this.rng !== void 0 ? { rng: this.rng } : {}
|
|
13241
|
-
});
|
|
13242
|
-
this.onRateLimit?.({ attempt: 1, retryAfterMs: backoffMs });
|
|
13243
|
-
await sleepWithAbort(backoffMs, signal);
|
|
13244
|
-
hasRetried429 = true;
|
|
13245
|
-
continue;
|
|
13246
|
-
}
|
|
13247
|
-
if (decision === "rotate") {
|
|
13248
|
-
try {
|
|
13249
|
-
await this.pool.markExhaustedAndRotate({
|
|
13250
|
-
entryId: entry.id,
|
|
13251
|
-
statusCode: attempt.error.metadata?.statusCode ?? inferStatusCode(attempt.error),
|
|
13252
|
-
...parseRetryAfterMs(attempt.error) !== void 0 ? { resetAtMs: parseRetryAfterMs(attempt.error) } : {}
|
|
13253
|
-
});
|
|
13254
|
-
} catch (persistErr) {
|
|
13255
|
-
process.stderr.write(
|
|
13256
|
-
`[theokit-sdk] credential-pool: persist failed during rotate; continuing in-memory: ${persistErr instanceof Error ? persistErr.message : String(persistErr)}
|
|
13257
|
-
`
|
|
13258
|
-
);
|
|
13259
|
-
}
|
|
13260
|
-
hasRetried429 = false;
|
|
13261
|
-
continue;
|
|
13262
|
-
}
|
|
13263
|
-
this.breaker.recordTimeout(this.pool.provider);
|
|
13264
|
-
throw attempt.error;
|
|
13265
|
-
}
|
|
13266
|
-
}
|
|
13267
|
-
/**
|
|
13268
|
-
* Earliest epoch ms among entries' `lastErrorResetAt` — best estimate
|
|
13269
|
-
* for the caller's `CredentialPoolExhaustedError.nextRetryAt`.
|
|
13270
|
-
*/
|
|
13271
|
-
nextRetryHint() {
|
|
13272
|
-
const resets = this.pool.list().map((e) => e.lastErrorResetAt).filter((v) => v !== void 0);
|
|
13273
|
-
return resets.length === 0 ? void 0 : Math.min(...resets);
|
|
13298
|
+
return makeLlmFinish({
|
|
13299
|
+
stopReason,
|
|
13300
|
+
text,
|
|
13301
|
+
toolCalls,
|
|
13302
|
+
inputTokens,
|
|
13303
|
+
outputTokens,
|
|
13304
|
+
reasoningTokens
|
|
13305
|
+
});
|
|
13274
13306
|
}
|
|
13275
13307
|
};
|
|
13276
|
-
function classifyAndDecide(error, hasRetried429) {
|
|
13277
|
-
if (error instanceof NetworkError) return "propagate";
|
|
13278
|
-
if (error instanceof AuthenticationError) return "rotate";
|
|
13279
|
-
const status = error.metadata?.statusCode ?? 429;
|
|
13280
|
-
if (status === 402) return "rotate";
|
|
13281
|
-
return hasRetried429 ? "rotate" : "retry";
|
|
13282
|
-
}
|
|
13283
|
-
function parseRetryAfterMs(error) {
|
|
13284
|
-
const seconds = error.metadata?.retryAfter;
|
|
13285
|
-
if (typeof seconds === "number" && seconds > 0) {
|
|
13286
|
-
return Date.now() + seconds * 1e3;
|
|
13287
|
-
}
|
|
13288
|
-
return void 0;
|
|
13289
|
-
}
|
|
13290
|
-
function inferStatusCode(error) {
|
|
13291
|
-
if (error instanceof AuthenticationError) return 401;
|
|
13292
|
-
if (error instanceof RateLimitError) return 429;
|
|
13293
|
-
return 0;
|
|
13294
|
-
}
|
|
13295
|
-
function abortError2(signal) {
|
|
13296
|
-
if (signal.reason instanceof Error) return signal.reason;
|
|
13297
|
-
return new Error("AbortError");
|
|
13298
|
-
}
|
|
13299
13308
|
|
|
13300
13309
|
// src/internal/llm/vertex-anthropic.ts
|
|
13301
13310
|
init_errors();
|
|
@@ -13668,6 +13677,9 @@ function resolveApiKey2(envVars) {
|
|
|
13668
13677
|
return void 0;
|
|
13669
13678
|
}
|
|
13670
13679
|
function selectTransport(profile, apiKey) {
|
|
13680
|
+
const transformCtx = { apiKey };
|
|
13681
|
+
const transformFetch = profile.transform?.fetch?.(transformCtx);
|
|
13682
|
+
const transformHeaders = profile.transform?.headers?.(transformCtx);
|
|
13671
13683
|
if (profile.apiMode === "chat_completions") {
|
|
13672
13684
|
if (profile.name === "ollama") {
|
|
13673
13685
|
const ollamaBase = process.env.OLLAMA_HOST ?? profile.baseUrl;
|
|
@@ -13684,6 +13696,7 @@ function selectTransport(profile, apiKey) {
|
|
|
13684
13696
|
}
|
|
13685
13697
|
const envOverride = resolveBaseUrlEnvOverride(profile.name);
|
|
13686
13698
|
if (envOverride !== void 0) opts.baseUrl = envOverride;
|
|
13699
|
+
if (transformFetch !== void 0) opts.fetch = transformFetch;
|
|
13687
13700
|
return new OpenAIClient(opts);
|
|
13688
13701
|
}
|
|
13689
13702
|
if (profile.apiMode === "anthropic_messages") {
|
|
@@ -13700,10 +13713,12 @@ function selectTransport(profile, apiKey) {
|
|
|
13700
13713
|
return new BedrockAnthropicClient(realKey !== void 0 ? { apiKey: realKey } : {});
|
|
13701
13714
|
}
|
|
13702
13715
|
if (profile.apiMode === "responses_api") {
|
|
13716
|
+
const mergedHeaders = profile.extraHeaders !== void 0 || transformHeaders !== void 0 ? { ...profile.extraHeaders, ...transformHeaders } : void 0;
|
|
13703
13717
|
return new ResponsesApiClient({
|
|
13704
13718
|
apiKey,
|
|
13705
13719
|
...profile.baseUrl !== void 0 ? { baseUrl: profile.baseUrl } : {},
|
|
13706
|
-
...
|
|
13720
|
+
...mergedHeaders !== void 0 ? { extraHeaders: mergedHeaders } : {},
|
|
13721
|
+
...transformFetch !== void 0 ? { fetch: transformFetch } : {},
|
|
13707
13722
|
providerName: profile.name
|
|
13708
13723
|
});
|
|
13709
13724
|
}
|