@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/index.cjs
CHANGED
|
@@ -15550,6 +15550,172 @@ function assistantMessage(message) {
|
|
|
15550
15550
|
return result;
|
|
15551
15551
|
}
|
|
15552
15552
|
|
|
15553
|
+
// src/internal/llm/pool-aware-client.ts
|
|
15554
|
+
init_errors();
|
|
15555
|
+
|
|
15556
|
+
// src/internal/resilience/circuit-breaker.ts
|
|
15557
|
+
var DEFAULT_MAX_TIMEOUTS = 3;
|
|
15558
|
+
var DEFAULT_COOLDOWN_MS2 = 6e4;
|
|
15559
|
+
var CircuitBreaker = class {
|
|
15560
|
+
constructor(opts = {}) {
|
|
15561
|
+
this.opts = opts;
|
|
15562
|
+
}
|
|
15563
|
+
opts;
|
|
15564
|
+
states = /* @__PURE__ */ new Map();
|
|
15565
|
+
/** @returns true when the breaker is open and the call should be skipped. */
|
|
15566
|
+
shouldSkip(key2) {
|
|
15567
|
+
const state4 = this.states.get(key2);
|
|
15568
|
+
if (state4 === void 0) return false;
|
|
15569
|
+
if (state4.cooldownUntilMs === 0) return false;
|
|
15570
|
+
if (this.now() < state4.cooldownUntilMs) return true;
|
|
15571
|
+
state4.cooldownUntilMs = 0;
|
|
15572
|
+
state4.consecutiveTimeouts = 0;
|
|
15573
|
+
return false;
|
|
15574
|
+
}
|
|
15575
|
+
recordSuccess(key2) {
|
|
15576
|
+
const state4 = this.states.get(key2);
|
|
15577
|
+
if (state4 === void 0) return;
|
|
15578
|
+
state4.consecutiveTimeouts = 0;
|
|
15579
|
+
state4.cooldownUntilMs = 0;
|
|
15580
|
+
}
|
|
15581
|
+
recordTimeout(key2) {
|
|
15582
|
+
const state4 = this.states.get(key2) ?? { consecutiveTimeouts: 0, cooldownUntilMs: 0 };
|
|
15583
|
+
state4.consecutiveTimeouts += 1;
|
|
15584
|
+
if (state4.consecutiveTimeouts >= (this.opts.maxTimeouts ?? DEFAULT_MAX_TIMEOUTS)) {
|
|
15585
|
+
state4.cooldownUntilMs = this.now() + (this.opts.cooldownMs ?? DEFAULT_COOLDOWN_MS2);
|
|
15586
|
+
}
|
|
15587
|
+
this.states.set(key2, state4);
|
|
15588
|
+
}
|
|
15589
|
+
/** @internal — tests inspect counter state. */
|
|
15590
|
+
inspect(key2) {
|
|
15591
|
+
return this.states.get(key2) ?? { consecutiveTimeouts: 0, cooldownUntilMs: 0 };
|
|
15592
|
+
}
|
|
15593
|
+
now() {
|
|
15594
|
+
return this.opts.now?.() ?? Date.now();
|
|
15595
|
+
}
|
|
15596
|
+
};
|
|
15597
|
+
|
|
15598
|
+
// src/internal/llm/pool-aware-client.ts
|
|
15599
|
+
init_retry();
|
|
15600
|
+
var PoolAwareLlmClient = class {
|
|
15601
|
+
constructor(pool, buildClient2, waitForAvailableMs = 3e4, resilience = {}) {
|
|
15602
|
+
this.pool = pool;
|
|
15603
|
+
this.buildClient = buildClient2;
|
|
15604
|
+
this.waitForAvailableMs = waitForAvailableMs;
|
|
15605
|
+
this.name = `pool-aware:${pool.provider}`;
|
|
15606
|
+
this.breaker = resilience.breaker ?? new CircuitBreaker();
|
|
15607
|
+
this.backoffBaseMs = resilience.backoffBaseMs;
|
|
15608
|
+
this.rng = resilience.rng;
|
|
15609
|
+
this.onRateLimit = resilience.onRateLimit;
|
|
15610
|
+
}
|
|
15611
|
+
pool;
|
|
15612
|
+
buildClient;
|
|
15613
|
+
waitForAvailableMs;
|
|
15614
|
+
name;
|
|
15615
|
+
onRateLimit;
|
|
15616
|
+
/** M2 #60 — provider-level circuit breaker (consecutive-failure). */
|
|
15617
|
+
breaker;
|
|
15618
|
+
backoffBaseMs;
|
|
15619
|
+
rng;
|
|
15620
|
+
// 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.
|
|
15621
|
+
async *stream(request, signal) {
|
|
15622
|
+
if (this.breaker.shouldSkip(this.pool.provider)) {
|
|
15623
|
+
throw new exports.NetworkError(`${this.pool.provider} circuit open \u2014 failing fast`, {
|
|
15624
|
+
code: "circuit_open"
|
|
15625
|
+
});
|
|
15626
|
+
}
|
|
15627
|
+
let hasRetried429 = false;
|
|
15628
|
+
while (true) {
|
|
15629
|
+
if (signal.aborted) throw abortError2(signal);
|
|
15630
|
+
let entry = await this.pool.select();
|
|
15631
|
+
if (entry === null) {
|
|
15632
|
+
if (this.waitForAvailableMs > 0) {
|
|
15633
|
+
const available = await this.pool.waitForAvailable(signal, {
|
|
15634
|
+
maxWaitMs: this.waitForAvailableMs
|
|
15635
|
+
});
|
|
15636
|
+
if (available) {
|
|
15637
|
+
entry = await this.pool.select();
|
|
15638
|
+
}
|
|
15639
|
+
}
|
|
15640
|
+
if (entry === null) {
|
|
15641
|
+
this.breaker.recordTimeout(this.pool.provider);
|
|
15642
|
+
throw new CredentialPoolExhaustedError(
|
|
15643
|
+
`All ${this.pool.provider} credentials exhausted; next retry available at ${this.nextRetryHint() ?? "unknown"}`,
|
|
15644
|
+
{ provider: this.pool.provider, nextRetryAt: this.nextRetryHint() }
|
|
15645
|
+
);
|
|
15646
|
+
}
|
|
15647
|
+
}
|
|
15648
|
+
const realClient = this.buildClient(entry.accessToken);
|
|
15649
|
+
const attempt = await tryFirstEvent(realClient, request, signal);
|
|
15650
|
+
if (attempt.kind === "ok") {
|
|
15651
|
+
this.breaker.recordSuccess(this.pool.provider);
|
|
15652
|
+
return yield* relayStream(attempt.generator, attempt.firstResult);
|
|
15653
|
+
}
|
|
15654
|
+
const decision = classifyAndDecide(attempt.error, hasRetried429);
|
|
15655
|
+
if (decision === "retry") {
|
|
15656
|
+
const backoffMs = computeBackoffMs({
|
|
15657
|
+
attempt: 0,
|
|
15658
|
+
...this.backoffBaseMs !== void 0 ? { baseMs: this.backoffBaseMs } : {},
|
|
15659
|
+
...this.rng !== void 0 ? { rng: this.rng } : {}
|
|
15660
|
+
});
|
|
15661
|
+
this.onRateLimit?.({ attempt: 1, retryAfterMs: backoffMs });
|
|
15662
|
+
await sleepWithAbort(backoffMs, signal);
|
|
15663
|
+
hasRetried429 = true;
|
|
15664
|
+
continue;
|
|
15665
|
+
}
|
|
15666
|
+
if (decision === "rotate") {
|
|
15667
|
+
try {
|
|
15668
|
+
await this.pool.markExhaustedAndRotate({
|
|
15669
|
+
entryId: entry.id,
|
|
15670
|
+
statusCode: attempt.error.metadata?.statusCode ?? inferStatusCode(attempt.error),
|
|
15671
|
+
...parseRetryAfterMs(attempt.error) !== void 0 ? { resetAtMs: parseRetryAfterMs(attempt.error) } : {}
|
|
15672
|
+
});
|
|
15673
|
+
} catch (persistErr) {
|
|
15674
|
+
process.stderr.write(
|
|
15675
|
+
`[theokit-sdk] credential-pool: persist failed during rotate; continuing in-memory: ${persistErr instanceof Error ? persistErr.message : String(persistErr)}
|
|
15676
|
+
`
|
|
15677
|
+
);
|
|
15678
|
+
}
|
|
15679
|
+
hasRetried429 = false;
|
|
15680
|
+
continue;
|
|
15681
|
+
}
|
|
15682
|
+
this.breaker.recordTimeout(this.pool.provider);
|
|
15683
|
+
throw attempt.error;
|
|
15684
|
+
}
|
|
15685
|
+
}
|
|
15686
|
+
/**
|
|
15687
|
+
* Earliest epoch ms among entries' `lastErrorResetAt` — best estimate
|
|
15688
|
+
* for the caller's `CredentialPoolExhaustedError.nextRetryAt`.
|
|
15689
|
+
*/
|
|
15690
|
+
nextRetryHint() {
|
|
15691
|
+
const resets = this.pool.list().map((e) => e.lastErrorResetAt).filter((v) => v !== void 0);
|
|
15692
|
+
return resets.length === 0 ? void 0 : Math.min(...resets);
|
|
15693
|
+
}
|
|
15694
|
+
};
|
|
15695
|
+
function classifyAndDecide(error, hasRetried429) {
|
|
15696
|
+
if (error instanceof exports.NetworkError) return "propagate";
|
|
15697
|
+
if (error instanceof exports.AuthenticationError) return "rotate";
|
|
15698
|
+
const status = error.metadata?.statusCode ?? 429;
|
|
15699
|
+
if (status === 402) return "rotate";
|
|
15700
|
+
return hasRetried429 ? "rotate" : "retry";
|
|
15701
|
+
}
|
|
15702
|
+
function parseRetryAfterMs(error) {
|
|
15703
|
+
const seconds = error.metadata?.retryAfter;
|
|
15704
|
+
if (typeof seconds === "number" && seconds > 0) {
|
|
15705
|
+
return Date.now() + seconds * 1e3;
|
|
15706
|
+
}
|
|
15707
|
+
return void 0;
|
|
15708
|
+
}
|
|
15709
|
+
function inferStatusCode(error) {
|
|
15710
|
+
if (error instanceof exports.AuthenticationError) return 401;
|
|
15711
|
+
if (error instanceof exports.RateLimitError) return 429;
|
|
15712
|
+
return 0;
|
|
15713
|
+
}
|
|
15714
|
+
function abortError2(signal) {
|
|
15715
|
+
if (signal.reason instanceof Error) return signal.reason;
|
|
15716
|
+
return new Error("AbortError");
|
|
15717
|
+
}
|
|
15718
|
+
|
|
15553
15719
|
// src/internal/llm/responses.ts
|
|
15554
15720
|
function messageToInputItems(message) {
|
|
15555
15721
|
const items = [];
|
|
@@ -15598,7 +15764,9 @@ function buildResponsesBody(request) {
|
|
|
15598
15764
|
for (const message of request.messages) {
|
|
15599
15765
|
for (const item of messageToInputItems(message)) input.push(item);
|
|
15600
15766
|
}
|
|
15601
|
-
const
|
|
15767
|
+
const slash = request.model.lastIndexOf("/");
|
|
15768
|
+
const model = slash >= 0 ? request.model.slice(slash + 1) : request.model;
|
|
15769
|
+
const body = { model, input, stream: true, store: false };
|
|
15602
15770
|
const instructions = collapseSystemText(request.system);
|
|
15603
15771
|
if (instructions.length > 0) body.instructions = instructions;
|
|
15604
15772
|
if (request.maxTokens !== void 0) body.max_output_tokens = request.maxTokens;
|
|
@@ -15732,175 +15900,16 @@ var ResponsesApiClient = class {
|
|
|
15732
15900
|
}
|
|
15733
15901
|
if (toolCalls.length > 0 && stopReason === "end_turn") stopReason = "tool_use";
|
|
15734
15902
|
yield { type: "stop", reason: stopReason };
|
|
15735
|
-
return makeLlmFinish({
|
|
15736
|
-
|
|
15737
|
-
|
|
15738
|
-
|
|
15739
|
-
|
|
15740
|
-
|
|
15741
|
-
|
|
15742
|
-
|
|
15743
|
-
var DEFAULT_MAX_TIMEOUTS = 3;
|
|
15744
|
-
var DEFAULT_COOLDOWN_MS2 = 6e4;
|
|
15745
|
-
var CircuitBreaker = class {
|
|
15746
|
-
constructor(opts = {}) {
|
|
15747
|
-
this.opts = opts;
|
|
15748
|
-
}
|
|
15749
|
-
opts;
|
|
15750
|
-
states = /* @__PURE__ */ new Map();
|
|
15751
|
-
/** @returns true when the breaker is open and the call should be skipped. */
|
|
15752
|
-
shouldSkip(key2) {
|
|
15753
|
-
const state4 = this.states.get(key2);
|
|
15754
|
-
if (state4 === void 0) return false;
|
|
15755
|
-
if (state4.cooldownUntilMs === 0) return false;
|
|
15756
|
-
if (this.now() < state4.cooldownUntilMs) return true;
|
|
15757
|
-
state4.cooldownUntilMs = 0;
|
|
15758
|
-
state4.consecutiveTimeouts = 0;
|
|
15759
|
-
return false;
|
|
15760
|
-
}
|
|
15761
|
-
recordSuccess(key2) {
|
|
15762
|
-
const state4 = this.states.get(key2);
|
|
15763
|
-
if (state4 === void 0) return;
|
|
15764
|
-
state4.consecutiveTimeouts = 0;
|
|
15765
|
-
state4.cooldownUntilMs = 0;
|
|
15766
|
-
}
|
|
15767
|
-
recordTimeout(key2) {
|
|
15768
|
-
const state4 = this.states.get(key2) ?? { consecutiveTimeouts: 0, cooldownUntilMs: 0 };
|
|
15769
|
-
state4.consecutiveTimeouts += 1;
|
|
15770
|
-
if (state4.consecutiveTimeouts >= (this.opts.maxTimeouts ?? DEFAULT_MAX_TIMEOUTS)) {
|
|
15771
|
-
state4.cooldownUntilMs = this.now() + (this.opts.cooldownMs ?? DEFAULT_COOLDOWN_MS2);
|
|
15772
|
-
}
|
|
15773
|
-
this.states.set(key2, state4);
|
|
15774
|
-
}
|
|
15775
|
-
/** @internal — tests inspect counter state. */
|
|
15776
|
-
inspect(key2) {
|
|
15777
|
-
return this.states.get(key2) ?? { consecutiveTimeouts: 0, cooldownUntilMs: 0 };
|
|
15778
|
-
}
|
|
15779
|
-
now() {
|
|
15780
|
-
return this.opts.now?.() ?? Date.now();
|
|
15781
|
-
}
|
|
15782
|
-
};
|
|
15783
|
-
|
|
15784
|
-
// src/internal/llm/pool-aware-client.ts
|
|
15785
|
-
init_retry();
|
|
15786
|
-
var PoolAwareLlmClient = class {
|
|
15787
|
-
constructor(pool, buildClient2, waitForAvailableMs = 3e4, resilience = {}) {
|
|
15788
|
-
this.pool = pool;
|
|
15789
|
-
this.buildClient = buildClient2;
|
|
15790
|
-
this.waitForAvailableMs = waitForAvailableMs;
|
|
15791
|
-
this.name = `pool-aware:${pool.provider}`;
|
|
15792
|
-
this.breaker = resilience.breaker ?? new CircuitBreaker();
|
|
15793
|
-
this.backoffBaseMs = resilience.backoffBaseMs;
|
|
15794
|
-
this.rng = resilience.rng;
|
|
15795
|
-
this.onRateLimit = resilience.onRateLimit;
|
|
15796
|
-
}
|
|
15797
|
-
pool;
|
|
15798
|
-
buildClient;
|
|
15799
|
-
waitForAvailableMs;
|
|
15800
|
-
name;
|
|
15801
|
-
onRateLimit;
|
|
15802
|
-
/** M2 #60 — provider-level circuit breaker (consecutive-failure). */
|
|
15803
|
-
breaker;
|
|
15804
|
-
backoffBaseMs;
|
|
15805
|
-
rng;
|
|
15806
|
-
// 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.
|
|
15807
|
-
async *stream(request, signal) {
|
|
15808
|
-
if (this.breaker.shouldSkip(this.pool.provider)) {
|
|
15809
|
-
throw new exports.NetworkError(`${this.pool.provider} circuit open \u2014 failing fast`, {
|
|
15810
|
-
code: "circuit_open"
|
|
15811
|
-
});
|
|
15812
|
-
}
|
|
15813
|
-
let hasRetried429 = false;
|
|
15814
|
-
while (true) {
|
|
15815
|
-
if (signal.aborted) throw abortError2(signal);
|
|
15816
|
-
let entry = await this.pool.select();
|
|
15817
|
-
if (entry === null) {
|
|
15818
|
-
if (this.waitForAvailableMs > 0) {
|
|
15819
|
-
const available = await this.pool.waitForAvailable(signal, {
|
|
15820
|
-
maxWaitMs: this.waitForAvailableMs
|
|
15821
|
-
});
|
|
15822
|
-
if (available) {
|
|
15823
|
-
entry = await this.pool.select();
|
|
15824
|
-
}
|
|
15825
|
-
}
|
|
15826
|
-
if (entry === null) {
|
|
15827
|
-
this.breaker.recordTimeout(this.pool.provider);
|
|
15828
|
-
throw new CredentialPoolExhaustedError(
|
|
15829
|
-
`All ${this.pool.provider} credentials exhausted; next retry available at ${this.nextRetryHint() ?? "unknown"}`,
|
|
15830
|
-
{ provider: this.pool.provider, nextRetryAt: this.nextRetryHint() }
|
|
15831
|
-
);
|
|
15832
|
-
}
|
|
15833
|
-
}
|
|
15834
|
-
const realClient = this.buildClient(entry.accessToken);
|
|
15835
|
-
const attempt = await tryFirstEvent(realClient, request, signal);
|
|
15836
|
-
if (attempt.kind === "ok") {
|
|
15837
|
-
this.breaker.recordSuccess(this.pool.provider);
|
|
15838
|
-
return yield* relayStream(attempt.generator, attempt.firstResult);
|
|
15839
|
-
}
|
|
15840
|
-
const decision = classifyAndDecide(attempt.error, hasRetried429);
|
|
15841
|
-
if (decision === "retry") {
|
|
15842
|
-
const backoffMs = computeBackoffMs({
|
|
15843
|
-
attempt: 0,
|
|
15844
|
-
...this.backoffBaseMs !== void 0 ? { baseMs: this.backoffBaseMs } : {},
|
|
15845
|
-
...this.rng !== void 0 ? { rng: this.rng } : {}
|
|
15846
|
-
});
|
|
15847
|
-
this.onRateLimit?.({ attempt: 1, retryAfterMs: backoffMs });
|
|
15848
|
-
await sleepWithAbort(backoffMs, signal);
|
|
15849
|
-
hasRetried429 = true;
|
|
15850
|
-
continue;
|
|
15851
|
-
}
|
|
15852
|
-
if (decision === "rotate") {
|
|
15853
|
-
try {
|
|
15854
|
-
await this.pool.markExhaustedAndRotate({
|
|
15855
|
-
entryId: entry.id,
|
|
15856
|
-
statusCode: attempt.error.metadata?.statusCode ?? inferStatusCode(attempt.error),
|
|
15857
|
-
...parseRetryAfterMs(attempt.error) !== void 0 ? { resetAtMs: parseRetryAfterMs(attempt.error) } : {}
|
|
15858
|
-
});
|
|
15859
|
-
} catch (persistErr) {
|
|
15860
|
-
process.stderr.write(
|
|
15861
|
-
`[theokit-sdk] credential-pool: persist failed during rotate; continuing in-memory: ${persistErr instanceof Error ? persistErr.message : String(persistErr)}
|
|
15862
|
-
`
|
|
15863
|
-
);
|
|
15864
|
-
}
|
|
15865
|
-
hasRetried429 = false;
|
|
15866
|
-
continue;
|
|
15867
|
-
}
|
|
15868
|
-
this.breaker.recordTimeout(this.pool.provider);
|
|
15869
|
-
throw attempt.error;
|
|
15870
|
-
}
|
|
15871
|
-
}
|
|
15872
|
-
/**
|
|
15873
|
-
* Earliest epoch ms among entries' `lastErrorResetAt` — best estimate
|
|
15874
|
-
* for the caller's `CredentialPoolExhaustedError.nextRetryAt`.
|
|
15875
|
-
*/
|
|
15876
|
-
nextRetryHint() {
|
|
15877
|
-
const resets = this.pool.list().map((e) => e.lastErrorResetAt).filter((v) => v !== void 0);
|
|
15878
|
-
return resets.length === 0 ? void 0 : Math.min(...resets);
|
|
15903
|
+
return makeLlmFinish({
|
|
15904
|
+
stopReason,
|
|
15905
|
+
text,
|
|
15906
|
+
toolCalls,
|
|
15907
|
+
inputTokens,
|
|
15908
|
+
outputTokens,
|
|
15909
|
+
reasoningTokens
|
|
15910
|
+
});
|
|
15879
15911
|
}
|
|
15880
15912
|
};
|
|
15881
|
-
function classifyAndDecide(error, hasRetried429) {
|
|
15882
|
-
if (error instanceof exports.NetworkError) return "propagate";
|
|
15883
|
-
if (error instanceof exports.AuthenticationError) return "rotate";
|
|
15884
|
-
const status = error.metadata?.statusCode ?? 429;
|
|
15885
|
-
if (status === 402) return "rotate";
|
|
15886
|
-
return hasRetried429 ? "rotate" : "retry";
|
|
15887
|
-
}
|
|
15888
|
-
function parseRetryAfterMs(error) {
|
|
15889
|
-
const seconds = error.metadata?.retryAfter;
|
|
15890
|
-
if (typeof seconds === "number" && seconds > 0) {
|
|
15891
|
-
return Date.now() + seconds * 1e3;
|
|
15892
|
-
}
|
|
15893
|
-
return void 0;
|
|
15894
|
-
}
|
|
15895
|
-
function inferStatusCode(error) {
|
|
15896
|
-
if (error instanceof exports.AuthenticationError) return 401;
|
|
15897
|
-
if (error instanceof exports.RateLimitError) return 429;
|
|
15898
|
-
return 0;
|
|
15899
|
-
}
|
|
15900
|
-
function abortError2(signal) {
|
|
15901
|
-
if (signal.reason instanceof Error) return signal.reason;
|
|
15902
|
-
return new Error("AbortError");
|
|
15903
|
-
}
|
|
15904
15913
|
|
|
15905
15914
|
// src/internal/llm/vertex-anthropic.ts
|
|
15906
15915
|
init_errors();
|
|
@@ -16273,6 +16282,9 @@ function resolveApiKey2(envVars) {
|
|
|
16273
16282
|
return void 0;
|
|
16274
16283
|
}
|
|
16275
16284
|
function selectTransport(profile, apiKey) {
|
|
16285
|
+
const transformCtx = { apiKey };
|
|
16286
|
+
const transformFetch = profile.transform?.fetch?.(transformCtx);
|
|
16287
|
+
const transformHeaders = profile.transform?.headers?.(transformCtx);
|
|
16276
16288
|
if (profile.apiMode === "chat_completions") {
|
|
16277
16289
|
if (profile.name === "ollama") {
|
|
16278
16290
|
const ollamaBase = process.env.OLLAMA_HOST ?? profile.baseUrl;
|
|
@@ -16289,6 +16301,7 @@ function selectTransport(profile, apiKey) {
|
|
|
16289
16301
|
}
|
|
16290
16302
|
const envOverride = resolveBaseUrlEnvOverride(profile.name);
|
|
16291
16303
|
if (envOverride !== void 0) opts.baseUrl = envOverride;
|
|
16304
|
+
if (transformFetch !== void 0) opts.fetch = transformFetch;
|
|
16292
16305
|
return new OpenAIClient(opts);
|
|
16293
16306
|
}
|
|
16294
16307
|
if (profile.apiMode === "anthropic_messages") {
|
|
@@ -16305,10 +16318,12 @@ function selectTransport(profile, apiKey) {
|
|
|
16305
16318
|
return new BedrockAnthropicClient(realKey !== void 0 ? { apiKey: realKey } : {});
|
|
16306
16319
|
}
|
|
16307
16320
|
if (profile.apiMode === "responses_api") {
|
|
16321
|
+
const mergedHeaders = profile.extraHeaders !== void 0 || transformHeaders !== void 0 ? { ...profile.extraHeaders, ...transformHeaders } : void 0;
|
|
16308
16322
|
return new ResponsesApiClient({
|
|
16309
16323
|
apiKey,
|
|
16310
16324
|
...profile.baseUrl !== void 0 ? { baseUrl: profile.baseUrl } : {},
|
|
16311
|
-
...
|
|
16325
|
+
...mergedHeaders !== void 0 ? { extraHeaders: mergedHeaders } : {},
|
|
16326
|
+
...transformFetch !== void 0 ? { fetch: transformFetch } : {},
|
|
16312
16327
|
providerName: profile.name
|
|
16313
16328
|
});
|
|
16314
16329
|
}
|