@effect-uai/google 0.2.0 → 0.3.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/Gemini.d.mts +105 -0
- package/dist/Gemini.d.mts.map +1 -0
- package/dist/Gemini.mjs +170 -0
- package/dist/Gemini.mjs.map +1 -0
- package/dist/GeminiEmbedding.d.mts +64 -0
- package/dist/GeminiEmbedding.d.mts.map +1 -0
- package/dist/GeminiEmbedding.mjs +167 -0
- package/dist/GeminiEmbedding.mjs.map +1 -0
- package/dist/codec.d.mts +107 -0
- package/dist/codec.d.mts.map +1 -0
- package/dist/codec.mjs +151 -0
- package/dist/codec.mjs.map +1 -0
- package/dist/index.d.mts +5 -214
- package/dist/index.mjs +5 -289
- package/dist/models.d.mts +27 -0
- package/dist/models.d.mts.map +1 -0
- package/dist/models.mjs +1 -0
- package/package.json +20 -12
- package/src/Gemini.ts +3 -3
- package/src/GeminiEmbedding.ts +351 -0
- package/src/codec.ts +42 -35
- package/src/index.ts +3 -2
- package/src/models.ts +20 -0
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,289 +1,5 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import { JsonParseError } from "@effect-uai/core/JSONL";
|
|
7
|
-
import * as SSE from "@effect-uai/core/SSE";
|
|
8
|
-
import { matchType } from "@effect-uai/core/Match";
|
|
9
|
-
//#region src/codec.ts
|
|
10
|
-
var codec_exports = /* @__PURE__ */ __exportAll({
|
|
11
|
-
WireChunk: () => WireChunk,
|
|
12
|
-
accumulatorToTurn: () => accumulatorToTurn,
|
|
13
|
-
buildRequestBody: () => buildRequestBody,
|
|
14
|
-
emptyAccumulator: () => emptyAccumulator,
|
|
15
|
-
ingestChunk: () => ingestChunk
|
|
16
|
-
});
|
|
17
|
-
const TextPart = Schema.Struct({
|
|
18
|
-
text: Schema.String,
|
|
19
|
-
/**
|
|
20
|
-
* Gemini's flag for chain-of-thought parts. When `true`, the part is
|
|
21
|
-
* reasoning trace, not the model's user-facing answer. Maps onto
|
|
22
|
-
* `reasoning_delta { kind: "trace" }` in the canonical view.
|
|
23
|
-
*/
|
|
24
|
-
thought: Schema.optional(Schema.Boolean)
|
|
25
|
-
});
|
|
26
|
-
const Part = Schema.Union([TextPart]);
|
|
27
|
-
const Content = Schema.Struct({
|
|
28
|
-
role: Schema.optional(Schema.String),
|
|
29
|
-
parts: Schema.optional(Schema.Array(Part))
|
|
30
|
-
});
|
|
31
|
-
const Candidate = Schema.Struct({
|
|
32
|
-
content: Schema.optional(Content),
|
|
33
|
-
finishReason: Schema.optional(Schema.String),
|
|
34
|
-
index: Schema.optional(Schema.Number)
|
|
35
|
-
});
|
|
36
|
-
const UsageMetadata = Schema.Struct({
|
|
37
|
-
promptTokenCount: Schema.optional(Schema.Number),
|
|
38
|
-
candidatesTokenCount: Schema.optional(Schema.Number),
|
|
39
|
-
totalTokenCount: Schema.optional(Schema.Number),
|
|
40
|
-
cachedContentTokenCount: Schema.optional(Schema.Number),
|
|
41
|
-
thoughtsTokenCount: Schema.optional(Schema.Number)
|
|
42
|
-
});
|
|
43
|
-
const WireChunk = Schema.Struct({
|
|
44
|
-
candidates: Schema.optional(Schema.Array(Candidate)),
|
|
45
|
-
usageMetadata: Schema.optional(UsageMetadata)
|
|
46
|
-
});
|
|
47
|
-
const blockText = Match.type().pipe(matchType("input_text", (b) => b.text), matchType("input_image", () => ""), matchType("output_text", (b) => b.text), matchType("refusal", (b) => b.text), Match.exhaustive);
|
|
48
|
-
const messageText = (message) => message.content.map(blockText).join("");
|
|
49
|
-
const blockToParts = Match.type().pipe(matchType("input_text", (b) => b.text.length === 0 ? [] : [{ text: b.text }]), matchType("input_image", (b) => b.source._tag === "base64" ? [{ inlineData: {
|
|
50
|
-
mimeType: b.source.media_type,
|
|
51
|
-
data: b.source.data
|
|
52
|
-
} }] : []), matchType("output_text", (b) => b.text.length === 0 ? [] : [{ text: b.text }]), matchType("refusal", () => []), Match.exhaustive);
|
|
53
|
-
const messageToContent = (message) => {
|
|
54
|
-
const parts = pipe(message.content, Array.flatMap(blockToParts));
|
|
55
|
-
if (parts.length === 0) return Result.failVoid;
|
|
56
|
-
return Match.value(message.role).pipe(Match.when("user", () => Result.succeed({
|
|
57
|
-
role: "user",
|
|
58
|
-
parts
|
|
59
|
-
})), Match.when("assistant", () => Result.succeed({
|
|
60
|
-
role: "model",
|
|
61
|
-
parts
|
|
62
|
-
})), Match.when("system", () => Result.failVoid), Match.exhaustive);
|
|
63
|
-
};
|
|
64
|
-
const systemMessageText = (message) => {
|
|
65
|
-
if (message.role !== "system") return Result.failVoid;
|
|
66
|
-
const text = messageText(message);
|
|
67
|
-
return text.length === 0 ? Result.failVoid : Result.succeed(text);
|
|
68
|
-
};
|
|
69
|
-
const messages = (history) => pipe(history, Array.filterMap((item) => item.type === "message" ? Result.succeed(item) : Result.failVoid));
|
|
70
|
-
const buildRequestBody = (history, generationConfig) => {
|
|
71
|
-
const msgs = messages(history);
|
|
72
|
-
const systemTexts = pipe(msgs, Array.filterMap(systemMessageText));
|
|
73
|
-
return {
|
|
74
|
-
contents: pipe(msgs, Array.filterMap(messageToContent)),
|
|
75
|
-
...systemTexts.length > 0 && { systemInstruction: { parts: [{ text: systemTexts.join("\n") }] } },
|
|
76
|
-
...Option.match(generationConfig, {
|
|
77
|
-
onNone: () => ({}),
|
|
78
|
-
onSome: (cfg) => ({ generationConfig: cfg })
|
|
79
|
-
})
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
const finishReasonToStop = (reason) => Option.match(reason, {
|
|
83
|
-
onNone: () => "stop",
|
|
84
|
-
onSome: (r) => r === "MAX_TOKENS" ? "max_tokens" : "stop"
|
|
85
|
-
});
|
|
86
|
-
const emptyAccumulator = {
|
|
87
|
-
text: "",
|
|
88
|
-
reasoning: "",
|
|
89
|
-
finishReason: Option.none(),
|
|
90
|
-
usage: {}
|
|
91
|
-
};
|
|
92
|
-
const chunkParts = (chunk) => pipe(chunk.candidates?.[0]?.content?.parts ?? [], Array.filterMap((p) => p.text.length === 0 ? Result.failVoid : Result.succeed({
|
|
93
|
-
kind: p.thought === true ? "reasoning" : "text",
|
|
94
|
-
text: p.text
|
|
95
|
-
})));
|
|
96
|
-
const sumByKind = (parts, kind) => pipe(parts, Array.filterMap((p) => p.kind === kind ? Result.succeed(p.text) : Result.failVoid)).join("");
|
|
97
|
-
const mergeUsage = (prev, next) => next === void 0 ? prev : {
|
|
98
|
-
...prev,
|
|
99
|
-
...next.promptTokenCount !== void 0 && { input_tokens: next.promptTokenCount },
|
|
100
|
-
...next.candidatesTokenCount !== void 0 && { output_tokens: next.candidatesTokenCount },
|
|
101
|
-
...next.totalTokenCount !== void 0 && { total_tokens: next.totalTokenCount },
|
|
102
|
-
...next.cachedContentTokenCount !== void 0 && { input_tokens_details: { cached_tokens: next.cachedContentTokenCount } },
|
|
103
|
-
...next.thoughtsTokenCount !== void 0 && { output_tokens_details: { reasoning_tokens: next.thoughtsTokenCount } }
|
|
104
|
-
};
|
|
105
|
-
const ingestChunk = (acc, chunk) => {
|
|
106
|
-
const parts = chunkParts(chunk);
|
|
107
|
-
const finishReason = Option.fromNullishOr(chunk.candidates?.[0]?.finishReason);
|
|
108
|
-
return {
|
|
109
|
-
parts,
|
|
110
|
-
finished: Option.isSome(finishReason),
|
|
111
|
-
accumulator: {
|
|
112
|
-
text: acc.text + sumByKind(parts, "text"),
|
|
113
|
-
reasoning: acc.reasoning + sumByKind(parts, "reasoning"),
|
|
114
|
-
finishReason: Option.orElse(finishReason, () => acc.finishReason),
|
|
115
|
-
usage: mergeUsage(acc.usage, chunk.usageMetadata)
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
};
|
|
119
|
-
const accumulatorToTurn = (acc) => ({
|
|
120
|
-
stop_reason: finishReasonToStop(acc.finishReason),
|
|
121
|
-
usage: { ...acc.usage },
|
|
122
|
-
items: [...acc.reasoning.length > 0 ? [{
|
|
123
|
-
type: "reasoning",
|
|
124
|
-
summary: acc.reasoning
|
|
125
|
-
}] : [], ...acc.text.length === 0 ? [] : [{
|
|
126
|
-
type: "message",
|
|
127
|
-
role: "assistant",
|
|
128
|
-
content: [{
|
|
129
|
-
type: "output_text",
|
|
130
|
-
text: acc.text
|
|
131
|
-
}]
|
|
132
|
-
}]]
|
|
133
|
-
});
|
|
134
|
-
//#endregion
|
|
135
|
-
//#region src/Gemini.ts
|
|
136
|
-
/**
|
|
137
|
-
* Gemini's native event vocabulary. Aliased from `WireChunk` so the public
|
|
138
|
-
* surface matches `@effect-uai/responses` and `@effect-uai/anthropic`. Each
|
|
139
|
-
* `ProviderEvent` is a full `GenerateContentResponse` chunk (not a per-field
|
|
140
|
-
* delta) - that's how Gemini's SSE works.
|
|
141
|
-
*/
|
|
142
|
-
const ProviderEvent = WireChunk;
|
|
143
|
-
/**
|
|
144
|
-
* Provider-typed service tag. Yield this when you want Gemini-specific
|
|
145
|
-
* options (`thinkingBudget`); yield the generic `LanguageModel` tag for
|
|
146
|
-
* provider-portable code. Both are registered by `layer`.
|
|
147
|
-
*/
|
|
148
|
-
var Gemini = class extends Context.Service()("@betalyra/effect-uai/providers/google/Gemini") {};
|
|
149
|
-
const buildGenerationConfig = (request) => {
|
|
150
|
-
const cfg = {
|
|
151
|
-
...request.temperature !== void 0 && { temperature: request.temperature },
|
|
152
|
-
...request.maxOutputTokens !== void 0 && { maxOutputTokens: request.maxOutputTokens },
|
|
153
|
-
...request.topP !== void 0 && { topP: request.topP },
|
|
154
|
-
...request.thinkingBudget !== void 0 && { thinkingConfig: { thinkingBudget: request.thinkingBudget } },
|
|
155
|
-
...request.structured !== void 0 && {
|
|
156
|
-
responseMimeType: "application/json",
|
|
157
|
-
responseJsonSchema: request.structured.schema["~standard"].jsonSchema.input({ target: "draft-2020-12" })
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
return Object.keys(cfg).length === 0 ? Option.none() : Option.some(cfg);
|
|
161
|
-
};
|
|
162
|
-
const decodeChunk = Schema.decodeUnknownEffect(WireChunk);
|
|
163
|
-
/**
|
|
164
|
-
* Parse one SSE event's `data` payload into a `WireChunk`. Unlike the other
|
|
165
|
-
* providers, Gemini's wire vocabulary is non-discriminated (a single
|
|
166
|
-
* permissive struct, all fields optional) - there's no natural shape for
|
|
167
|
-
* an `_unknown` variant, so JSON parse / schema decode failures flow
|
|
168
|
-
* through as transport errors rather than being silently dropped.
|
|
169
|
-
*/
|
|
170
|
-
const sseEventToChunk = (ev) => Effect.try({
|
|
171
|
-
try: () => JSON.parse(ev.data),
|
|
172
|
-
catch: (cause) => new JsonParseError({
|
|
173
|
-
line: ev.data,
|
|
174
|
-
cause
|
|
175
|
-
})
|
|
176
|
-
}).pipe(Effect.flatMap(decodeChunk));
|
|
177
|
-
const httpStatusError = (status, body) => {
|
|
178
|
-
const provider = "gemini";
|
|
179
|
-
const raw = body;
|
|
180
|
-
if (status === 429) return new AiError.RateLimited({
|
|
181
|
-
provider,
|
|
182
|
-
raw
|
|
183
|
-
});
|
|
184
|
-
if (status === 408 || status === 504) return new AiError.Timeout({
|
|
185
|
-
provider,
|
|
186
|
-
raw
|
|
187
|
-
});
|
|
188
|
-
if (status === 401) return new AiError.AuthFailed({
|
|
189
|
-
provider,
|
|
190
|
-
subtype: "auth",
|
|
191
|
-
raw
|
|
192
|
-
});
|
|
193
|
-
if (status === 403) return new AiError.AuthFailed({
|
|
194
|
-
provider,
|
|
195
|
-
subtype: "permission",
|
|
196
|
-
raw
|
|
197
|
-
});
|
|
198
|
-
if (status === 402) return new AiError.AuthFailed({
|
|
199
|
-
provider,
|
|
200
|
-
subtype: "billing",
|
|
201
|
-
raw
|
|
202
|
-
});
|
|
203
|
-
if (status === 413) return new AiError.ContextLengthExceeded({
|
|
204
|
-
provider,
|
|
205
|
-
raw
|
|
206
|
-
});
|
|
207
|
-
if (status >= 500) return new AiError.Unavailable({
|
|
208
|
-
provider,
|
|
209
|
-
status,
|
|
210
|
-
raw
|
|
211
|
-
});
|
|
212
|
-
return new AiError.InvalidRequest({
|
|
213
|
-
provider,
|
|
214
|
-
raw
|
|
215
|
-
});
|
|
216
|
-
};
|
|
217
|
-
const buildNativeStream = (cfg) => {
|
|
218
|
-
const baseUrl = cfg.baseUrl ?? "https://generativelanguage.googleapis.com/v1beta";
|
|
219
|
-
return (request) => Stream.unwrap(Effect.gen(function* () {
|
|
220
|
-
const client = yield* HttpClient.HttpClient;
|
|
221
|
-
const url = `${baseUrl}/models/${request.model}:streamGenerateContent?alt=sse`;
|
|
222
|
-
const generationConfig = buildGenerationConfig(request);
|
|
223
|
-
const body = buildRequestBody(request.history, generationConfig);
|
|
224
|
-
const httpRequest = HttpClientRequest.post(url).pipe(HttpClientRequest.setHeader("x-goog-api-key", Redacted.value(cfg.apiKey)), HttpClientRequest.bodyJsonUnsafe(body), HttpClientRequest.accept("text/event-stream"));
|
|
225
|
-
const response = yield* client.execute(httpRequest).pipe(Effect.mapError((cause) => new AiError.Unavailable({
|
|
226
|
-
provider: "gemini",
|
|
227
|
-
raw: cause
|
|
228
|
-
})));
|
|
229
|
-
if (response.status >= 400) {
|
|
230
|
-
const text = yield* response.text.pipe(Effect.orElseSucceed(() => ""));
|
|
231
|
-
return Stream.fail(httpStatusError(response.status, text));
|
|
232
|
-
}
|
|
233
|
-
return response.stream.pipe(Stream.mapError((cause) => new AiError.Unavailable({
|
|
234
|
-
provider: "gemini",
|
|
235
|
-
raw: cause
|
|
236
|
-
})), SSE.fromBytes, Stream.mapEffect((ev) => sseEventToChunk(ev).pipe(Effect.mapError((cause) => new AiError.Unavailable({
|
|
237
|
-
provider: "gemini",
|
|
238
|
-
raw: cause
|
|
239
|
-
})))));
|
|
240
|
-
}));
|
|
241
|
-
};
|
|
242
|
-
/**
|
|
243
|
-
* Project a stream of native `ProviderEvent`s into canonical `TurnEvent`s.
|
|
244
|
-
* Threads a fresh `Accumulator` so chunk-level text/usage merging works
|
|
245
|
-
* across the run.
|
|
246
|
-
*/
|
|
247
|
-
const toCanonical = (s) => s.pipe(Stream.mapAccum(() => emptyAccumulator, (acc, chunk) => {
|
|
248
|
-
const result = ingestChunk(acc, chunk);
|
|
249
|
-
const partDeltas = result.parts.map((p) => p.kind === "text" ? {
|
|
250
|
-
type: "text_delta",
|
|
251
|
-
text: p.text
|
|
252
|
-
} : {
|
|
253
|
-
type: "reasoning_delta",
|
|
254
|
-
text: p.text,
|
|
255
|
-
kind: "trace"
|
|
256
|
-
});
|
|
257
|
-
const deltas = result.finished ? [...partDeltas, {
|
|
258
|
-
type: "turn_complete",
|
|
259
|
-
turn: accumulatorToTurn(result.accumulator)
|
|
260
|
-
}] : partDeltas;
|
|
261
|
-
return [result.accumulator, deltas];
|
|
262
|
-
}));
|
|
263
|
-
/**
|
|
264
|
-
* Build a `GeminiService` value. For Layer-based setup, prefer `layer`.
|
|
265
|
-
*/
|
|
266
|
-
const make = (cfg) => Effect.map(HttpClient.HttpClient.asEffect(), (client) => {
|
|
267
|
-
const streamNative = (request) => buildNativeStream(cfg)(request).pipe(Stream.provideService(HttpClient.HttpClient, client));
|
|
268
|
-
return {
|
|
269
|
-
streamNative,
|
|
270
|
-
streamTurn: (request) => toCanonical(streamNative(request)),
|
|
271
|
-
toCanonical
|
|
272
|
-
};
|
|
273
|
-
});
|
|
274
|
-
/**
|
|
275
|
-
* Layer that registers both the provider-specific `Gemini` tag and the
|
|
276
|
-
* generic `LanguageModel` tag, sharing one underlying implementation.
|
|
277
|
-
*
|
|
278
|
-
* The generic tag accepts `CommonRequest`; the typed tag accepts the full
|
|
279
|
-
* `GeminiRequest` surface.
|
|
280
|
-
*/
|
|
281
|
-
const layer = (cfg) => {
|
|
282
|
-
const typed = Layer.effect(Gemini, make(cfg));
|
|
283
|
-
const generic = Layer.effect(LanguageModel, Effect.map(make(cfg), (s) => ({ streamTurn: (request) => s.streamTurn(request) })));
|
|
284
|
-
return Layer.merge(typed, generic);
|
|
285
|
-
};
|
|
286
|
-
//#endregion
|
|
287
|
-
export { Gemini, ProviderEvent, codec_exports as codec, layer, make, toCanonical };
|
|
288
|
-
|
|
289
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
import { t as codec_exports } from "./codec.mjs";
|
|
2
|
+
import { t as Gemini_exports } from "./Gemini.mjs";
|
|
3
|
+
import { t as GeminiEmbedding_exports } from "./GeminiEmbedding.mjs";
|
|
4
|
+
import "./models.mjs";
|
|
5
|
+
export { Gemini_exports as Gemini, GeminiEmbedding_exports as GeminiEmbedding, codec_exports as codec };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/models.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Known Gemini model identifiers (as of April 2026). The `(string & {})`
|
|
4
|
+
* tail keeps autocomplete on the literals while still accepting any string,
|
|
5
|
+
* so newly-released models work without an SDK update.
|
|
6
|
+
*
|
|
7
|
+
* Reference: https://ai.google.dev/gemini-api/docs/models
|
|
8
|
+
*/
|
|
9
|
+
type GoogleModel = "gemini-3.1-pro-preview" | "gemini-3-flash-preview" | "gemini-3.1-flash-lite-preview" | "gemini-3.1-flash-live-preview" | "gemini-3.1-flash-tts-preview" | "gemini-2.5-pro" | "gemini-2.5-flash" | "gemini-2.5-flash-lite" | (string & {});
|
|
10
|
+
/**
|
|
11
|
+
* Known Gemini embedding model identifiers.
|
|
12
|
+
*
|
|
13
|
+
* - `gemini-embedding-2` — natively multimodal (text, image, audio, video,
|
|
14
|
+
* PDF). Does *not* honour the `taskType` field; instead prepend a task
|
|
15
|
+
* instruction to the text yourself.
|
|
16
|
+
* - `gemini-embedding-001` — text-only, supports the full `taskType` enum
|
|
17
|
+
* (`RETRIEVAL_QUERY` / `RETRIEVAL_DOCUMENT` / classification / etc.).
|
|
18
|
+
*
|
|
19
|
+
* The `(string & {})` tail accepts any string so newly-released models
|
|
20
|
+
* work without an SDK update.
|
|
21
|
+
*
|
|
22
|
+
* Reference: https://ai.google.dev/gemini-api/docs/embeddings
|
|
23
|
+
*/
|
|
24
|
+
type GoogleEmbeddingModel = "gemini-embedding-2" | "gemini-embedding-001" | (string & {});
|
|
25
|
+
//#endregion
|
|
26
|
+
export { GoogleEmbeddingModel, GoogleModel };
|
|
27
|
+
//# sourceMappingURL=models.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.mts","names":[],"sources":["../src/models.ts"],"mappings":";;AAOA;;;;;AA0BA;KA1BY,WAAA;;;;;;;;;;;;;;;KA0BA,oBAAA"}
|
package/dist/models.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-uai/google",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Google Gemini provider for @effect-uai/core.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
"url": "https://github.com/betalyra/effect-uai",
|
|
21
21
|
"directory": "packages/providers/google"
|
|
22
22
|
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"src",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
23
29
|
"type": "module",
|
|
24
30
|
"main": "./dist/index.mjs",
|
|
25
31
|
"types": "./dist/index.d.mts",
|
|
@@ -27,25 +33,27 @@
|
|
|
27
33
|
".": {
|
|
28
34
|
"types": "./dist/index.d.mts",
|
|
29
35
|
"import": "./dist/index.mjs"
|
|
36
|
+
},
|
|
37
|
+
"./Gemini": {
|
|
38
|
+
"types": "./dist/Gemini.d.mts",
|
|
39
|
+
"import": "./dist/Gemini.mjs"
|
|
40
|
+
},
|
|
41
|
+
"./GeminiEmbedding": {
|
|
42
|
+
"types": "./dist/GeminiEmbedding.d.mts",
|
|
43
|
+
"import": "./dist/GeminiEmbedding.mjs"
|
|
30
44
|
}
|
|
31
45
|
},
|
|
32
|
-
"files": [
|
|
33
|
-
"dist",
|
|
34
|
-
"src",
|
|
35
|
-
"README.md",
|
|
36
|
-
"LICENSE"
|
|
37
|
-
],
|
|
38
46
|
"publishConfig": {
|
|
39
47
|
"access": "public"
|
|
40
48
|
},
|
|
41
|
-
"peerDependencies": {
|
|
42
|
-
"effect": "4.0.0-beta.57",
|
|
43
|
-
"@effect-uai/core": "^0.2.0"
|
|
44
|
-
},
|
|
45
49
|
"devDependencies": {
|
|
46
50
|
"effect": "4.0.0-beta.57",
|
|
47
51
|
"typescript": "^6.0.3",
|
|
48
|
-
"@effect-uai/core": "0.
|
|
52
|
+
"@effect-uai/core": "0.3.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"@effect-uai/core": ">=0.2.0 <1",
|
|
56
|
+
"effect": "4.0.0-beta.57"
|
|
49
57
|
},
|
|
50
58
|
"scripts": {
|
|
51
59
|
"build": "tsdown",
|
package/src/Gemini.ts
CHANGED
|
@@ -32,7 +32,7 @@ export type ProviderEvent = WireChunk
|
|
|
32
32
|
// Public types
|
|
33
33
|
// ---------------------------------------------------------------------------
|
|
34
34
|
|
|
35
|
-
export
|
|
35
|
+
export type GeminiRequest = Omit<CommonRequest, "model"> & {
|
|
36
36
|
/**
|
|
37
37
|
* Narrows `CommonRequest.model` (`string`) to the typed `GoogleModel`
|
|
38
38
|
* literal union for autocomplete.
|
|
@@ -46,7 +46,7 @@ export interface GeminiRequest extends Omit<CommonRequest, "model"> {
|
|
|
46
46
|
readonly thinkingBudget?: number
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export
|
|
49
|
+
export type GeminiService = {
|
|
50
50
|
/**
|
|
51
51
|
* Stream the provider's native event vocabulary (post-SSE-decode). For
|
|
52
52
|
* Gemini, each event is a full `GenerateContentResponse` chunk. Use this
|
|
@@ -79,7 +79,7 @@ export class Gemini extends Context.Service<Gemini, GeminiService>()(
|
|
|
79
79
|
"@betalyra/effect-uai/providers/google/Gemini",
|
|
80
80
|
) {}
|
|
81
81
|
|
|
82
|
-
export
|
|
82
|
+
export type Config = {
|
|
83
83
|
readonly apiKey: Redacted.Redacted
|
|
84
84
|
readonly baseUrl?: string
|
|
85
85
|
}
|