@providerkit/core 0.1.0 → 0.2.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/README.md +33 -157
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +8 -0
- package/dist/context.js.map +1 -1
- package/dist/errors.d.ts +36 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +72 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/key-pool.d.ts +60 -0
- package/dist/key-pool.d.ts.map +1 -0
- package/dist/key-pool.js +235 -0
- package/dist/key-pool.js.map +1 -0
- package/dist/providers/anthropic.d.ts +9 -0
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +12 -13
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/gemini.d.ts +40 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +303 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +9 -0
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/responses.d.ts +38 -0
- package/dist/providers/responses.d.ts.map +1 -0
- package/dist/providers/responses.js +341 -0
- package/dist/providers/responses.js.map +1 -0
- package/dist/rate-limit.d.ts +29 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +194 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/transport.d.ts +18 -5
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +61 -35
- package/dist/transport.js.map +1 -1
- package/package.json +2 -2
- package/src/context.ts +7 -0
- package/src/errors.ts +79 -1
- package/src/index.ts +4 -0
- package/src/key-pool.ts +272 -0
- package/src/providers/anthropic.ts +21 -18
- package/src/providers/gemini.ts +386 -0
- package/src/providers/openai.ts +12 -0
- package/src/providers/responses.ts +455 -0
- package/src/rate-limit.ts +217 -0
- package/src/transport.ts +61 -35
package/dist/key-pool.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// A rotating pool of API keys for one provider.
|
|
2
|
+
//
|
|
3
|
+
// Rate limits are scoped per project or per account, so several keys multiply
|
|
4
|
+
// throughput. Free-tier keys go first, round-robin, and the paid key last —
|
|
5
|
+
// free quota burns before money. A key that answers 429 is benched for the
|
|
6
|
+
// delay the provider named (Retry-After, or Gemini's RetryInfo; else a minute,
|
|
7
|
+
// and an hour when the body says the balance or the daily window is gone), a
|
|
8
|
+
// denied key for 12 h (durable, but key-specific — one dead key must not take
|
|
9
|
+
// the pool down with it), an overload only briefly, because a sibling project's
|
|
10
|
+
// key routes to a different backend.
|
|
11
|
+
//
|
|
12
|
+
// With ONE key there is nothing to rotate to, so NOTHING is evicted and the
|
|
13
|
+
// error propagates untouched: a transient 503 must not switch a single-key
|
|
14
|
+
// deployment off for a minute, where the caller's own retry is the whole
|
|
15
|
+
// recovery there is.
|
|
16
|
+
import { isTransient, ProviderError } from "./errors.js";
|
|
17
|
+
/** A per-minute throttle: the window it names is the next one. */
|
|
18
|
+
const RATE_COOLDOWN_MS = 60_000;
|
|
19
|
+
/** A balance or a daily window — minutes will not bring it back. */
|
|
20
|
+
const QUOTA_COOLDOWN_MS = 60 * 60_000;
|
|
21
|
+
const AUTH_COOLDOWN_MS = 12 * 60 * 60_000;
|
|
22
|
+
/** The vendor's bad time, not the key's — benched only long enough for the
|
|
23
|
+
* next call to land somewhere else. */
|
|
24
|
+
const TRANSIENT_COOLDOWN_MS = 60_000;
|
|
25
|
+
const MIN_EVICTION_MS = 1_000;
|
|
26
|
+
const MAX_EVICTION_MS = 12 * 60 * 60_000;
|
|
27
|
+
/** No key can serve right now. `retryAtMs` = when the soonest one is back. */
|
|
28
|
+
export class NoAvailableKeyError extends Error {
|
|
29
|
+
retryAtMs;
|
|
30
|
+
constructor(label, retryAtMs) {
|
|
31
|
+
super(`No ${label} API key available (all rate-limited or denied)`);
|
|
32
|
+
this.name = "NoAvailableKeyError";
|
|
33
|
+
this.retryAtMs = retryAtMs;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class KeyPool {
|
|
37
|
+
label;
|
|
38
|
+
free;
|
|
39
|
+
paid;
|
|
40
|
+
onEvict;
|
|
41
|
+
now;
|
|
42
|
+
cursor = 0;
|
|
43
|
+
constructor(label, opts) {
|
|
44
|
+
this.label = label;
|
|
45
|
+
// A blank slot in the caller's config is not a key — an absent env var
|
|
46
|
+
// reads as "" and would otherwise be dialled once per rotation.
|
|
47
|
+
this.free = opts.keys
|
|
48
|
+
.filter(Boolean)
|
|
49
|
+
.map((apiKey) => ({ apiKey, tier: "free", evictedUntil: 0 }));
|
|
50
|
+
this.paid = opts.paidKey ? { apiKey: opts.paidKey, tier: "paid", evictedUntil: 0 } : null;
|
|
51
|
+
this.onEvict = opts.onEvict;
|
|
52
|
+
this.now = opts.now ?? Date.now;
|
|
53
|
+
if (this.free.length === 0 && !this.paid) {
|
|
54
|
+
throw new Error(`KeyPool(${this.label}) needs at least one key`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
get size() {
|
|
58
|
+
return this.free.length + (this.paid ? 1 : 0);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Run `fn` with the next available key, rotating on key-specific and
|
|
62
|
+
* transient failures. Everything else (a bad request, a content block) throws
|
|
63
|
+
* straight through — it would fail identically on every key, and spending the
|
|
64
|
+
* pool on it only turns one bad request into an outage.
|
|
65
|
+
*/
|
|
66
|
+
async with(fn) {
|
|
67
|
+
const candidates = this.candidates(this.now());
|
|
68
|
+
if (candidates.length === 0)
|
|
69
|
+
throw new NoAvailableKeyError(this.label, this.nextAvailableAt());
|
|
70
|
+
let last;
|
|
71
|
+
for (const key of candidates) {
|
|
72
|
+
try {
|
|
73
|
+
return await fn(key.apiKey, key.tier);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
last = err;
|
|
77
|
+
// The single-key rule: with nothing to rotate to, benching the only key
|
|
78
|
+
// answers NoAvailableKeyError to every call for the next minute — for a
|
|
79
|
+
// failure the caller's own retry would have absorbed.
|
|
80
|
+
const cooldown = this.size > 1 ? cooldownFor(err) : null;
|
|
81
|
+
if (cooldown === null)
|
|
82
|
+
throw err;
|
|
83
|
+
key.evictedUntil = this.now() + cooldown.forMs;
|
|
84
|
+
this.onEvict?.({ tier: key.tier, kind: cooldown.kind, forMs: cooldown.forMs });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Every candidate was evicted during this call.
|
|
88
|
+
if (this.candidates(this.now()).length === 0)
|
|
89
|
+
throw new NoAvailableKeyError(this.label, this.nextAvailableAt());
|
|
90
|
+
throw last;
|
|
91
|
+
}
|
|
92
|
+
/** Free keys round-robin from a moving cursor, then the paid key. */
|
|
93
|
+
candidates(now) {
|
|
94
|
+
const out = [];
|
|
95
|
+
const n = this.free.length;
|
|
96
|
+
for (let i = 0; i < n; i++) {
|
|
97
|
+
const key = this.free[(this.cursor + i) % n];
|
|
98
|
+
if (key.evictedUntil <= now)
|
|
99
|
+
out.push(key);
|
|
100
|
+
}
|
|
101
|
+
if (n > 0)
|
|
102
|
+
this.cursor = (this.cursor + 1) % n;
|
|
103
|
+
if (this.paid && this.paid.evictedUntil <= now)
|
|
104
|
+
out.push(this.paid);
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
107
|
+
nextAvailableAt() {
|
|
108
|
+
const all = this.paid ? [...this.free, this.paid] : this.free;
|
|
109
|
+
return Math.min(...all.map((key) => key.evictedUntil));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* How long to bench a key for this failure, or null when the failure is not the
|
|
114
|
+
* key's fault — nothing is gained by rotating, and benching would spend the
|
|
115
|
+
* pool on a request that fails the same way everywhere.
|
|
116
|
+
*/
|
|
117
|
+
function cooldownFor(err) {
|
|
118
|
+
if (!(err instanceof ProviderError))
|
|
119
|
+
return null;
|
|
120
|
+
const clamp = (ms) => Math.min(Math.max(ms, MIN_EVICTION_MS), MAX_EVICTION_MS);
|
|
121
|
+
switch (err.kind) {
|
|
122
|
+
// The three kinds that are about THIS key.
|
|
123
|
+
case "rate":
|
|
124
|
+
return { kind: err.kind, forMs: clamp(err.retryAfterMs ?? RATE_COOLDOWN_MS) };
|
|
125
|
+
case "quota":
|
|
126
|
+
return { kind: err.kind, forMs: clamp(err.retryAfterMs ?? QUOTA_COOLDOWN_MS) };
|
|
127
|
+
case "auth":
|
|
128
|
+
// 12 h, not forever: a key is also refused while a billing account is
|
|
129
|
+
// reinstated, and a pool that drops keys permanently ends up empty.
|
|
130
|
+
return { kind: err.kind, forMs: AUTH_COOLDOWN_MS };
|
|
131
|
+
default:
|
|
132
|
+
// Not the key's fault, but a sibling key is a different project on a
|
|
133
|
+
// different backend, so one more call is the cheapest way to find out —
|
|
134
|
+
// which is what an overload or a stalled request is worth. `network` is
|
|
135
|
+
// excluded deliberately: the socket died on our side and dies identically
|
|
136
|
+
// on every key, so benching for it would answer NoAvailableKeyError to
|
|
137
|
+
// what is really "no internet".
|
|
138
|
+
return isTransient(err.kind) && err.kind !== "network"
|
|
139
|
+
? { kind: err.kind, forMs: TRANSIENT_COOLDOWN_MS }
|
|
140
|
+
: null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Give any provider a rotating pool of keys.
|
|
145
|
+
*
|
|
146
|
+
* The subtlety is the seam's shape. `createStream` is an async generator, so
|
|
147
|
+
* CALLING it performs no I/O: the POST — and the 429 that should rotate the key
|
|
148
|
+
* — happens on the first `next()`, long after a `pool.with` wrapped around the
|
|
149
|
+
* call itself would have returned, with nothing left to rotate. So the first
|
|
150
|
+
* chunk is pulled INSIDE the pool and only the rest of the stream is consumed
|
|
151
|
+
* outside it.
|
|
152
|
+
*
|
|
153
|
+
* That line is also the honest one. Past the first chunk the answer is
|
|
154
|
+
* committed to one key, exactly as a retry is committed past its first chunk
|
|
155
|
+
* (retry.ts, rule 2): a mid-stream 429 evicts nothing and rotates nothing,
|
|
156
|
+
* because there is no way to resume a half-rendered answer on another key.
|
|
157
|
+
*/
|
|
158
|
+
export function withKeyPool(pool, factory) {
|
|
159
|
+
// The identity every key shares. Building an adapter performs no I/O — it
|
|
160
|
+
// closes over its config and nothing else — so a throwaway instance is the
|
|
161
|
+
// cheapest way to read `id` and `model` without holding a key outside the
|
|
162
|
+
// pool.
|
|
163
|
+
const identity = factory("");
|
|
164
|
+
return {
|
|
165
|
+
id: identity.id,
|
|
166
|
+
model: identity.model,
|
|
167
|
+
async *createStream(messages, tools, opts = {}) {
|
|
168
|
+
const opened = await pool.with(async (apiKey) => {
|
|
169
|
+
// One AbortController per attempt, chained to the caller's own signal
|
|
170
|
+
// (retry.ts's rule). Finalizing a generator is not cancellation:
|
|
171
|
+
// `return()` unwinds the adapter down to `streamSse`'s finalizer, which
|
|
172
|
+
// only releases the reader's lock — the response body stays live and
|
|
173
|
+
// the request is never aborted. Without this controller an abandoned
|
|
174
|
+
// attempt keeps the provider generating the rest of the answer, holding
|
|
175
|
+
// a connection and a concurrency slot on the very key the pool is
|
|
176
|
+
// rotating away from.
|
|
177
|
+
const controller = new AbortController();
|
|
178
|
+
const onAbort = () => controller.abort(opts.signal?.reason);
|
|
179
|
+
if (opts.signal?.aborted)
|
|
180
|
+
onAbort();
|
|
181
|
+
else
|
|
182
|
+
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
183
|
+
const stream = factory(apiKey).createStream(messages, tools, {
|
|
184
|
+
...opts,
|
|
185
|
+
signal: controller.signal,
|
|
186
|
+
});
|
|
187
|
+
const iterator = stream[Symbol.asyncIterator]();
|
|
188
|
+
const release = async () => {
|
|
189
|
+
opts.signal?.removeEventListener("abort", onAbort);
|
|
190
|
+
await close(iterator);
|
|
191
|
+
controller.abort();
|
|
192
|
+
};
|
|
193
|
+
try {
|
|
194
|
+
return { iterator, first: await iterator.next(), release };
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
// The request failed under the pool, which is about to try the next
|
|
198
|
+
// key: release this attempt before a second one opens against the
|
|
199
|
+
// same rate limit.
|
|
200
|
+
await release();
|
|
201
|
+
throw err;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
const { iterator, first, release } = opened;
|
|
205
|
+
try {
|
|
206
|
+
if (first.done)
|
|
207
|
+
return;
|
|
208
|
+
yield first.value;
|
|
209
|
+
for (;;) {
|
|
210
|
+
const next = await iterator.next();
|
|
211
|
+
if (next.done)
|
|
212
|
+
return;
|
|
213
|
+
yield next.value;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
finally {
|
|
217
|
+
// A consumer that breaks out of its loop never reaches the end of ours,
|
|
218
|
+
// and an attempt left unfinalized and un-aborted streams for the whole
|
|
219
|
+
// rest of the answer into a body nobody reads.
|
|
220
|
+
await release();
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/** Finalize an abandoned stream. `return()` can reject on its own (an aborted
|
|
226
|
+
* body), and that must never replace the failure being handled. */
|
|
227
|
+
async function close(iterator) {
|
|
228
|
+
try {
|
|
229
|
+
await iterator.return?.();
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// The request is being abandoned either way.
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=key-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-pool.js","sourceRoot":"","sources":["../src/key-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,13 +2,22 @@ import type { ChatMessage, Effort, Provider } from "../types.ts";
|
|
|
2
2
|
export interface AnthropicConfig {
|
|
3
3
|
apiKey: string;
|
|
4
4
|
model: string;
|
|
5
|
+
/** Any endpoint speaking the Anthropic Messages dialect — a proxy or gateway.
|
|
6
|
+
* Defaults to Anthropic itself. */
|
|
5
7
|
baseUrl?: string;
|
|
8
|
+
/** Names the provider in errors and logs. The subscription backend is the
|
|
9
|
+
* reason this is not hardcoded: a token failure there is a re-login, not a
|
|
10
|
+
* bad API key, and the two must not read the same in a ledger. */
|
|
11
|
+
id?: string;
|
|
6
12
|
/** Bound default; a per-call `effort` overrides it. */
|
|
7
13
|
effort?: Effort;
|
|
8
14
|
/** Anthropic requires an output ceiling on every request. */
|
|
9
15
|
maxTokens?: number;
|
|
10
16
|
version?: string;
|
|
11
17
|
fetchImpl?: typeof fetch;
|
|
18
|
+
/** Merged into every request. The subscription backend needs its own beta
|
|
19
|
+
* headers, and a gateway in front usually wants one of its own. */
|
|
20
|
+
headers?: Record<string, string>;
|
|
12
21
|
/** Send the key as a Bearer instead of `x-api-key` — what a subscription
|
|
13
22
|
* access token needs. */
|
|
14
23
|
bearer?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,WAAW,EAEX,MAAM,EAEN,QAAQ,EAIT,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd;wCACoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;uEAEmE;IACnE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;wEACoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;8BAC0B;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA+CD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CAoDA;AAyBD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,GAAG,QAAQ,CAoJzE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Anthropic-shape adapter — SSE from POST /v1/messages.
|
|
2
|
-
import {
|
|
2
|
+
import { streamError } from "../errors.js";
|
|
3
|
+
import { parseToolArgs } from "../tool-args.js";
|
|
3
4
|
import { streamSse, apiUrl } from "../transport.js";
|
|
4
5
|
const DEFAULT_BASE_URL = "https://api.anthropic.com";
|
|
5
6
|
const DEFAULT_VERSION = "2023-06-01";
|
|
@@ -93,7 +94,7 @@ export function toAnthropicMessages(messages) {
|
|
|
93
94
|
type: "tool_use",
|
|
94
95
|
id: call.id,
|
|
95
96
|
name: call.name,
|
|
96
|
-
input:
|
|
97
|
+
input: parseToolArgs(call.arguments),
|
|
97
98
|
});
|
|
98
99
|
}
|
|
99
100
|
if (blocks.length > 0)
|
|
@@ -101,18 +102,11 @@ export function toAnthropicMessages(messages) {
|
|
|
101
102
|
}
|
|
102
103
|
return { ...(system ? { system } : {}), messages: out };
|
|
103
104
|
}
|
|
104
|
-
function safeParse(raw) {
|
|
105
|
-
try {
|
|
106
|
-
return raw ? JSON.parse(raw) : {};
|
|
107
|
-
}
|
|
108
|
-
catch {
|
|
109
|
-
return {};
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
105
|
export function createAnthropicProvider(config) {
|
|
113
106
|
const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
107
|
+
const id = config.id ?? "anthropic";
|
|
114
108
|
return {
|
|
115
|
-
id
|
|
109
|
+
id,
|
|
116
110
|
model: config.model,
|
|
117
111
|
async *createStream(messages, tools, opts = {}) {
|
|
118
112
|
const model = opts.model ?? config.model;
|
|
@@ -167,9 +161,10 @@ export function createAnthropicProvider(config) {
|
|
|
167
161
|
...(config.bearer
|
|
168
162
|
? { authorization: `Bearer ${config.apiKey}` }
|
|
169
163
|
: { "x-api-key": config.apiKey }),
|
|
164
|
+
...config.headers,
|
|
170
165
|
},
|
|
171
166
|
body: request,
|
|
172
|
-
provider:
|
|
167
|
+
provider: id,
|
|
173
168
|
...(opts.signal ? { signal: opts.signal } : {}),
|
|
174
169
|
...(config.fetchImpl ? { fetchImpl: config.fetchImpl } : {}),
|
|
175
170
|
})) {
|
|
@@ -181,8 +176,12 @@ export function createAnthropicProvider(config) {
|
|
|
181
176
|
continue; // a keep-alive or a frame we do not model
|
|
182
177
|
}
|
|
183
178
|
switch (event.type) {
|
|
179
|
+
// A failure the backend reports after its headers went out. Classified
|
|
180
|
+
// rather than assumed transient: this shape carries `overloaded_error`
|
|
181
|
+
// most of the time, but a prompt found too long mid-stream arrives the
|
|
182
|
+
// same way, and retrying that one only fails it again more slowly.
|
|
184
183
|
case "error":
|
|
185
|
-
throw
|
|
184
|
+
throw streamError(id, event.error);
|
|
186
185
|
case "message_start": {
|
|
187
186
|
const usage = event.message?.usage;
|
|
188
187
|
cachedInputTokens = usage?.cache_read_input_tokens ?? 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ChatMessage, Effort, Provider } from "../types.ts";
|
|
2
|
+
export interface GeminiConfig {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
model: string;
|
|
5
|
+
/** Any endpoint speaking the Generative Language REST dialect — a proxy or
|
|
6
|
+
* gateway. Defaults to the Generative Language API.
|
|
7
|
+
*
|
|
8
|
+
* Not Vertex: it serves `/v1/projects/…/locations/…/publishers/google/models`
|
|
9
|
+
* and authenticates with a Bearer token, and both the path and the
|
|
10
|
+
* `x-goog-api-key` header are fixed below. Vertex would be its own adapter. */
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
/** Names the provider in errors and logs. */
|
|
13
|
+
id?: string;
|
|
14
|
+
/** Bound default; a per-call `effort` overrides it. */
|
|
15
|
+
effort?: Effort;
|
|
16
|
+
maxTokens?: number;
|
|
17
|
+
fetchImpl?: typeof fetch;
|
|
18
|
+
headers?: Record<string, string>;
|
|
19
|
+
}
|
|
20
|
+
/** A turn in Gemini's history. `model` is its word for the assistant. */
|
|
21
|
+
export interface GeminiContent {
|
|
22
|
+
role: "user" | "model";
|
|
23
|
+
parts: unknown[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Our messages → Gemini contents.
|
|
27
|
+
*
|
|
28
|
+
* Three shape differences the rest of the adapter must not have to know about:
|
|
29
|
+
* system text is lifted out and merged into ONE instruction (Gemini takes a
|
|
30
|
+
* single one, not a role in the turn list); assistant turns are role `model`
|
|
31
|
+
* and carry tool calls as `functionCall` parts with the thought signature
|
|
32
|
+
* beside them; tool results are role `user` with a `functionResponse` part
|
|
33
|
+
* naming the FUNCTION, since Gemini pairs a result to its call by name.
|
|
34
|
+
*/
|
|
35
|
+
export declare function toGeminiContents(messages: readonly ChatMessage[]): {
|
|
36
|
+
system?: string;
|
|
37
|
+
contents: GeminiContent[];
|
|
38
|
+
};
|
|
39
|
+
export declare function createGeminiProvider(config: GeminiConfig): Provider;
|
|
40
|
+
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EAEN,QAAQ,EAMT,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd;;;;;oFAKgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAoBD,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAqCD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B,CA+DA;AA0DD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,QAAQ,CAuJnE"}
|