@opencode/ai 0.0.0-reserved → 2.0.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.
Files changed (288) hide show
  1. package/README.md +879 -2
  2. package/dist/cache-policy.d.ts +2 -0
  3. package/dist/cache-policy.js +129 -0
  4. package/dist/image-client.d.ts +19 -0
  5. package/dist/image-client.js +28 -0
  6. package/dist/image.d.ts +110 -0
  7. package/dist/image.js +103 -0
  8. package/dist/index.d.ts +18 -0
  9. package/dist/index.js +12 -0
  10. package/dist/llm.d.ts +252 -0
  11. package/dist/llm.js +74 -0
  12. package/dist/protocols/alibaba-chat.d.ts +225 -0
  13. package/dist/protocols/alibaba-chat.js +75 -0
  14. package/dist/protocols/alibaba-messages.d.ts +350 -0
  15. package/dist/protocols/alibaba-messages.js +40 -0
  16. package/dist/protocols/alibaba-responses.d.ts +255 -0
  17. package/dist/protocols/alibaba-responses.js +80 -0
  18. package/dist/protocols/anthropic-messages.d.ts +980 -0
  19. package/dist/protocols/anthropic-messages.js +1460 -0
  20. package/dist/protocols/bedrock-converse.d.ts +499 -0
  21. package/dist/protocols/bedrock-converse.js +643 -0
  22. package/dist/protocols/bedrock-event-stream.d.ts +9 -0
  23. package/dist/protocols/bedrock-event-stream.js +97 -0
  24. package/dist/protocols/gemini.d.ts +285 -0
  25. package/dist/protocols/gemini.js +671 -0
  26. package/dist/protocols/google-images.d.ts +30 -0
  27. package/dist/protocols/google-images.js +181 -0
  28. package/dist/protocols/index.d.ts +12 -0
  29. package/dist/protocols/index.js +12 -0
  30. package/dist/protocols/meta-images.d.ts +26 -0
  31. package/dist/protocols/meta-images.js +89 -0
  32. package/dist/protocols/meta-messages.d.ts +356 -0
  33. package/dist/protocols/meta-messages.js +41 -0
  34. package/dist/protocols/meta-responses.d.ts +473 -0
  35. package/dist/protocols/meta-responses.js +173 -0
  36. package/dist/protocols/mistral-chat.d.ts +540 -0
  37. package/dist/protocols/mistral-chat.js +624 -0
  38. package/dist/protocols/open-responses-channel.d.ts +25 -0
  39. package/dist/protocols/open-responses-channel.js +141 -0
  40. package/dist/protocols/open-responses-continuation.d.ts +16 -0
  41. package/dist/protocols/open-responses-continuation.js +170 -0
  42. package/dist/protocols/open-responses.d.ts +1715 -0
  43. package/dist/protocols/open-responses.js +1228 -0
  44. package/dist/protocols/openai-chat.d.ts +860 -0
  45. package/dist/protocols/openai-chat.js +966 -0
  46. package/dist/protocols/openai-compatible-chat.d.ts +109 -0
  47. package/dist/protocols/openai-compatible-chat.js +19 -0
  48. package/dist/protocols/openai-compatible-responses.d.ts +172 -0
  49. package/dist/protocols/openai-compatible-responses.js +18 -0
  50. package/dist/protocols/openai-images.d.ts +32 -0
  51. package/dist/protocols/openai-images.js +183 -0
  52. package/dist/protocols/openai-responses.d.ts +1389 -0
  53. package/dist/protocols/openai-responses.js +260 -0
  54. package/dist/protocols/shared.d.ts +193 -0
  55. package/dist/protocols/shared.js +290 -0
  56. package/dist/protocols/utils/bedrock-auth.d.ts +60 -0
  57. package/dist/protocols/utils/bedrock-auth.js +85 -0
  58. package/dist/protocols/utils/bedrock-cache.d.ts +19 -0
  59. package/dist/protocols/utils/bedrock-cache.js +49 -0
  60. package/dist/protocols/utils/bedrock-media.d.ts +55 -0
  61. package/dist/protocols/utils/bedrock-media.js +73 -0
  62. package/dist/protocols/utils/cache.d.ts +6 -0
  63. package/dist/protocols/utils/cache.js +5 -0
  64. package/dist/protocols/utils/gemini-tool-schema.d.ts +2 -0
  65. package/dist/protocols/utils/gemini-tool-schema.js +103 -0
  66. package/dist/protocols/utils/image-input.d.ts +21 -0
  67. package/dist/protocols/utils/image-input.js +20 -0
  68. package/dist/protocols/utils/lifecycle.d.ts +24 -0
  69. package/dist/protocols/utils/lifecycle.js +72 -0
  70. package/dist/protocols/utils/meta-image.d.ts +2 -0
  71. package/dist/protocols/utils/meta-image.js +13 -0
  72. package/dist/protocols/utils/open-responses-options.d.ts +56 -0
  73. package/dist/protocols/utils/open-responses-options.js +61 -0
  74. package/dist/protocols/utils/openai-image.d.ts +5 -0
  75. package/dist/protocols/utils/openai-image.js +18 -0
  76. package/dist/protocols/utils/openai-options.d.ts +16 -0
  77. package/dist/protocols/utils/openai-options.js +14 -0
  78. package/dist/protocols/utils/partial-json-options.d.ts +62 -0
  79. package/dist/protocols/utils/partial-json-options.js +52 -0
  80. package/dist/protocols/utils/partial-json.d.ts +8 -0
  81. package/dist/protocols/utils/partial-json.js +279 -0
  82. package/dist/protocols/utils/responses-checkpoint.d.ts +4 -0
  83. package/dist/protocols/utils/responses-checkpoint.js +107 -0
  84. package/dist/protocols/utils/responses-compaction.d.ts +4 -0
  85. package/dist/protocols/utils/responses-compaction.js +129 -0
  86. package/dist/protocols/utils/responses-hosted-tools.d.ts +26 -0
  87. package/dist/protocols/utils/responses-hosted-tools.js +32 -0
  88. package/dist/protocols/utils/tool-schema.d.ts +8 -0
  89. package/dist/protocols/utils/tool-schema.js +54 -0
  90. package/dist/protocols/utils/tool-stream.d.ts +710 -0
  91. package/dist/protocols/utils/tool-stream.js +155 -0
  92. package/dist/protocols/xai-images.d.ts +26 -0
  93. package/dist/protocols/xai-images.js +106 -0
  94. package/dist/protocols/xai-responses.d.ts +250 -0
  95. package/dist/protocols/xai-responses.js +81 -0
  96. package/dist/protocols/zai-chat.d.ts +202 -0
  97. package/dist/protocols/zai-chat.js +49 -0
  98. package/dist/protocols/zai-images.d.ts +22 -0
  99. package/dist/protocols/zai-images.js +79 -0
  100. package/dist/protocols/zai-messages.d.ts +344 -0
  101. package/dist/protocols/zai-messages.js +27 -0
  102. package/dist/protocols.d.ts +1 -0
  103. package/dist/protocols.js +1 -0
  104. package/dist/provider-error.d.ts +15 -0
  105. package/dist/provider-error.js +125 -0
  106. package/dist/provider-package.d.ts +15 -0
  107. package/dist/provider-package.js +1 -0
  108. package/dist/provider.d.ts +23 -0
  109. package/dist/provider.js +2 -0
  110. package/dist/providers/alibaba/chat.d.ts +1 -0
  111. package/dist/providers/alibaba/chat.js +1 -0
  112. package/dist/providers/alibaba/messages.d.ts +3 -0
  113. package/dist/providers/alibaba/messages.js +1 -0
  114. package/dist/providers/alibaba/responses.d.ts +3 -0
  115. package/dist/providers/alibaba/responses.js +1 -0
  116. package/dist/providers/alibaba.d.ts +711 -0
  117. package/dist/providers/alibaba.js +94 -0
  118. package/dist/providers/amazon-bedrock/mantle/chat.d.ts +2 -0
  119. package/dist/providers/amazon-bedrock/mantle/chat.js +1 -0
  120. package/dist/providers/amazon-bedrock/mantle/responses.d.ts +2 -0
  121. package/dist/providers/amazon-bedrock/mantle/responses.js +1 -0
  122. package/dist/providers/amazon-bedrock/mantle.d.ts +2 -0
  123. package/dist/providers/amazon-bedrock/mantle.js +1 -0
  124. package/dist/providers/amazon-bedrock-mantle.d.ts +313 -0
  125. package/dist/providers/amazon-bedrock-mantle.js +79 -0
  126. package/dist/providers/amazon-bedrock.d.ts +173 -0
  127. package/dist/providers/amazon-bedrock.js +41 -0
  128. package/dist/providers/anthropic-compatible.d.ts +309 -0
  129. package/dist/providers/anthropic-compatible.js +50 -0
  130. package/dist/providers/anthropic.d.ts +307 -0
  131. package/dist/providers/anthropic.js +42 -0
  132. package/dist/providers/azure/chat.d.ts +2 -0
  133. package/dist/providers/azure/chat.js +1 -0
  134. package/dist/providers/azure/responses.d.ts +2 -0
  135. package/dist/providers/azure/responses.js +1 -0
  136. package/dist/providers/azure.d.ts +598 -0
  137. package/dist/providers/azure.js +115 -0
  138. package/dist/providers/baseten.d.ts +228 -0
  139. package/dist/providers/baseten.js +38 -0
  140. package/dist/providers/cerebras.d.ts +227 -0
  141. package/dist/providers/cerebras.js +40 -0
  142. package/dist/providers/cloudflare-ai-gateway.d.ts +237 -0
  143. package/dist/providers/cloudflare-ai-gateway.js +65 -0
  144. package/dist/providers/cloudflare-workers-ai.d.ts +231 -0
  145. package/dist/providers/cloudflare-workers-ai.js +51 -0
  146. package/dist/providers/deepinfra.d.ts +227 -0
  147. package/dist/providers/deepinfra.js +43 -0
  148. package/dist/providers/deepseek.d.ts +228 -0
  149. package/dist/providers/deepseek.js +41 -0
  150. package/dist/providers/fireworks.d.ts +228 -0
  151. package/dist/providers/fireworks.js +38 -0
  152. package/dist/providers/google-vertex/chat.d.ts +2 -0
  153. package/dist/providers/google-vertex/chat.js +1 -0
  154. package/dist/providers/google-vertex/gemini.d.ts +2 -0
  155. package/dist/providers/google-vertex/gemini.js +1 -0
  156. package/dist/providers/google-vertex/messages.d.ts +2 -0
  157. package/dist/providers/google-vertex/messages.js +1 -0
  158. package/dist/providers/google-vertex/responses.d.ts +2 -0
  159. package/dist/providers/google-vertex/responses.js +1 -0
  160. package/dist/providers/google-vertex-chat.d.ts +132 -0
  161. package/dist/providers/google-vertex-chat.js +55 -0
  162. package/dist/providers/google-vertex-messages.d.ts +306 -0
  163. package/dist/providers/google-vertex-messages.js +75 -0
  164. package/dist/providers/google-vertex-responses.d.ts +197 -0
  165. package/dist/providers/google-vertex-responses.js +56 -0
  166. package/dist/providers/google-vertex-shared.d.ts +22 -0
  167. package/dist/providers/google-vertex-shared.js +72 -0
  168. package/dist/providers/google-vertex.d.ts +119 -0
  169. package/dist/providers/google-vertex.js +98 -0
  170. package/dist/providers/google.d.ts +114 -0
  171. package/dist/providers/google.js +42 -0
  172. package/dist/providers/groq.d.ts +314 -0
  173. package/dist/providers/groq.js +81 -0
  174. package/dist/providers/index.d.ts +31 -0
  175. package/dist/providers/index.js +31 -0
  176. package/dist/providers/meta/chat.d.ts +2 -0
  177. package/dist/providers/meta/chat.js +1 -0
  178. package/dist/providers/meta/messages.d.ts +2 -0
  179. package/dist/providers/meta/messages.js +1 -0
  180. package/dist/providers/meta/responses.d.ts +2 -0
  181. package/dist/providers/meta/responses.js +1 -0
  182. package/dist/providers/meta.d.ts +636 -0
  183. package/dist/providers/meta.js +113 -0
  184. package/dist/providers/minimax/chat.d.ts +4 -0
  185. package/dist/providers/minimax/chat.js +8 -0
  186. package/dist/providers/minimax/messages.d.ts +1 -0
  187. package/dist/providers/minimax/messages.js +1 -0
  188. package/dist/providers/minimax/responses.d.ts +4 -0
  189. package/dist/providers/minimax/responses.js +8 -0
  190. package/dist/providers/minimax.d.ts +598 -0
  191. package/dist/providers/minimax.js +89 -0
  192. package/dist/providers/mistral.d.ts +207 -0
  193. package/dist/providers/mistral.js +28 -0
  194. package/dist/providers/moonshot/chat.d.ts +1 -0
  195. package/dist/providers/moonshot/chat.js +1 -0
  196. package/dist/providers/moonshot/messages.d.ts +4 -0
  197. package/dist/providers/moonshot/messages.js +8 -0
  198. package/dist/providers/moonshot/responses.d.ts +4 -0
  199. package/dist/providers/moonshot/responses.js +8 -0
  200. package/dist/providers/moonshot.d.ts +596 -0
  201. package/dist/providers/moonshot.js +90 -0
  202. package/dist/providers/open-responses-options.d.ts +6 -0
  203. package/dist/providers/open-responses-options.js +1 -0
  204. package/dist/providers/openai/chat.d.ts +2 -0
  205. package/dist/providers/openai/chat.js +1 -0
  206. package/dist/providers/openai/responses.d.ts +2 -0
  207. package/dist/providers/openai/responses.js +1 -0
  208. package/dist/providers/openai-compatible/responses.d.ts +1 -0
  209. package/dist/providers/openai-compatible/responses.js +1 -0
  210. package/dist/providers/openai-compatible-responses.d.ts +195 -0
  211. package/dist/providers/openai-compatible-responses.js +32 -0
  212. package/dist/providers/openai-compatible.d.ts +130 -0
  213. package/dist/providers/openai-compatible.js +33 -0
  214. package/dist/providers/openai-options.d.ts +26 -0
  215. package/dist/providers/openai-options.js +41 -0
  216. package/dist/providers/openai.d.ts +404 -0
  217. package/dist/providers/openai.js +82 -0
  218. package/dist/providers/openrouter.d.ts +563 -0
  219. package/dist/providers/openrouter.js +114 -0
  220. package/dist/providers/togetherai.d.ts +227 -0
  221. package/dist/providers/togetherai.js +40 -0
  222. package/dist/providers/xai.d.ts +163 -0
  223. package/dist/providers/xai.js +88 -0
  224. package/dist/providers/zai/chat.d.ts +1 -0
  225. package/dist/providers/zai/chat.js +1 -0
  226. package/dist/providers/zai-coding-plan/chat.d.ts +1 -0
  227. package/dist/providers/zai-coding-plan/chat.js +1 -0
  228. package/dist/providers/zai-coding-plan/messages.d.ts +4 -0
  229. package/dist/providers/zai-coding-plan/messages.js +8 -0
  230. package/dist/providers/zai-coding-plan/responses.d.ts +4 -0
  231. package/dist/providers/zai-coding-plan/responses.js +8 -0
  232. package/dist/providers/zai-coding-plan.d.ts +577 -0
  233. package/dist/providers/zai-coding-plan.js +63 -0
  234. package/dist/providers/zai.d.ts +149 -0
  235. package/dist/providers/zai.js +53 -0
  236. package/dist/providers.d.ts +1 -0
  237. package/dist/providers.js +1 -0
  238. package/dist/route/auth-options.d.ts +34 -0
  239. package/dist/route/auth-options.js +14 -0
  240. package/dist/route/auth.d.ts +51 -0
  241. package/dist/route/auth.js +87 -0
  242. package/dist/route/client.d.ts +430 -0
  243. package/dist/route/client.js +307 -0
  244. package/dist/route/endpoint.d.ts +28 -0
  245. package/dist/route/endpoint.js +21 -0
  246. package/dist/route/executor.d.ts +27 -0
  247. package/dist/route/executor.js +183 -0
  248. package/dist/route/framing.d.ts +29 -0
  249. package/dist/route/framing.js +14 -0
  250. package/dist/route/index.d.ts +16 -0
  251. package/dist/route/index.js +9 -0
  252. package/dist/route/protocol.d.ts +76 -0
  253. package/dist/route/protocol.js +16 -0
  254. package/dist/route/transport/http.d.ts +34 -0
  255. package/dist/route/transport/http.js +68 -0
  256. package/dist/route/transport/index.d.ts +41 -0
  257. package/dist/route/transport/index.js +4 -0
  258. package/dist/route/transport/websocket-channel.d.ts +57 -0
  259. package/dist/route/transport/websocket-channel.js +1 -0
  260. package/dist/route/transport/websocket.d.ts +56 -0
  261. package/dist/route/transport/websocket.js +370 -0
  262. package/dist/route.d.ts +1 -0
  263. package/dist/route.js +1 -0
  264. package/dist/schema/errors.d.ts +170 -0
  265. package/dist/schema/errors.js +131 -0
  266. package/dist/schema/events.d.ts +8123 -0
  267. package/dist/schema/events.js +550 -0
  268. package/dist/schema/ids.d.ts +17 -0
  269. package/dist/schema/ids.js +10 -0
  270. package/dist/schema/index.d.ts +5 -0
  271. package/dist/schema/index.js +5 -0
  272. package/dist/schema/messages.d.ts +646 -0
  273. package/dist/schema/messages.js +301 -0
  274. package/dist/schema/options.d.ts +159 -0
  275. package/dist/schema/options.js +189 -0
  276. package/dist/testing.d.ts +1693 -0
  277. package/dist/testing.js +129 -0
  278. package/dist/tool-history.d.ts +2 -0
  279. package/dist/tool-history.js +84 -0
  280. package/dist/tool-runtime.d.ts +15 -0
  281. package/dist/tool-runtime.js +62 -0
  282. package/dist/tool.d.ts +136 -0
  283. package/dist/tool.js +66 -0
  284. package/dist/utils/record.d.ts +2 -0
  285. package/dist/utils/record.js +2 -0
  286. package/dist/utils/sanitize.d.ts +1 -0
  287. package/dist/utils/sanitize.js +12 -0
  288. package/package.json +43 -10
@@ -0,0 +1,30 @@
1
+ import { ImageModel } from "../image.js";
2
+ import { type Definition as AuthDefinition } from "../route/auth.js";
3
+ import { type HttpOptions } from "../schema/index.js";
4
+ export declare const DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
5
+ export type GoogleImageString<Known extends string> = Known | (string & {});
6
+ export type GoogleImageOptions = {
7
+ readonly aspectRatio?: GoogleImageString<"1:1" | "2:3" | "3:2" | "3:4" | "4:3" | "4:5" | "5:4" | "9:16" | "16:9" | "21:9">;
8
+ readonly imageSize?: GoogleImageString<"1K" | "2K" | "4K">;
9
+ readonly seed?: number;
10
+ readonly thinkingLevel?: GoogleImageString<"MINIMAL" | "LOW" | "MEDIUM" | "HIGH">;
11
+ readonly includeThoughts?: boolean;
12
+ } & Record<string, unknown>;
13
+ export type GoogleImageBody = Record<string, unknown> & {
14
+ readonly contents: ReadonlyArray<{
15
+ readonly role: "user";
16
+ readonly parts: ReadonlyArray<Record<string, unknown>>;
17
+ }>;
18
+ readonly generationConfig: Record<string, unknown>;
19
+ };
20
+ export interface ModelInput {
21
+ readonly id: string;
22
+ readonly auth: AuthDefinition;
23
+ readonly baseURL?: string;
24
+ readonly headers?: Record<string, string>;
25
+ readonly http?: HttpOptions;
26
+ }
27
+ export declare const model: (input: ModelInput) => ImageModel<GoogleImageOptions>;
28
+ export declare const GoogleImages: {
29
+ readonly model: (input: ModelInput) => ImageModel<GoogleImageOptions>;
30
+ };
@@ -0,0 +1,181 @@
1
+ import { Effect, Encoding, Schema } from "effect";
2
+ import { Headers, HttpClientRequest } from "effect/unstable/http";
3
+ import { GeneratedImage, ImageModel, ImageResponse, } from "../image.js";
4
+ import { Auth } from "../route/auth.js";
5
+ import { AIError, Usage, mergeHttpOptions, mergeJsonRecords } from "../schema/index.js";
6
+ import { ProviderShared } from "./shared.js";
7
+ import { ImageInputs } from "./utils/image-input.js";
8
+ const ADAPTER = "google-images";
9
+ export const DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
10
+ const GoogleUsage = Schema.StructWithRest(Schema.Struct({
11
+ cachedContentTokenCount: Schema.optional(Schema.Number),
12
+ thoughtsTokenCount: Schema.optional(Schema.Number),
13
+ promptTokenCount: Schema.optional(Schema.Number),
14
+ candidatesTokenCount: Schema.optional(Schema.Number),
15
+ totalTokenCount: Schema.optional(Schema.Number),
16
+ promptTokensDetails: Schema.optional(Schema.Unknown),
17
+ candidatesTokensDetails: Schema.optional(Schema.Unknown),
18
+ }), [Schema.Record(Schema.String, Schema.Unknown)]);
19
+ const GoogleImageResponse = Schema.Struct({
20
+ candidates: Schema.optional(Schema.Array(Schema.Struct({
21
+ index: Schema.optional(Schema.Number),
22
+ content: Schema.optional(Schema.Struct({
23
+ parts: Schema.Array(Schema.Struct({
24
+ text: Schema.optional(Schema.String),
25
+ thought: Schema.optional(Schema.Boolean),
26
+ thoughtSignature: Schema.optional(Schema.String),
27
+ inlineData: Schema.optional(Schema.Struct({
28
+ mimeType: Schema.String,
29
+ data: Schema.String,
30
+ })),
31
+ })),
32
+ })),
33
+ finishReason: Schema.optional(Schema.String),
34
+ finishMessage: Schema.optional(Schema.String),
35
+ safetyRatings: Schema.optional(Schema.Unknown),
36
+ citationMetadata: Schema.optional(Schema.Unknown),
37
+ groundingMetadata: Schema.optional(Schema.Unknown),
38
+ }))),
39
+ usageMetadata: Schema.optional(GoogleUsage),
40
+ modelVersion: Schema.optional(Schema.String),
41
+ responseId: Schema.optional(Schema.String),
42
+ promptFeedback: Schema.optional(Schema.Unknown),
43
+ });
44
+ const nativeOptions = (options) => {
45
+ const { aspectRatio, imageSize, seed, thinkingLevel, includeThoughts, ...native } = options ?? {};
46
+ const image = {
47
+ aspectRatio,
48
+ imageSize,
49
+ };
50
+ const thinkingConfig = {
51
+ thinkingLevel,
52
+ includeThoughts,
53
+ };
54
+ return (mergeJsonRecords({
55
+ responseModalities: ["IMAGE"],
56
+ imageConfig: Object.values(image).some((value) => value !== undefined) ? image : undefined,
57
+ seed,
58
+ thinkingConfig: Object.values(thinkingConfig).some((value) => value !== undefined) ? thinkingConfig : undefined,
59
+ }, native) ?? { responseModalities: ["IMAGE"] });
60
+ };
61
+ const applyQuery = (url, query) => {
62
+ if (!query)
63
+ return url;
64
+ const next = new URL(url);
65
+ Object.entries(query).forEach(([key, value]) => next.searchParams.set(key, value));
66
+ return next.toString();
67
+ };
68
+ export const model = (input) => {
69
+ const route = {
70
+ id: ADAPTER,
71
+ generate: Effect.fn("GoogleImages.generate")(function* (request, execute) {
72
+ const imageParts = yield* Effect.forEach(request.images ?? [], googleImagePart);
73
+ const http = mergeHttpOptions(request.model.http, request.http);
74
+ const requestBody = mergeJsonRecords({
75
+ contents: [{ role: "user", parts: [{ text: request.prompt }, ...imageParts] }],
76
+ generationConfig: nativeOptions(request.options),
77
+ }, http?.body);
78
+ const text = ProviderShared.encodeJson(requestBody);
79
+ const url = applyQuery(`${(input.baseURL ?? DEFAULT_BASE_URL).replace(/\/$/, "")}/models/${request.model.id}:generateContent`, http?.query);
80
+ const headers = yield* Auth.toEffect(input.auth)({
81
+ request,
82
+ method: "POST",
83
+ url,
84
+ body: text,
85
+ headers: Headers.fromInput({ ...input.headers, ...http?.headers }),
86
+ });
87
+ const response = yield* execute(HttpClientRequest.post(url).pipe(HttpClientRequest.setHeaders(headers), HttpClientRequest.bodyText(text, "application/json")));
88
+ const output = yield* ProviderShared.imageResponse(ADAPTER, "Google Images", response);
89
+ const decoded = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(GoogleImageResponse))(output.body).pipe(Effect.mapError((cause) => output.invalid("Google Images returned an invalid response", cause)));
90
+ const candidates = decoded.candidates ?? [];
91
+ const candidateMetadata = candidates.map((candidate, candidateIndex) => ({
92
+ index: candidate.index ?? candidateIndex,
93
+ finishReason: candidate.finishReason,
94
+ finishMessage: candidate.finishMessage,
95
+ safetyRatings: candidate.safetyRatings,
96
+ citationMetadata: candidate.citationMetadata,
97
+ groundingMetadata: candidate.groundingMetadata,
98
+ parts: (candidate.content?.parts ?? []).map((part) => part.inlineData === undefined
99
+ ? {
100
+ type: "text",
101
+ text: part.text,
102
+ thought: part.thought,
103
+ thoughtSignature: part.thoughtSignature,
104
+ }
105
+ : {
106
+ type: "inlineData",
107
+ mediaType: part.inlineData.mimeType,
108
+ thought: part.thought,
109
+ thoughtSignature: part.thoughtSignature,
110
+ }),
111
+ }));
112
+ const encoded = candidates.flatMap((candidate, candidateIndex) => (candidate.content?.parts ?? []).flatMap((part, partIndex) => part.inlineData === undefined || part.thought === true
113
+ ? []
114
+ : [{ candidate, candidateIndex, partIndex, inlineData: part.inlineData }]));
115
+ const images = yield* Effect.forEach(encoded, (item) => Effect.fromResult(Encoding.decodeBase64(item.inlineData.data)).pipe(Effect.mapError((cause) => output.invalid(`Google Images candidate ${item.candidateIndex} part ${item.partIndex} contains invalid base64 data`, cause)), Effect.map((data) => new GeneratedImage({
116
+ mediaType: item.inlineData.mimeType,
117
+ data,
118
+ providerMetadata: {
119
+ google: {
120
+ candidateIndex: item.candidate.index ?? item.candidateIndex,
121
+ partIndex: item.partIndex,
122
+ finishReason: item.candidate.finishReason,
123
+ safetyRatings: item.candidate.safetyRatings,
124
+ citationMetadata: item.candidate.citationMetadata,
125
+ groundingMetadata: item.candidate.groundingMetadata,
126
+ thoughtSignature: item.candidate.content?.parts[item.partIndex]?.thoughtSignature,
127
+ },
128
+ },
129
+ }))));
130
+ if (images.length === 0) {
131
+ const finishReasons = candidates.flatMap((candidate) => candidate.finishReason === undefined ? [] : [candidate.finishReason]);
132
+ return yield* output.invalid(`Google Images returned no final images${finishReasons.length === 0 ? "" : ` (finish reasons: ${finishReasons.join(", ")})`}; inspect body for prompt feedback and candidate details`);
133
+ }
134
+ const usage = decoded.usageMetadata;
135
+ const outputTokens = usage?.candidatesTokenCount === undefined
136
+ ? undefined
137
+ : usage.candidatesTokenCount + (usage.thoughtsTokenCount ?? 0);
138
+ return new ImageResponse({
139
+ images,
140
+ usage: usage === undefined
141
+ ? undefined
142
+ : new Usage({
143
+ inputTokens: usage.promptTokenCount,
144
+ outputTokens,
145
+ nonCachedInputTokens: ProviderShared.subtractTokens(usage.promptTokenCount, usage.cachedContentTokenCount),
146
+ cacheReadInputTokens: usage.cachedContentTokenCount,
147
+ reasoningTokens: usage.thoughtsTokenCount,
148
+ totalTokens: ProviderShared.totalTokens(usage.promptTokenCount, outputTokens, usage.totalTokenCount),
149
+ providerMetadata: { google: usage },
150
+ }),
151
+ providerMetadata: {
152
+ google: {
153
+ modelVersion: decoded.modelVersion,
154
+ responseId: decoded.responseId,
155
+ promptFeedback: decoded.promptFeedback,
156
+ candidates: candidateMetadata,
157
+ },
158
+ },
159
+ });
160
+ }),
161
+ };
162
+ return ImageModel.make({ id: input.id, provider: "google", route, http: input.http });
163
+ };
164
+ const googleImagePart = (image) => {
165
+ if (image.type === "bytes")
166
+ return Effect.succeed({ inlineData: { mimeType: image.mediaType, data: Encoding.encodeBase64(image.data) } });
167
+ if (image.type === "file-uri")
168
+ return Effect.succeed({ fileData: { mimeType: image.mediaType, fileUri: image.uri } });
169
+ if (image.type === "url")
170
+ return ImageInputs.decodeDataUrl(image.url).pipe(Effect.flatMap((decoded) => {
171
+ if (decoded === undefined)
172
+ return Effect.fail(ImageInputs.invalid("Google generateContent does not fetch public image URLs; use bytes, a data URL, or a Gemini file URI"));
173
+ return Effect.succeed({
174
+ inlineData: { mimeType: decoded.mediaType, data: Encoding.encodeBase64(decoded.data) },
175
+ });
176
+ }));
177
+ return Effect.fail(ImageInputs.invalid("Google generateContent requires Gemini file URIs rather than provider file IDs"));
178
+ };
179
+ export const GoogleImages = {
180
+ model,
181
+ };
@@ -0,0 +1,12 @@
1
+ export * as AnthropicMessages from "./anthropic-messages.js";
2
+ export * as BedrockConverse from "./bedrock-converse.js";
3
+ export * as Gemini from "./gemini.js";
4
+ export * as MistralChat from "./mistral-chat.js";
5
+ export * as OpenAIChat from "./openai-chat.js";
6
+ export * as OpenAIImages from "./openai-images.js";
7
+ export * as OpenAICompatibleChat from "./openai-compatible-chat.js";
8
+ export * as OpenAICompatibleResponses from "./openai-compatible-responses.js";
9
+ export * as OpenAIResponses from "./openai-responses.js";
10
+ export * as OpenResponses from "./open-responses.js";
11
+ export * as OpenResponsesChannel from "./open-responses-channel.js";
12
+ export * as XAIResponses from "./xai-responses.js";
@@ -0,0 +1,12 @@
1
+ export * as AnthropicMessages from "./anthropic-messages.js";
2
+ export * as BedrockConverse from "./bedrock-converse.js";
3
+ export * as Gemini from "./gemini.js";
4
+ export * as MistralChat from "./mistral-chat.js";
5
+ export * as OpenAIChat from "./openai-chat.js";
6
+ export * as OpenAIImages from "./openai-images.js";
7
+ export * as OpenAICompatibleChat from "./openai-compatible-chat.js";
8
+ export * as OpenAICompatibleResponses from "./openai-compatible-responses.js";
9
+ export * as OpenAIResponses from "./openai-responses.js";
10
+ export * as OpenResponses from "./open-responses.js";
11
+ export * as OpenResponsesChannel from "./open-responses-channel.js";
12
+ export * as XAIResponses from "./xai-responses.js";
@@ -0,0 +1,26 @@
1
+ import { ImageModel } from "../image.js";
2
+ import { Auth } from "../route/auth.js";
3
+ import { type HttpOptions } from "../schema/index.js";
4
+ type OpenString<Known extends string> = Known | (string & {});
5
+ export type ImageOptions = {
6
+ readonly n?: number;
7
+ /** Aspect ratio hint, not an exact output resolution. */
8
+ readonly size?: string;
9
+ readonly outputFormat?: OpenString<"webp" | "png" | "jpeg">;
10
+ readonly responseFormat?: OpenString<"b64_json" | "url">;
11
+ readonly reasoningStrength?: OpenString<"low" | "high">;
12
+ readonly toolEnablement?: {
13
+ readonly enable_image_search?: boolean;
14
+ readonly enable_web_search?: boolean;
15
+ readonly enable_shell?: boolean;
16
+ };
17
+ readonly [key: string]: unknown;
18
+ };
19
+ export declare const model: (input: {
20
+ readonly id: string;
21
+ readonly auth: Auth.Definition;
22
+ readonly baseURL: string;
23
+ readonly headers?: Record<string, string>;
24
+ readonly http?: HttpOptions;
25
+ }) => ImageModel<ImageOptions>;
26
+ export * as MetaImages from "./meta-images.js";
@@ -0,0 +1,89 @@
1
+ import { Effect, Encoding, Schema } from "effect";
2
+ import { Headers, HttpClientRequest } from "effect/unstable/http";
3
+ import { GeneratedImage, ImageModel, ImageResponse } from "../image.js";
4
+ import { Auth } from "../route/auth.js";
5
+ import { Usage, mergeHttpOptions, mergeJsonRecords } from "../schema/index.js";
6
+ import { JsonObject, ProviderShared, optionalNull } from "./shared.js";
7
+ import { ImageInputs } from "./utils/image-input.js";
8
+ const Body = Schema.StructWithRest(Schema.Struct({
9
+ model: Schema.String,
10
+ prompt: Schema.String,
11
+ images: Schema.optional(Schema.Array(JsonObject)),
12
+ n: Schema.optional(Schema.Number),
13
+ size: Schema.optional(Schema.String),
14
+ output_format: Schema.optional(Schema.String),
15
+ response_format: Schema.optional(Schema.String),
16
+ reasoning_strength: Schema.optional(Schema.String),
17
+ tool_enablement: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)),
18
+ }), [JsonObject]);
19
+ const Response = Schema.Struct({
20
+ data: Schema.Array(Schema.Struct({ b64_json: optionalNull(Schema.String), url: optionalNull(Schema.String) })),
21
+ output_format: Schema.optional(Schema.String),
22
+ usage: Schema.optional(Schema.Struct({
23
+ input_tokens: Schema.optional(Schema.Number),
24
+ output_tokens: Schema.optional(Schema.Number),
25
+ total_tokens: Schema.optional(Schema.Number),
26
+ })),
27
+ });
28
+ export const model = (input) => {
29
+ const route = {
30
+ id: "meta-images",
31
+ generate: Effect.fn("MetaImages.generate")(function* (request, execute) {
32
+ const http = mergeHttpOptions(request.model.http, request.http);
33
+ const images = yield* Effect.forEach(request.images ?? [], (image) => {
34
+ if (image.type === "bytes")
35
+ return Effect.succeed({ image_url: ImageInputs.dataUrl(image) });
36
+ if (image.type === "url")
37
+ return Effect.succeed({ image_url: image.url });
38
+ return ImageInputs.invalid("Meta Images accepts image bytes and URLs");
39
+ });
40
+ const { outputFormat, responseFormat, reasoningStrength, toolEnablement, ...native } = request.options ?? {};
41
+ const payload = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Body))(mergeJsonRecords({
42
+ model: request.model.id,
43
+ prompt: request.prompt,
44
+ images: images.length === 0 ? undefined : images,
45
+ output_format: outputFormat,
46
+ response_format: responseFormat,
47
+ reasoning_strength: reasoningStrength,
48
+ tool_enablement: toolEnablement,
49
+ }, native, http?.body));
50
+ const body = ProviderShared.encodeJson(payload);
51
+ const url = new URL(`${input.baseURL.replace(/\/$/, "")}/images/${images.length === 0 ? "generations" : "edits"}`);
52
+ Object.entries(http?.query ?? {}).forEach(([key, value]) => url.searchParams.set(key, value));
53
+ const headers = yield* Auth.toEffect(input.auth)({
54
+ request,
55
+ method: "POST",
56
+ url: url.toString(),
57
+ body,
58
+ headers: Headers.fromInput({ ...input.headers, ...http?.headers }),
59
+ });
60
+ const response = yield* execute(HttpClientRequest.post(url.toString()).pipe(HttpClientRequest.setHeaders(headers), HttpClientRequest.bodyText(body, "application/json")));
61
+ const output = yield* ProviderShared.imageResponse("meta-images", "Meta Images", response);
62
+ const decoded = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(Response))(output.body).pipe(Effect.mapError((cause) => output.invalid("Meta Images returned an invalid response", cause)));
63
+ const format = decoded.output_format ?? payload.output_format ?? "webp";
64
+ const generated = yield* Effect.forEach(decoded.data, (item, index) => {
65
+ if (item.b64_json)
66
+ return Effect.fromResult(Encoding.decodeBase64(item.b64_json)).pipe(Effect.mapError((cause) => output.invalid(`Meta Images result ${index} contains invalid base64`, cause)), Effect.map((data) => new GeneratedImage({ mediaType: `image/${format}`, data })));
67
+ if (item.url)
68
+ return Effect.succeed(new GeneratedImage({ mediaType: `image/${format}`, data: item.url }));
69
+ return output.invalid(`Meta Images result ${index} has neither image data nor a URL`);
70
+ });
71
+ if (generated.length === 0)
72
+ return yield* output.invalid("Meta Images returned no images");
73
+ return new ImageResponse({
74
+ images: generated,
75
+ usage: decoded.usage === undefined
76
+ ? undefined
77
+ : new Usage({
78
+ inputTokens: decoded.usage.input_tokens,
79
+ outputTokens: decoded.usage.output_tokens,
80
+ totalTokens: decoded.usage.total_tokens,
81
+ providerMetadata: { meta: decoded.usage },
82
+ }),
83
+ providerMetadata: { meta: { outputFormat: format } },
84
+ });
85
+ }),
86
+ };
87
+ return ImageModel.make({ id: input.id, provider: "meta", route, http: input.http });
88
+ };
89
+ export * as MetaImages from "./meta-images.js";