@opencode/ai 2.0.22 → 2.0.23

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.
Files changed (92) hide show
  1. package/README.md +61 -1
  2. package/dist/cache-policy.js +1 -0
  3. package/dist/protocols/alibaba-chat.d.ts +3 -3
  4. package/dist/protocols/alibaba-responses.d.ts +16 -12
  5. package/dist/protocols/alibaba-responses.js +3 -5
  6. package/dist/protocols/anthropic-messages.js +44 -39
  7. package/dist/protocols/bedrock-converse.js +3 -3
  8. package/dist/protocols/cartesia-speech.js +3 -3
  9. package/dist/protocols/cohere-chat.d.ts +178 -0
  10. package/dist/protocols/cohere-chat.js +299 -0
  11. package/dist/protocols/elevenlabs-speech.js +3 -3
  12. package/dist/protocols/gemini.d.ts +2 -2
  13. package/dist/protocols/gemini.js +3 -3
  14. package/dist/protocols/google-interactions.d.ts +236 -0
  15. package/dist/protocols/google-interactions.js +478 -0
  16. package/dist/protocols/google-speech.js +1 -1
  17. package/dist/protocols/google-transcription.js +1 -1
  18. package/dist/protocols/index.d.ts +2 -0
  19. package/dist/protocols/index.js +2 -0
  20. package/dist/protocols/meta-responses.d.ts +31 -58
  21. package/dist/protocols/meta-responses.js +8 -27
  22. package/dist/protocols/mistral-chat.d.ts +24 -9
  23. package/dist/protocols/mistral-chat.js +22 -10
  24. package/dist/protocols/open-responses.d.ts +406 -91
  25. package/dist/protocols/open-responses.js +25 -15
  26. package/dist/protocols/openai-chat.d.ts +401 -5
  27. package/dist/protocols/openai-chat.js +18 -21
  28. package/dist/protocols/openai-compatible-chat.d.ts +1 -1
  29. package/dist/protocols/openai-compatible-responses.d.ts +16 -4
  30. package/dist/protocols/openai-images.js +2 -2
  31. package/dist/protocols/openai-responses.d.ts +87 -223
  32. package/dist/protocols/openai-responses.js +6 -13
  33. package/dist/protocols/openai-speech.js +1 -1
  34. package/dist/protocols/openai-transcription.js +1 -1
  35. package/dist/protocols/shared.js +2 -2
  36. package/dist/protocols/stability-images.js +1 -1
  37. package/dist/protocols/utils/bedrock-media.js +2 -2
  38. package/dist/protocols/utils/responses-checkpoint.js +2 -2
  39. package/dist/protocols/utils/responses-hosted-tools.js +1 -1
  40. package/dist/protocols/utils/tool-stream.js +15 -7
  41. package/dist/protocols/venice-chat.d.ts +280 -0
  42. package/dist/protocols/venice-chat.js +283 -0
  43. package/dist/protocols/xai-responses.d.ts +18 -21
  44. package/dist/protocols/xai-responses.js +2 -8
  45. package/dist/protocols/zai-chat.d.ts +3 -3
  46. package/dist/provider-error.js +7 -1
  47. package/dist/providers/alibaba.d.ts +17 -13
  48. package/dist/providers/amazon-bedrock/mantle/messages.d.ts +2 -0
  49. package/dist/providers/amazon-bedrock/mantle/messages.js +1 -0
  50. package/dist/providers/amazon-bedrock-mantle.d.ts +301 -9
  51. package/dist/providers/amazon-bedrock-mantle.js +28 -3
  52. package/dist/providers/azure.d.ts +13 -61
  53. package/dist/providers/baseten.d.ts +2 -2
  54. package/dist/providers/cerebras.d.ts +2 -2
  55. package/dist/providers/cloudflare-ai-gateway.d.ts +14 -62
  56. package/dist/providers/cloudflare-workers-ai.d.ts +2 -2
  57. package/dist/providers/cohere/chat.d.ts +4 -0
  58. package/dist/providers/cohere/chat.js +8 -0
  59. package/dist/providers/cohere.d.ts +395 -0
  60. package/dist/providers/cohere.js +48 -0
  61. package/dist/providers/deepinfra.d.ts +2 -2
  62. package/dist/providers/deepseek.d.ts +2 -2
  63. package/dist/providers/digitalocean.d.ts +5 -5
  64. package/dist/providers/fireworks.d.ts +2 -2
  65. package/dist/providers/google/interactions.d.ts +7 -0
  66. package/dist/providers/google/interactions.js +8 -0
  67. package/dist/providers/google-vertex-chat.d.ts +1 -1
  68. package/dist/providers/google-vertex-responses.d.ts +16 -4
  69. package/dist/providers/google-vertex.d.ts +1 -1
  70. package/dist/providers/google.d.ts +95 -4
  71. package/dist/providers/google.js +8 -1
  72. package/dist/providers/groq.d.ts +4 -4
  73. package/dist/providers/index.d.ts +2 -0
  74. package/dist/providers/index.js +2 -0
  75. package/dist/providers/meta.d.ts +15 -28
  76. package/dist/providers/minimax.d.ts +17 -5
  77. package/dist/providers/mistral.d.ts +10 -4
  78. package/dist/providers/moonshot.d.ts +17 -5
  79. package/dist/providers/openai-compatible-responses.d.ts +16 -4
  80. package/dist/providers/openai-compatible.d.ts +1 -1
  81. package/dist/providers/openai-options.d.ts +1 -1
  82. package/dist/providers/openai.d.ts +7 -31
  83. package/dist/providers/openrouter.d.ts +5 -5
  84. package/dist/providers/togetherai.d.ts +2 -2
  85. package/dist/providers/venice.d.ts +183 -0
  86. package/dist/providers/venice.js +38 -0
  87. package/dist/providers/xai.d.ts +1 -1
  88. package/dist/providers/zai-coding-plan.d.ts +17 -5
  89. package/dist/providers/zai.d.ts +1 -1
  90. package/dist/route/client.js +2 -5
  91. package/dist/route/framing.js +23 -23
  92. package/package.json +3 -3
@@ -0,0 +1,299 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { Route } from "../route/client.js";
3
+ import { Endpoint } from "../route/endpoint.js";
4
+ import { Framing } from "../route/framing.js";
5
+ import { Protocol } from "../route/protocol.js";
6
+ import { LLMEvent, Usage } from "../schema/index.js";
7
+ import { ProviderShared } from "./shared.js";
8
+ import { Lifecycle } from "./utils/lifecycle.js";
9
+ import { ToolStream } from "./utils/tool-stream.js";
10
+ const ADAPTER = "cohere-chat";
11
+ export const DEFAULT_BASE_URL = "https://api.cohere.com/v2";
12
+ const Options = Schema.Struct({
13
+ thinking: Schema.optional(Schema.Struct({
14
+ type: Schema.optional(Schema.Literals(["enabled", "disabled"])),
15
+ tokenBudget: Schema.optional(Schema.Int.check(Schema.isGreaterThan(0))),
16
+ })),
17
+ });
18
+ const Content = Schema.Union([
19
+ Schema.Struct({ type: Schema.Literal("text"), text: Schema.String }),
20
+ Schema.Struct({ type: Schema.Literal("thinking"), thinking: Schema.String }),
21
+ Schema.Struct({ type: Schema.Literal("image_url"), image_url: Schema.Struct({ url: Schema.String }) }),
22
+ ]);
23
+ const ToolCall = Schema.Struct({
24
+ id: Schema.String,
25
+ type: Schema.Literal("function"),
26
+ function: Schema.Struct({ name: Schema.String, arguments: Schema.String }),
27
+ });
28
+ const Message = Schema.Struct({
29
+ role: Schema.Literals(["system", "user", "assistant", "tool"]),
30
+ content: Schema.optional(Schema.Union([Schema.String, Schema.Array(Content)])),
31
+ tool_calls: Schema.optional(Schema.Array(ToolCall)),
32
+ tool_call_id: Schema.optional(Schema.String),
33
+ tool_plan: Schema.optional(Schema.String),
34
+ });
35
+ const Body = Schema.Struct({
36
+ model: Schema.String,
37
+ messages: Schema.Array(Message),
38
+ stream: Schema.Literal(true),
39
+ tools: Schema.optional(Schema.Array(Schema.Struct({
40
+ type: Schema.Literal("function"),
41
+ function: Schema.Struct({
42
+ name: Schema.String,
43
+ description: Schema.optional(Schema.String),
44
+ parameters: Schema.Unknown,
45
+ }),
46
+ }))),
47
+ tool_choice: Schema.optional(Schema.Literals(["NONE", "REQUIRED"])),
48
+ thinking: Schema.optional(Schema.Struct({ type: Schema.String, token_budget: Schema.optional(Schema.Number) })),
49
+ max_tokens: Schema.optional(Schema.Number),
50
+ temperature: Schema.optional(Schema.Number),
51
+ p: Schema.optional(Schema.Number),
52
+ k: Schema.optional(Schema.Number),
53
+ seed: Schema.optional(Schema.Number),
54
+ stop_sequences: Schema.optional(Schema.Array(Schema.String)),
55
+ frequency_penalty: Schema.optional(Schema.Number),
56
+ presence_penalty: Schema.optional(Schema.Number),
57
+ });
58
+ const TokenCounts = Schema.Struct({
59
+ input_tokens: Schema.optional(Schema.Number),
60
+ output_tokens: Schema.optional(Schema.Number),
61
+ reasoning_tokens: Schema.optional(Schema.Number),
62
+ });
63
+ const NativeUsage = Schema.Struct({
64
+ tokens: Schema.optional(TokenCounts),
65
+ billed_units: Schema.optional(TokenCounts),
66
+ cached_tokens: Schema.optional(Schema.Number),
67
+ });
68
+ const Event = Schema.Union([
69
+ Schema.Struct({ type: Schema.Literal("message-start") }),
70
+ Schema.Struct({
71
+ type: Schema.Literals(["content-start", "content-delta"]),
72
+ index: Schema.Number,
73
+ delta: Schema.Struct({
74
+ message: Schema.Struct({
75
+ content: Schema.Struct({ text: Schema.optional(Schema.String), thinking: Schema.optional(Schema.String) }),
76
+ }),
77
+ }),
78
+ }),
79
+ Schema.Struct({ type: Schema.Literal("content-end"), index: Schema.Number }),
80
+ Schema.Struct({
81
+ type: Schema.Literal("tool-plan-delta"),
82
+ delta: Schema.Struct({ message: Schema.Struct({ tool_plan: Schema.String }) }),
83
+ }),
84
+ Schema.Struct({
85
+ type: Schema.Literals(["tool-call-start", "tool-call-delta"]),
86
+ index: Schema.Number,
87
+ delta: Schema.Struct({
88
+ message: Schema.Struct({
89
+ tool_calls: Schema.Struct({
90
+ id: Schema.optional(Schema.String),
91
+ function: Schema.Struct({ name: Schema.optional(Schema.String), arguments: Schema.optional(Schema.String) }),
92
+ }),
93
+ }),
94
+ }),
95
+ }),
96
+ Schema.Struct({ type: Schema.Literal("tool-call-end"), index: Schema.Number }),
97
+ Schema.Struct({
98
+ type: Schema.Literal("message-end"),
99
+ delta: Schema.Struct({ finish_reason: Schema.String, usage: Schema.optional(NativeUsage) }),
100
+ }),
101
+ // Citation output is outside this basic chat surface.
102
+ Schema.Struct({ type: Schema.Literals(["citation-start", "citation-end"]) }),
103
+ ]);
104
+ const TOOL_CHOICE = { auto: undefined, none: "NONE", required: "REQUIRED", tool: "REQUIRED" };
105
+ const fromRequest = Effect.fn("CohereChat.fromRequest")(function* (request) {
106
+ const options = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Options))(request.providerOptions ?? {});
107
+ const flattened = ProviderShared.flattenToolRequest(request);
108
+ const messages = request.system.length
109
+ ? [
110
+ {
111
+ role: "system",
112
+ content: request.system.length === 1
113
+ ? request.system[0].text
114
+ : request.system.map((part) => ({ type: "text", text: part.text })),
115
+ },
116
+ ]
117
+ : [];
118
+ for (const message of flattened.request.messages) {
119
+ if (message.role === "system") {
120
+ messages.push({ role: "user", content: (yield* ProviderShared.wrappedSystemUpdate("Cohere Chat", message)).text });
121
+ continue;
122
+ }
123
+ if (message.role === "tool") {
124
+ for (const part of message.content) {
125
+ if (part.type !== "tool-result")
126
+ return yield* ProviderShared.unsupportedContent("Cohere Chat", "tool", ["tool-result"]);
127
+ if (part.result.type === "content" && part.result.value.some((item) => item.type === "file"))
128
+ return yield* ProviderShared.invalidRequest("Cohere Chat does not support file content in tool results");
129
+ messages.push({ role: "tool", tool_call_id: part.id, content: ProviderShared.toolResultText(part) });
130
+ }
131
+ continue;
132
+ }
133
+ const content = [];
134
+ const calls = [];
135
+ const plans = [];
136
+ for (const part of message.content) {
137
+ if (part.type === "text") {
138
+ content.push({ type: "text", text: part.text });
139
+ continue;
140
+ }
141
+ if (message.role === "assistant" && part.type === "reasoning") {
142
+ if (part.providerMetadata?.cohere?.toolPlan === true)
143
+ plans.push(part.text);
144
+ else
145
+ content.push({ type: "thinking", thinking: part.text });
146
+ continue;
147
+ }
148
+ if (message.role === "assistant" && part.type === "tool-call") {
149
+ const args = ProviderShared.encodeJson(part.input);
150
+ calls.push({ id: part.id, type: "function", function: { name: part.name, arguments: args } });
151
+ continue;
152
+ }
153
+ if (message.role === "user" && part.type === "media" && part.media.mediaType.startsWith("image/")) {
154
+ const url = ProviderShared.mediaUrl(part.media) ??
155
+ (yield* ProviderShared.requireInlineMedia("Cohere Chat", part.media)).dataUrl;
156
+ content.push({ type: "image_url", image_url: { url } });
157
+ continue;
158
+ }
159
+ return yield* ProviderShared.unsupportedContent("Cohere Chat", message.role, message.role === "user" ? ["text", "media"] : ["text", "reasoning", "tool-call"]);
160
+ }
161
+ messages.push({
162
+ role: message.role,
163
+ content: content.length ? content : undefined,
164
+ tool_calls: calls.length ? calls : undefined,
165
+ tool_plan: plans.length ? plans.join("") : undefined,
166
+ });
167
+ }
168
+ const selected = request.toolChoice?.type === "tool" ? request.toolChoice.name : undefined;
169
+ const tools = selected === undefined ? flattened.tools : flattened.tools.filter((tool) => tool.name === selected);
170
+ if (selected !== undefined && tools.length === 0)
171
+ return yield* ProviderShared.invalidRequest("Cohere Chat tool choice must name an available tool");
172
+ if (tools.some((tool) => tool.native !== undefined))
173
+ return yield* ProviderShared.invalidRequest("Cohere Chat does not support provider-defined tools");
174
+ return {
175
+ model: request.model.id,
176
+ messages,
177
+ stream: true,
178
+ tools: tools.length
179
+ ? tools.map((tool) => ({
180
+ type: "function",
181
+ function: { name: tool.name, description: tool.description, parameters: tool.inputSchema },
182
+ }))
183
+ : undefined,
184
+ tool_choice: TOOL_CHOICE[request.toolChoice?.type ?? "auto"],
185
+ thinking: options.thinking && {
186
+ type: options.thinking.type ?? "enabled",
187
+ // Cohere rejects budgets above max_tokens; fitting also leaves room for the answer.
188
+ token_budget: options.thinking.tokenBudget === undefined
189
+ ? undefined
190
+ : ProviderShared.fitThinkingBudget(options.thinking.tokenBudget, request.generation?.maxTokens),
191
+ },
192
+ max_tokens: request.generation?.maxTokens,
193
+ temperature: request.generation?.temperature,
194
+ p: request.generation?.topP,
195
+ k: request.generation?.topK,
196
+ seed: request.generation?.seed,
197
+ stop_sequences: request.generation?.stop,
198
+ frequency_penalty: request.generation?.frequencyPenalty,
199
+ presence_penalty: request.generation?.presencePenalty,
200
+ };
201
+ });
202
+ const finishReason = (raw) => {
203
+ switch (raw) {
204
+ case "COMPLETE":
205
+ case "STOP_SEQUENCE":
206
+ return { normalized: "stop", raw };
207
+ case "MAX_TOKENS":
208
+ return { normalized: "length", raw };
209
+ case "TOOL_CALL":
210
+ return { normalized: "tool-calls", raw };
211
+ case "ERROR":
212
+ case "TIMEOUT":
213
+ return { normalized: "error", raw };
214
+ default:
215
+ return { normalized: "unknown", raw };
216
+ }
217
+ };
218
+ const mapUsage = (usage) => new Usage({
219
+ inputTokens: usage.tokens?.input_tokens,
220
+ outputTokens: usage.tokens?.output_tokens,
221
+ nonCachedInputTokens: ProviderShared.subtractTokens(usage.tokens?.input_tokens, usage.cached_tokens),
222
+ cacheReadInputTokens: usage.cached_tokens,
223
+ reasoningTokens: usage.tokens?.reasoning_tokens,
224
+ totalTokens: ProviderShared.totalTokens(usage.tokens?.input_tokens, usage.tokens?.output_tokens, undefined),
225
+ providerMetadata: { cohere: usage },
226
+ });
227
+ // Lifecycle deltas open blocks on demand and ends are no-ops for closed blocks, so content-start needs no handling.
228
+ const step = Effect.fnUntraced(function* (state, event) {
229
+ const events = [];
230
+ switch (event.type) {
231
+ case "message-start":
232
+ return [{ ...state, lifecycle: Lifecycle.stepStart(state.lifecycle, events) }, events];
233
+ case "content-delta": {
234
+ const id = String(event.index);
235
+ const content = event.delta.message.content;
236
+ const lifecycle = content.thinking !== undefined
237
+ ? Lifecycle.reasoningDelta(state.lifecycle, events, id, content.thinking)
238
+ : Lifecycle.textDelta(state.lifecycle, events, id, content.text ?? "");
239
+ return [{ ...state, lifecycle }, events];
240
+ }
241
+ case "content-end": {
242
+ const id = String(event.index);
243
+ const lifecycle = Lifecycle.textEnd(Lifecycle.reasoningEnd(state.lifecycle, events, id), events, id);
244
+ return [{ ...state, lifecycle }, events];
245
+ }
246
+ case "tool-plan-delta": {
247
+ const plan = event.delta.message.tool_plan;
248
+ const lifecycle = Lifecycle.reasoningDelta(state.lifecycle, events, "tool-plan", plan, {
249
+ cohere: { toolPlan: true },
250
+ });
251
+ return [{ ...state, lifecycle }, events];
252
+ }
253
+ case "tool-call-start":
254
+ case "tool-call-delta": {
255
+ const call = event.delta.message.tool_calls;
256
+ const result = ToolStream.appendOrStart(ADAPTER, state.tools, event.index, { id: call.id, name: call.function.name, text: call.function.arguments ?? "" }, "Cohere tool call is missing id or name");
257
+ if (ToolStream.isError(result))
258
+ return yield* result;
259
+ return [{ ...state, tools: result.tools }, result.events];
260
+ }
261
+ case "tool-call-end": {
262
+ const result = yield* ToolStream.finish(ADAPTER, state.tools, event.index);
263
+ return [{ ...state, tools: result.tools }, result.events ?? []];
264
+ }
265
+ case "message-end": {
266
+ const pending = yield* ToolStream.finishAll(ADAPTER, state.tools);
267
+ events.push(...pending.events);
268
+ const lifecycle = Lifecycle.finish(state.lifecycle, events, {
269
+ reason: finishReason(event.delta.finish_reason),
270
+ usage: event.delta.usage && mapUsage(event.delta.usage),
271
+ });
272
+ return [{ tools: pending.tools, lifecycle, finished: true }, events];
273
+ }
274
+ default:
275
+ return [state, events];
276
+ }
277
+ });
278
+ export const protocol = Protocol.make({
279
+ id: ADAPTER,
280
+ body: { schema: Body, from: fromRequest },
281
+ stream: {
282
+ event: Protocol.jsonEvent(Event),
283
+ initial: () => ({ lifecycle: Lifecycle.initial(), tools: ToolStream.empty(), finished: false }),
284
+ step,
285
+ terminal: (event) => event.type === "message-end",
286
+ onHalt: (state) => state.finished
287
+ ? Effect.succeed([])
288
+ : Effect.fail(ProviderShared.eventError(ADAPTER, "Cohere stream ended without message-end")),
289
+ },
290
+ });
291
+ export const route = Route.make({
292
+ id: ADAPTER,
293
+ provider: "cohere",
294
+ providerMetadataKey: "cohere",
295
+ protocol,
296
+ endpoint: Endpoint.path("/chat", { baseURL: DEFAULT_BASE_URL }),
297
+ framing: Framing.sse,
298
+ });
299
+ export * as CohereChat from "./cohere-chat.js";
@@ -32,7 +32,7 @@ const OUTPUT_FORMATS = {
32
32
  opus: "opus_48000_64",
33
33
  };
34
34
  /** WAV is served only by the non-streaming endpoints. */
35
- const outputFormat = Effect.fn("ElevenLabsSpeech.outputFormat")(function* (request) {
35
+ const outputFormat = Effect.fnUntraced(function* (request) {
36
36
  const format = request.providerOptions?.outputFormat ?? OUTPUT_FORMATS[request.format ?? "mp3"];
37
37
  if (format === undefined)
38
38
  return yield* route.unsupported("media.format", `${route.name} has no default output format for "${request.format}"; pass providerOptions.outputFormat`);
@@ -55,7 +55,7 @@ const path = (request) => `${PATH}/${encodeURIComponent(SpeechStream.voiceID(req
55
55
  // ---------------------------------------------------------------------------
56
56
  // 6. Stream parsing
57
57
  // ---------------------------------------------------------------------------
58
- const onRecord = Effect.fn("ElevenLabsSpeech.onRecord")(function* (state, frame) {
58
+ const onRecord = Effect.fnUntraced(function* (state, frame) {
59
59
  const record = yield* decodeRecord(frame);
60
60
  const [next, events] = SpeechStream.delta(state, record.audio_base64);
61
61
  const alignment = record.alignment;
@@ -80,7 +80,7 @@ const describeOutput = (format) => {
80
80
  const encoding = PCM_CODECS[codec];
81
81
  return encoding === undefined ? SpeechStream.container(codec, sampleRate) : SpeechStream.pcm(encoding, sampleRate);
82
82
  };
83
- const finish = Effect.fn("ElevenLabsSpeech.finish")(function* (state, context) {
83
+ const finish = Effect.fnUntraced(function* (state, context) {
84
84
  const requestID = context.http.headers["request-id"];
85
85
  return yield* SpeechStream.finish(route, state, {
86
86
  ...describeOutput(yield* outputFormat(context.request)),
@@ -158,7 +158,7 @@ export declare const protocol: Protocol<{
158
158
  readonly serviceTier?: string | undefined;
159
159
  readonly toolConfig?: {
160
160
  readonly functionCallingConfig: {
161
- readonly mode: "AUTO" | "NONE" | "ANY";
161
+ readonly mode: "NONE" | "AUTO" | "ANY";
162
162
  readonly allowedFunctionNames?: readonly string[] | undefined;
163
163
  };
164
164
  } | undefined;
@@ -272,7 +272,7 @@ export declare const route: Route<{
272
272
  readonly serviceTier?: string | undefined;
273
273
  readonly toolConfig?: {
274
274
  readonly functionCallingConfig: {
275
- readonly mode: "AUTO" | "NONE" | "ANY";
275
+ readonly mode: "NONE" | "AUTO" | "ANY";
276
276
  readonly allowedFunctionNames?: readonly string[] | undefined;
277
277
  };
278
278
  } | undefined;
@@ -201,7 +201,7 @@ const lowerToolConfig = (toolChoice) => ProviderShared.matchToolChoice("Gemini",
201
201
  required: () => ({ functionCallingConfig: { mode: "ANY" } }),
202
202
  tool: (name) => ({ functionCallingConfig: { mode: "ANY", allowedFunctionNames: [name] } }),
203
203
  });
204
- const lowerContentPart = Effect.fn("Gemini.lowerContentPart")(function* (part) {
204
+ const lowerContentPart = Effect.fnUntraced(function* (part) {
205
205
  if (part.type === "text")
206
206
  return { text: part.text };
207
207
  return yield* GeminiGenerateContent.mediaPart("Gemini", part.media);
@@ -217,7 +217,7 @@ const lowerToolCall = (part, omitIds, metadataKey) => ({
217
217
  functionCall: { ...(omitIds ? {} : { id: part.id }), name: part.name, args: part.input },
218
218
  thoughtSignature: thoughtSignature(part.providerMetadata, metadataKey),
219
219
  });
220
- const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
220
+ const lowerMessages = Effect.fnUntraced(function* (request) {
221
221
  const contents = [];
222
222
  const metadataKey = request.model.route.providerMetadataKey ?? String(request.model.provider);
223
223
  const omitCallIds = omitsFunctionCallIds(request.model.id);
@@ -382,7 +382,7 @@ const fromRequest = Effect.fn("Gemini.fromRequest")(function* (request) {
382
382
  contents: yield* lowerMessages(flattened.request),
383
383
  safetySettings: options.safetySettings,
384
384
  serviceTier: options.serviceTier,
385
- systemInstruction: request.system.length === 0 ? undefined : { parts: [{ text: ProviderShared.joinText(request.system) }] },
385
+ systemInstruction: request.system.length === 0 ? undefined : { parts: request.system.map((part) => ({ text: part.text })) },
386
386
  tools: hasTools
387
387
  ? [
388
388
  {
@@ -0,0 +1,236 @@
1
+ import { Schema } from "effect";
2
+ import { Route } from "../route/client.js";
3
+ import { Protocol } from "../route/protocol.js";
4
+ import { Lifecycle } from "./utils/lifecycle.js";
5
+ import { ToolStream } from "./utils/tool-stream.js";
6
+ export declare const DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
7
+ declare const Options: Schema.Struct<{
8
+ readonly previousInteractionId: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.String>, never>>;
9
+ readonly store: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Boolean>, never>>;
10
+ readonly thinkingLevel: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<import("../schema/options.js").OpenString<"minimal" | "low" | "medium" | "high">, import("../schema/options.js").OpenString<"minimal" | "low" | "medium" | "high">>>, never>>;
11
+ readonly thinkingSummaries: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<import("../schema/options.js").OpenString<"auto" | "none">, import("../schema/options.js").OpenString<"auto" | "none">>>, never>>;
12
+ readonly serviceTier: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<import("../schema/options.js").OpenString<"standard" | "flex" | "priority">, import("../schema/options.js").OpenString<"standard" | "flex" | "priority">>>, never>>;
13
+ }>;
14
+ export type OptionsInput = typeof Options.Encoded;
15
+ export type ProviderOptionsInput = OptionsInput;
16
+ declare const OutputStep: Schema.Struct<{
17
+ readonly type: Schema.String;
18
+ readonly id: Schema.optional<Schema.String>;
19
+ readonly name: Schema.optional<Schema.String>;
20
+ readonly arguments: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
21
+ readonly signature: Schema.optional<Schema.String>;
22
+ readonly summary: Schema.optional<Schema.$Array<Schema.Struct<{
23
+ readonly type: Schema.Literal<"text">;
24
+ readonly text: Schema.String;
25
+ }>>>;
26
+ readonly content: Schema.optional<Schema.$Array<Schema.Struct<{
27
+ readonly type: Schema.String;
28
+ readonly text: Schema.optional<Schema.String>;
29
+ }>>>;
30
+ }>;
31
+ type OutputStep = typeof OutputStep.Type;
32
+ interface ParserState {
33
+ readonly route: string;
34
+ readonly metadataKey: string;
35
+ readonly lifecycle: Lifecycle.State;
36
+ readonly steps: Partial<Record<number, OutputStep>>;
37
+ readonly tools: ToolStream.State<number>;
38
+ readonly completed: boolean;
39
+ }
40
+ export declare const protocol: Protocol<{
41
+ readonly input: readonly ({
42
+ readonly type: "user_input" | "model_output";
43
+ readonly content: readonly ({
44
+ readonly type: "text";
45
+ readonly text: string;
46
+ } | {
47
+ readonly type: "image" | "document" | "video" | "audio";
48
+ readonly mime_type: string;
49
+ readonly data?: string | undefined;
50
+ readonly uri?: string | undefined;
51
+ })[];
52
+ } | {
53
+ readonly type: "thought";
54
+ readonly summary?: readonly {
55
+ readonly type: "text";
56
+ readonly text: string;
57
+ }[] | undefined;
58
+ readonly signature?: string | undefined;
59
+ } | {
60
+ readonly id: string;
61
+ readonly type: "function_call";
62
+ readonly name: string;
63
+ readonly arguments: unknown;
64
+ readonly signature?: string | undefined;
65
+ } | {
66
+ readonly type: "function_result";
67
+ readonly name: string;
68
+ readonly result: unknown;
69
+ readonly call_id: string;
70
+ readonly is_error?: boolean | undefined;
71
+ })[];
72
+ readonly model: string;
73
+ readonly stream: true;
74
+ readonly store: boolean;
75
+ readonly generation_config: {
76
+ readonly temperature?: number | undefined;
77
+ readonly seed?: number | undefined;
78
+ readonly tool_choice?: "auto" | "none" | "any" | {
79
+ readonly allowed_tools: {
80
+ readonly mode: "any";
81
+ readonly tools: readonly string[];
82
+ };
83
+ } | undefined;
84
+ readonly top_p?: number | undefined;
85
+ readonly stop_sequences?: readonly string[] | undefined;
86
+ readonly max_output_tokens?: number | undefined;
87
+ readonly thinking_level?: import("../schema/options.js").OpenString<"minimal" | "low" | "medium" | "high"> | undefined;
88
+ readonly thinking_summaries?: string | undefined;
89
+ };
90
+ readonly tools?: readonly {
91
+ readonly type: "function";
92
+ readonly name: string;
93
+ readonly description: string;
94
+ readonly parameters: {
95
+ readonly [x: string]: unknown;
96
+ };
97
+ }[] | undefined;
98
+ readonly service_tier?: string | undefined;
99
+ readonly previous_interaction_id?: string | undefined;
100
+ readonly system_instruction?: string | undefined;
101
+ }, string, {
102
+ readonly event_type: "step.start";
103
+ readonly index: number;
104
+ readonly step: {
105
+ readonly type: string;
106
+ readonly id?: string | undefined;
107
+ readonly name?: string | undefined;
108
+ readonly summary?: readonly {
109
+ readonly type: "text";
110
+ readonly text: string;
111
+ }[] | undefined;
112
+ readonly content?: readonly {
113
+ readonly type: string;
114
+ readonly text?: string | undefined;
115
+ }[] | undefined;
116
+ readonly signature?: string | undefined;
117
+ readonly arguments?: {
118
+ readonly [x: string]: unknown;
119
+ } | undefined;
120
+ };
121
+ } | {
122
+ readonly event_type: "step.delta";
123
+ readonly index: number;
124
+ readonly delta: {
125
+ readonly type: "text";
126
+ readonly text: string;
127
+ } | {
128
+ readonly type: "arguments_delta";
129
+ readonly arguments: string;
130
+ } | {
131
+ readonly type: "thought_signature";
132
+ readonly signature: string;
133
+ } | {
134
+ readonly type: "thought_summary";
135
+ readonly content: {
136
+ readonly type: "text";
137
+ readonly text: string;
138
+ };
139
+ } | {
140
+ readonly type: string;
141
+ };
142
+ } | {
143
+ readonly event_type: "step.stop";
144
+ readonly index: number;
145
+ } | {
146
+ readonly event_type: "interaction.created";
147
+ readonly interaction: {
148
+ readonly id?: string | undefined;
149
+ };
150
+ } | {
151
+ readonly status: string;
152
+ readonly event_type: "interaction.status_update";
153
+ readonly interaction_id?: string | undefined;
154
+ } | {
155
+ readonly event_type: "interaction.completed";
156
+ readonly interaction: {
157
+ readonly [x: string]: unknown;
158
+ readonly status: string;
159
+ readonly id?: string | undefined;
160
+ readonly usage?: {
161
+ readonly [x: string]: unknown;
162
+ readonly total_input_tokens?: number | null | undefined;
163
+ readonly total_cached_tokens?: number | null | undefined;
164
+ readonly total_output_tokens?: number | null | undefined;
165
+ readonly total_thought_tokens?: number | null | undefined;
166
+ readonly total_tokens?: number | null | undefined;
167
+ readonly raw_prompt_token?: number | null | undefined;
168
+ } | undefined;
169
+ };
170
+ } | {
171
+ readonly event_type: "error";
172
+ readonly error: unknown;
173
+ }, ParserState>;
174
+ export declare const route: Route<{
175
+ readonly input: readonly ({
176
+ readonly type: "user_input" | "model_output";
177
+ readonly content: readonly ({
178
+ readonly type: "text";
179
+ readonly text: string;
180
+ } | {
181
+ readonly type: "image" | "document" | "video" | "audio";
182
+ readonly mime_type: string;
183
+ readonly data?: string | undefined;
184
+ readonly uri?: string | undefined;
185
+ })[];
186
+ } | {
187
+ readonly type: "thought";
188
+ readonly summary?: readonly {
189
+ readonly type: "text";
190
+ readonly text: string;
191
+ }[] | undefined;
192
+ readonly signature?: string | undefined;
193
+ } | {
194
+ readonly id: string;
195
+ readonly type: "function_call";
196
+ readonly name: string;
197
+ readonly arguments: unknown;
198
+ readonly signature?: string | undefined;
199
+ } | {
200
+ readonly type: "function_result";
201
+ readonly name: string;
202
+ readonly result: unknown;
203
+ readonly call_id: string;
204
+ readonly is_error?: boolean | undefined;
205
+ })[];
206
+ readonly model: string;
207
+ readonly stream: true;
208
+ readonly store: boolean;
209
+ readonly generation_config: {
210
+ readonly temperature?: number | undefined;
211
+ readonly seed?: number | undefined;
212
+ readonly tool_choice?: "auto" | "none" | "any" | {
213
+ readonly allowed_tools: {
214
+ readonly mode: "any";
215
+ readonly tools: readonly string[];
216
+ };
217
+ } | undefined;
218
+ readonly top_p?: number | undefined;
219
+ readonly stop_sequences?: readonly string[] | undefined;
220
+ readonly max_output_tokens?: number | undefined;
221
+ readonly thinking_level?: import("../schema/options.js").OpenString<"minimal" | "low" | "medium" | "high"> | undefined;
222
+ readonly thinking_summaries?: string | undefined;
223
+ };
224
+ readonly tools?: readonly {
225
+ readonly type: "function";
226
+ readonly name: string;
227
+ readonly description: string;
228
+ readonly parameters: {
229
+ readonly [x: string]: unknown;
230
+ };
231
+ }[] | undefined;
232
+ readonly service_tier?: string | undefined;
233
+ readonly previous_interaction_id?: string | undefined;
234
+ readonly system_instruction?: string | undefined;
235
+ }, import("../route/transport/http.js").HttpPrepared<string>, import("../route/client.js").CompactionOperations | undefined>;
236
+ export * as GoogleInteractions from "./google-interactions.js";