@opencode-ai/ai
Advanced tools
| import { ImageModel } from "../image"; | ||
| import { type Definition as AuthDefinition } from "../route/auth"; | ||
| import { type HttpOptions } from "../schema"; | ||
| export declare const DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta"; | ||
| export type GoogleImageString<Known extends string> = Known | (string & {}); | ||
| export type GoogleImageOptions = { | ||
| readonly aspectRatio?: GoogleImageString<"1:1" | "2:3" | "3:2" | "3:4" | "4:3" | "4:5" | "5:4" | "9:16" | "16:9" | "21:9">; | ||
| readonly imageSize?: GoogleImageString<"1K" | "2K" | "4K">; | ||
| readonly seed?: number; | ||
| readonly thinkingLevel?: GoogleImageString<"MINIMAL" | "LOW" | "MEDIUM" | "HIGH">; | ||
| readonly includeThoughts?: boolean; | ||
| } & Record<string, unknown>; | ||
| export type GoogleImageBody = Record<string, unknown> & { | ||
| readonly contents: ReadonlyArray<{ | ||
| readonly role: "user"; | ||
| readonly parts: ReadonlyArray<{ | ||
| readonly text: string; | ||
| }>; | ||
| }>; | ||
| readonly generationConfig: Record<string, unknown>; | ||
| }; | ||
| export interface ModelInput { | ||
| readonly id: string; | ||
| readonly auth: AuthDefinition; | ||
| readonly baseURL?: string; | ||
| readonly headers?: Record<string, string>; | ||
| readonly http?: HttpOptions; | ||
| } | ||
| export declare const model: (input: ModelInput) => ImageModel<GoogleImageOptions>; | ||
| export declare const GoogleImages: { | ||
| readonly model: (input: ModelInput) => ImageModel<GoogleImageOptions>; | ||
| }; |
| import { Effect, Encoding, Schema } from "effect"; | ||
| import { Headers, HttpClientRequest } from "effect/unstable/http"; | ||
| import { GeneratedImage, ImageModel, ImageResponse } from "../image"; | ||
| import { Auth } from "../route/auth"; | ||
| import { InvalidProviderOutputReason, LLMError, Usage, mergeHttpOptions, mergeJsonRecords, } from "../schema"; | ||
| import { ProviderShared } from "./shared"; | ||
| const ADAPTER = "google-images"; | ||
| export const DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta"; | ||
| const GoogleUsage = Schema.StructWithRest(Schema.Struct({ | ||
| cachedContentTokenCount: Schema.optional(Schema.Number), | ||
| thoughtsTokenCount: Schema.optional(Schema.Number), | ||
| promptTokenCount: Schema.optional(Schema.Number), | ||
| candidatesTokenCount: Schema.optional(Schema.Number), | ||
| totalTokenCount: Schema.optional(Schema.Number), | ||
| promptTokensDetails: Schema.optional(Schema.Unknown), | ||
| candidatesTokensDetails: Schema.optional(Schema.Unknown), | ||
| }), [Schema.Record(Schema.String, Schema.Unknown)]); | ||
| const GoogleImageResponse = Schema.Struct({ | ||
| candidates: Schema.optional(Schema.Array(Schema.Struct({ | ||
| index: Schema.optional(Schema.Number), | ||
| content: Schema.optional(Schema.Struct({ | ||
| parts: Schema.Array(Schema.Struct({ | ||
| text: Schema.optional(Schema.String), | ||
| thought: Schema.optional(Schema.Boolean), | ||
| thoughtSignature: Schema.optional(Schema.String), | ||
| inlineData: Schema.optional(Schema.Struct({ | ||
| mimeType: Schema.String, | ||
| data: Schema.String, | ||
| })), | ||
| })), | ||
| })), | ||
| finishReason: Schema.optional(Schema.String), | ||
| finishMessage: Schema.optional(Schema.String), | ||
| safetyRatings: Schema.optional(Schema.Unknown), | ||
| citationMetadata: Schema.optional(Schema.Unknown), | ||
| groundingMetadata: Schema.optional(Schema.Unknown), | ||
| }))), | ||
| usageMetadata: Schema.optional(GoogleUsage), | ||
| modelVersion: Schema.optional(Schema.String), | ||
| responseId: Schema.optional(Schema.String), | ||
| promptFeedback: Schema.optional(Schema.Unknown), | ||
| }); | ||
| const nativeOptions = (options) => { | ||
| const { aspectRatio, imageSize, seed, thinkingLevel, includeThoughts, ...native } = options ?? {}; | ||
| const image = { | ||
| aspectRatio, | ||
| imageSize, | ||
| }; | ||
| const thinkingConfig = { | ||
| thinkingLevel, | ||
| includeThoughts, | ||
| }; | ||
| return (mergeJsonRecords({ | ||
| responseModalities: ["IMAGE"], | ||
| imageConfig: Object.values(image).some((value) => value !== undefined) ? image : undefined, | ||
| seed, | ||
| thinkingConfig: Object.values(thinkingConfig).some((value) => value !== undefined) ? thinkingConfig : undefined, | ||
| }, native) ?? { responseModalities: ["IMAGE"] }); | ||
| }; | ||
| const body = (request, overlay) => mergeJsonRecords({ | ||
| contents: [{ role: "user", parts: [{ text: request.prompt }] }], | ||
| generationConfig: nativeOptions(request.options), | ||
| }, overlay); | ||
| const invalidOutput = (message, providerMetadata) => new LLMError({ | ||
| module: ADAPTER, | ||
| method: "generate", | ||
| reason: new InvalidProviderOutputReason({ message, route: ADAPTER, providerMetadata }), | ||
| }); | ||
| const applyQuery = (url, query) => { | ||
| if (!query) | ||
| return url; | ||
| const next = new URL(url); | ||
| Object.entries(query).forEach(([key, value]) => next.searchParams.set(key, value)); | ||
| return next.toString(); | ||
| }; | ||
| export const model = (input) => { | ||
| const route = { | ||
| id: ADAPTER, | ||
| generate: Effect.fn("GoogleImages.generate")(function* (request, execute) { | ||
| const http = mergeHttpOptions(request.model.http, request.http); | ||
| const text = ProviderShared.encodeJson(body(request, http?.body)); | ||
| const url = applyQuery(`${(input.baseURL ?? DEFAULT_BASE_URL).replace(/\/$/, "")}/models/${request.model.id}:generateContent`, http?.query); | ||
| const headers = yield* Auth.toEffect(input.auth)({ | ||
| request, | ||
| method: "POST", | ||
| url, | ||
| body: text, | ||
| headers: Headers.fromInput({ ...input.headers, ...http?.headers }), | ||
| }); | ||
| const response = yield* execute(HttpClientRequest.post(url).pipe(HttpClientRequest.setHeaders(headers), HttpClientRequest.bodyText(text, "application/json"))); | ||
| const payload = yield* response.json.pipe(Effect.mapError(() => invalidOutput("Failed to read the Google Images response"))); | ||
| const decoded = yield* Schema.decodeUnknownEffect(GoogleImageResponse)(payload).pipe(Effect.mapError(() => invalidOutput("Google Images returned an invalid response"))); | ||
| const candidates = decoded.candidates ?? []; | ||
| const candidateMetadata = candidates.map((candidate, candidateIndex) => ({ | ||
| index: candidate.index ?? candidateIndex, | ||
| finishReason: candidate.finishReason, | ||
| finishMessage: candidate.finishMessage, | ||
| safetyRatings: candidate.safetyRatings, | ||
| citationMetadata: candidate.citationMetadata, | ||
| groundingMetadata: candidate.groundingMetadata, | ||
| parts: (candidate.content?.parts ?? []).map((part) => part.inlineData === undefined | ||
| ? { | ||
| type: "text", | ||
| text: part.text, | ||
| thought: part.thought, | ||
| thoughtSignature: part.thoughtSignature, | ||
| } | ||
| : { | ||
| type: "inlineData", | ||
| mediaType: part.inlineData.mimeType, | ||
| thought: part.thought, | ||
| thoughtSignature: part.thoughtSignature, | ||
| }), | ||
| })); | ||
| const encoded = candidates.flatMap((candidate, candidateIndex) => (candidate.content?.parts ?? []).flatMap((part, partIndex) => part.inlineData === undefined || part.thought === true | ||
| ? [] | ||
| : [{ candidate, candidateIndex, partIndex, inlineData: part.inlineData }])); | ||
| const images = yield* Effect.forEach(encoded, (item) => Effect.fromResult(Encoding.decodeBase64(item.inlineData.data)).pipe(Effect.mapError(() => invalidOutput(`Google Images candidate ${item.candidateIndex} part ${item.partIndex} contains invalid base64 data`)), Effect.map((data) => new GeneratedImage({ | ||
| mediaType: item.inlineData.mimeType, | ||
| data, | ||
| providerMetadata: { | ||
| google: { | ||
| candidateIndex: item.candidate.index ?? item.candidateIndex, | ||
| partIndex: item.partIndex, | ||
| finishReason: item.candidate.finishReason, | ||
| safetyRatings: item.candidate.safetyRatings, | ||
| citationMetadata: item.candidate.citationMetadata, | ||
| groundingMetadata: item.candidate.groundingMetadata, | ||
| thoughtSignature: item.candidate.content?.parts[item.partIndex]?.thoughtSignature, | ||
| }, | ||
| }, | ||
| })))); | ||
| if (images.length === 0) { | ||
| const finishReasons = candidates.flatMap((candidate) => candidate.finishReason === undefined ? [] : [candidate.finishReason]); | ||
| return yield* invalidOutput(`Google Images returned no final images${finishReasons.length === 0 ? "" : ` (finish reasons: ${finishReasons.join(", ")})`}; inspect reason.providerMetadata.google for prompt feedback and candidate details`, { | ||
| google: { | ||
| promptFeedback: decoded.promptFeedback, | ||
| candidates: candidateMetadata, | ||
| }, | ||
| }); | ||
| } | ||
| const usage = decoded.usageMetadata; | ||
| const outputTokens = usage?.candidatesTokenCount === undefined | ||
| ? undefined | ||
| : usage.candidatesTokenCount + (usage.thoughtsTokenCount ?? 0); | ||
| return new ImageResponse({ | ||
| images, | ||
| usage: usage === undefined | ||
| ? undefined | ||
| : new Usage({ | ||
| inputTokens: usage.promptTokenCount, | ||
| outputTokens, | ||
| nonCachedInputTokens: ProviderShared.subtractTokens(usage.promptTokenCount, usage.cachedContentTokenCount), | ||
| cacheReadInputTokens: usage.cachedContentTokenCount, | ||
| reasoningTokens: usage.thoughtsTokenCount, | ||
| totalTokens: ProviderShared.totalTokens(usage.promptTokenCount, outputTokens, usage.totalTokenCount), | ||
| providerMetadata: { google: usage }, | ||
| }), | ||
| providerMetadata: { | ||
| google: { | ||
| modelVersion: decoded.modelVersion, | ||
| responseId: decoded.responseId, | ||
| promptFeedback: decoded.promptFeedback, | ||
| candidates: candidateMetadata, | ||
| }, | ||
| }, | ||
| }); | ||
| }), | ||
| }; | ||
| return ImageModel.make({ id: input.id, provider: "google", route, http: input.http }); | ||
| }; | ||
| export const GoogleImages = { | ||
| model, | ||
| }; |
| import { ImageModel } from "../image"; | ||
| import { type Definition as AuthDefinition } from "../route/auth"; | ||
| import { type HttpOptions } from "../schema"; | ||
| export declare const DEFAULT_BASE_URL = "https://api.x.ai/v1"; | ||
| export declare const PATH = "/images/generations"; | ||
| export type XAIImageString<Known extends string> = Known | (string & {}); | ||
| export type XAIImageOptions = { | ||
| readonly n?: number; | ||
| readonly aspectRatio?: XAIImageString<"1:1" | "3:4" | "4:3" | "9:16" | "16:9" | "2:3" | "3:2" | "9:19.5" | "19.5:9" | "9:20" | "20:9" | "1:2" | "2:1" | "auto">; | ||
| readonly aspect_ratio?: XAIImageString<"1:1" | "3:4" | "4:3" | "9:16" | "16:9" | "2:3" | "3:2" | "9:19.5" | "19.5:9" | "9:20" | "20:9" | "1:2" | "2:1" | "auto">; | ||
| readonly resolution?: XAIImageString<"1k" | "2k">; | ||
| readonly responseFormat?: XAIImageString<"url" | "b64_json">; | ||
| readonly response_format?: XAIImageString<"url" | "b64_json">; | ||
| } & Record<string, unknown>; | ||
| export interface ModelInput { | ||
| readonly id: string; | ||
| readonly auth: AuthDefinition; | ||
| readonly baseURL?: string; | ||
| readonly headers?: Record<string, string>; | ||
| readonly http?: HttpOptions; | ||
| } | ||
| export declare const model: (input: ModelInput) => ImageModel<XAIImageOptions>; | ||
| export declare const XAIImages: { | ||
| readonly model: (input: ModelInput) => ImageModel<XAIImageOptions>; | ||
| }; |
| import { Effect, Encoding, Schema } from "effect"; | ||
| import { Headers, HttpClientRequest } from "effect/unstable/http"; | ||
| import { GeneratedImage, ImageModel, ImageResponse } from "../image"; | ||
| import { Auth } from "../route/auth"; | ||
| import { InvalidProviderOutputReason, LLMError, Usage, mergeHttpOptions, mergeJsonRecords, } from "../schema"; | ||
| import { ProviderShared, optionalNull } from "./shared"; | ||
| const ADAPTER = "xai-images"; | ||
| export const DEFAULT_BASE_URL = "https://api.x.ai/v1"; | ||
| export const PATH = "/images/generations"; | ||
| const XAIImageResponse = Schema.Struct({ | ||
| data: Schema.Array(Schema.Struct({ | ||
| b64_json: optionalNull(Schema.String), | ||
| url: optionalNull(Schema.String), | ||
| revised_prompt: optionalNull(Schema.String), | ||
| mime_type: optionalNull(Schema.String), | ||
| })), | ||
| usage: Schema.optional(Schema.Unknown), | ||
| }); | ||
| const nativeOptions = (options) => { | ||
| if (!options) | ||
| return undefined; | ||
| const { aspectRatio, responseFormat, ...native } = options; | ||
| return { | ||
| aspect_ratio: aspectRatio, | ||
| response_format: responseFormat, | ||
| ...native, | ||
| }; | ||
| }; | ||
| const invalidOutput = (message) => new LLMError({ | ||
| module: ADAPTER, | ||
| method: "generate", | ||
| reason: new InvalidProviderOutputReason({ message, route: ADAPTER }), | ||
| }); | ||
| const applyQuery = (url, query) => { | ||
| if (!query) | ||
| return url; | ||
| const next = new URL(url); | ||
| Object.entries(query).forEach(([key, value]) => next.searchParams.set(key, value)); | ||
| return next.toString(); | ||
| }; | ||
| export const model = (input) => { | ||
| const route = { | ||
| id: ADAPTER, | ||
| generate: Effect.fn("XAIImages.generate")(function* (request, execute) { | ||
| const http = mergeHttpOptions(request.model.http, request.http); | ||
| const requestBody = mergeJsonRecords({ model: request.model.id, prompt: request.prompt }, nativeOptions(request.options), http?.body); | ||
| const text = ProviderShared.encodeJson(requestBody); | ||
| const url = applyQuery(`${(input.baseURL ?? DEFAULT_BASE_URL).replace(/\/$/, "")}${PATH}`, http?.query); | ||
| const headers = yield* Auth.toEffect(input.auth)({ | ||
| request, | ||
| method: "POST", | ||
| url, | ||
| body: text, | ||
| headers: Headers.fromInput({ ...input.headers, ...http?.headers }), | ||
| }); | ||
| const response = yield* execute(HttpClientRequest.post(url).pipe(HttpClientRequest.setHeaders(headers), HttpClientRequest.bodyText(text, "application/json"))); | ||
| const payload = yield* response.json.pipe(Effect.mapError(() => invalidOutput("Failed to read the xAI Images response"))); | ||
| const decoded = yield* Schema.decodeUnknownEffect(XAIImageResponse)(payload).pipe(Effect.mapError(() => invalidOutput("xAI Images returned an invalid response"))); | ||
| const images = yield* Effect.forEach(decoded.data, (item, index) => { | ||
| const mediaType = item.mime_type ?? "application/octet-stream"; | ||
| if (item.b64_json) | ||
| return Effect.fromResult(Encoding.decodeBase64(item.b64_json)).pipe(Effect.mapError(() => invalidOutput(`xAI Images result ${index} contains invalid base64 data`)), Effect.map((data) => new GeneratedImage({ | ||
| mediaType, | ||
| data, | ||
| providerMetadata: item.revised_prompt === undefined || item.revised_prompt === null | ||
| ? undefined | ||
| : { xai: { revisedPrompt: item.revised_prompt } }, | ||
| }))); | ||
| if (item.url) | ||
| return Effect.succeed(new GeneratedImage({ | ||
| mediaType, | ||
| data: item.url, | ||
| providerMetadata: item.revised_prompt === undefined || item.revised_prompt === null | ||
| ? undefined | ||
| : { xai: { revisedPrompt: item.revised_prompt } }, | ||
| })); | ||
| return Effect.fail(invalidOutput(`xAI Images result ${index} has neither image data nor a URL`)); | ||
| }); | ||
| if (images.length === 0) | ||
| return yield* invalidOutput("xAI Images returned no images"); | ||
| const usage = ProviderShared.isRecord(decoded.usage) ? decoded.usage : undefined; | ||
| return new ImageResponse({ | ||
| images, | ||
| usage: usage === undefined ? undefined : new Usage({ providerMetadata: { xai: usage } }), | ||
| providerMetadata: usage === undefined ? undefined : { xai: { usage } }, | ||
| }); | ||
| }), | ||
| }; | ||
| return ImageModel.make({ id: input.id, provider: "xai", route, http: input.http }); | ||
| }; | ||
| export const XAIImages = { | ||
| model, | ||
| }; |
| import { ImageModel } from "../image"; | ||
| import { type Definition as AuthDefinition } from "../route/auth"; | ||
| import { type HttpOptions } from "../schema"; | ||
| export declare const DEFAULT_BASE_URL = "https://api.z.ai/api/paas/v4"; | ||
| export declare const PATH = "/images/generations"; | ||
| export type ZAIImageString<Known extends string> = Known | (string & {}); | ||
| export type ZAIImageOptions = { | ||
| readonly size?: ZAIImageString<"1024x1024" | "768x1344" | "864x1152" | "1344x768" | "1152x864" | "1440x720" | "720x1440">; | ||
| readonly quality?: ZAIImageString<"hd" | "standard">; | ||
| readonly userID?: string; | ||
| } & Record<string, unknown>; | ||
| export interface ModelInput { | ||
| readonly id: string; | ||
| readonly auth: AuthDefinition; | ||
| readonly baseURL?: string; | ||
| readonly headers?: Record<string, string>; | ||
| readonly http?: HttpOptions; | ||
| } | ||
| export declare const model: (input: ModelInput) => ImageModel<ZAIImageOptions>; | ||
| export declare const ZAIImages: { | ||
| readonly model: (input: ModelInput) => ImageModel<ZAIImageOptions>; | ||
| }; |
| import { Effect, Schema } from "effect"; | ||
| import { Headers, HttpClientRequest } from "effect/unstable/http"; | ||
| import { GeneratedImage, ImageModel, ImageResponse } from "../image"; | ||
| import { Auth } from "../route/auth"; | ||
| import { InvalidProviderOutputReason, LLMError, mergeHttpOptions, mergeJsonRecords } from "../schema"; | ||
| import { ProviderShared } from "./shared"; | ||
| const ADAPTER = "zai-images"; | ||
| export const DEFAULT_BASE_URL = "https://api.z.ai/api/paas/v4"; | ||
| export const PATH = "/images/generations"; | ||
| const ZAIImageResponse = Schema.Struct({ | ||
| created: Schema.optional(Schema.Int), | ||
| id: Schema.optional(Schema.String), | ||
| request_id: Schema.optional(Schema.String), | ||
| data: Schema.Array(Schema.Struct({ url: Schema.String })), | ||
| content_filter: Schema.optional(Schema.Array(Schema.Struct({ | ||
| role: Schema.optional(Schema.String), | ||
| level: Schema.optional(Schema.Number), | ||
| }))), | ||
| }); | ||
| const nativeOptions = (options) => { | ||
| if (!options) | ||
| return undefined; | ||
| const { userID, ...native } = options; | ||
| return { | ||
| user_id: userID, | ||
| ...native, | ||
| }; | ||
| }; | ||
| const invalidOutput = (message) => new LLMError({ | ||
| module: ADAPTER, | ||
| method: "generate", | ||
| reason: new InvalidProviderOutputReason({ message, route: ADAPTER }), | ||
| }); | ||
| const applyQuery = (url, query) => { | ||
| if (!query) | ||
| return url; | ||
| const next = new URL(url); | ||
| Object.entries(query).forEach(([key, value]) => next.searchParams.set(key, value)); | ||
| return next.toString(); | ||
| }; | ||
| export const model = (input) => { | ||
| const route = { | ||
| id: ADAPTER, | ||
| generate: Effect.fn("ZAIImages.generate")(function* (request, execute) { | ||
| const http = mergeHttpOptions(request.model.http, request.http); | ||
| const requestBody = mergeJsonRecords({ model: request.model.id, prompt: request.prompt }, nativeOptions(request.options), http?.body); | ||
| const text = ProviderShared.encodeJson(requestBody); | ||
| const url = applyQuery(`${(input.baseURL ?? DEFAULT_BASE_URL).replace(/\/$/, "")}${PATH}`, http?.query); | ||
| const headers = yield* Auth.toEffect(input.auth)({ | ||
| request, | ||
| method: "POST", | ||
| url, | ||
| body: text, | ||
| headers: Headers.fromInput({ ...input.headers, ...http?.headers }), | ||
| }); | ||
| const response = yield* execute(HttpClientRequest.post(url).pipe(HttpClientRequest.setHeaders(headers), HttpClientRequest.bodyText(text, "application/json"))); | ||
| const payload = yield* response.json.pipe(Effect.mapError(() => invalidOutput("Failed to read the Z.ai Images response"))); | ||
| const decoded = yield* Schema.decodeUnknownEffect(ZAIImageResponse)(payload).pipe(Effect.mapError(() => invalidOutput("Z.ai Images returned an invalid response"))); | ||
| if (decoded.data.length === 0) | ||
| return yield* invalidOutput("Z.ai Images returned no images"); | ||
| return new ImageResponse({ | ||
| images: decoded.data.map((item) => new GeneratedImage({ | ||
| mediaType: "application/octet-stream", | ||
| data: item.url, | ||
| })), | ||
| providerMetadata: { | ||
| zai: { | ||
| created: decoded.created, | ||
| id: decoded.id, | ||
| requestID: decoded.request_id, | ||
| contentFilter: decoded.content_filter, | ||
| }, | ||
| }, | ||
| }); | ||
| }), | ||
| }; | ||
| return ImageModel.make({ id: input.id, provider: "zai", route, http: input.http }); | ||
| }; | ||
| export const ZAIImages = { | ||
| model, | ||
| }; |
| import { type ProviderAuthOption } from "../route/auth-options"; | ||
| import { HttpOptions, type ModelID } from "../schema"; | ||
| export declare const id: string & import("effect/Brand").Brand<"LLM.ProviderID">; | ||
| export type Config = ProviderAuthOption<"optional"> & { | ||
| readonly baseURL?: string; | ||
| readonly headers?: Record<string, string>; | ||
| readonly http?: HttpOptions.Input; | ||
| }; | ||
| export type { ZAIImageOptions } from "../protocols/zai-images"; | ||
| export declare const configure: (input?: Config) => { | ||
| id: string & import("effect/Brand").Brand<"LLM.ProviderID">; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./zai").ZAIImageOptions>; | ||
| configure: (input?: Config) => /*elided*/ any; | ||
| }; | ||
| export declare const provider: { | ||
| id: string & import("effect/Brand").Brand<"LLM.ProviderID">; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./zai").ZAIImageOptions>; | ||
| configure: (input?: Config) => { | ||
| id: string & import("effect/Brand").Brand<"LLM.ProviderID">; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./zai").ZAIImageOptions>; | ||
| configure: /*elided*/ any; | ||
| }; | ||
| }; | ||
| export declare const image: (modelID: string | ModelID) => import("..").ImageModel<import("./zai").ZAIImageOptions>; |
| import { ZAIImages } from "../protocols/zai-images"; | ||
| import { AuthOptions } from "../route/auth-options"; | ||
| import { HttpOptions, ProviderID } from "../schema"; | ||
| export const id = ProviderID.make("zai"); | ||
| const auth = (options) => AuthOptions.bearer(options, "ZAI_API_KEY"); | ||
| export const configure = (input = {}) => { | ||
| const image = (modelID) => ZAIImages.model({ | ||
| id: modelID, | ||
| auth: auth(input), | ||
| baseURL: input.baseURL, | ||
| headers: input.headers, | ||
| http: input.http === undefined ? undefined : HttpOptions.make(input.http), | ||
| }); | ||
| return { | ||
| id, | ||
| image, | ||
| configure, | ||
| }; | ||
| }; | ||
| export const provider = configure(); | ||
| export const image = provider.image; |
| import { Context, Effect, Layer } from "effect"; | ||
| import { RequestExecutor } from "./route/executor"; | ||
| import type { ImageRequest, ImageResponse } from "./image"; | ||
| import type { ImageOptions, ImageRequestFor, ImageResponse } from "./image"; | ||
| import type { LLMError } from "./schema"; | ||
| export type Execute = RequestExecutor.Interface["execute"]; | ||
| export interface Interface { | ||
| readonly generate: (request: ImageRequest) => Effect.Effect<ImageResponse, LLMError>; | ||
| readonly generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, LLMError>; | ||
| } | ||
@@ -12,3 +12,3 @@ declare const Service_base: Context.ServiceClass<Service, "@opencode/ImageClient", Interface>; | ||
| } | ||
| export declare const generate: (request: ImageRequest) => Effect.Effect<ImageResponse, LLMError>; | ||
| export declare const generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, LLMError>; | ||
| export declare const layer: Layer.Layer<Service, never, RequestExecutor.Service>; | ||
@@ -18,4 +18,4 @@ export declare const ImageClient: { | ||
| readonly layer: Layer.Layer<Service, never, RequestExecutor.Service>; | ||
| readonly generate: (request: ImageRequest) => Effect.Effect<ImageResponse, LLMError>; | ||
| readonly generate: <Options extends ImageOptions>(request: ImageRequestFor<Options>) => Effect.Effect<ImageResponse, LLMError>; | ||
| }; | ||
| export {}; |
+33
-38
| import { Effect, Schema } from "effect"; | ||
| import { HttpOptions, LLMError, ModelID, ProviderID, Usage } from "./schema"; | ||
| import { type Execute as ImageExecute } from "./image-client"; | ||
| export interface ImageRoute { | ||
| import { Service, type Execute as ImageExecute } from "./image-client"; | ||
| export interface ImageRoute<Options extends ImageOptions = ImageOptions> { | ||
| readonly id: string; | ||
| readonly generate: (request: ImageRequest, execute: ImageExecute) => Effect.Effect<ImageResponse, LLMError>; | ||
| readonly generate: (request: ImageRequestFor<Options>, execute: ImageExecute) => Effect.Effect<ImageResponse, LLMError>; | ||
| } | ||
| export declare class ImageModel { | ||
| export type ImageOptions = Record<string, unknown>; | ||
| export declare class ImageModel<Options extends ImageOptions = ImageOptions> { | ||
| protected readonly _Options: (options: Options) => Options; | ||
| readonly id: ModelID; | ||
| readonly provider: ProviderID; | ||
| readonly route: ImageRoute; | ||
| readonly defaults?: ImageModelDefaults; | ||
| constructor(input: ImageModel.Input); | ||
| static make(input: ImageModel.MakeInput): ImageModel; | ||
| readonly route: ImageRoute<Options>; | ||
| readonly http?: HttpOptions; | ||
| constructor(input: ImageModel.Input<Options>); | ||
| static make<Options extends ImageOptions = ImageOptions>(input: ImageModel.MakeInput<Options>): ImageModel<Options>; | ||
| } | ||
| export declare namespace ImageModel { | ||
| interface Input { | ||
| interface Input<Options extends ImageOptions = ImageOptions> { | ||
| readonly id: ModelID; | ||
| readonly provider: ProviderID; | ||
| readonly route: ImageRoute; | ||
| readonly defaults?: ImageModelDefaults; | ||
| readonly route: ImageRoute<Options>; | ||
| readonly http?: HttpOptions; | ||
| } | ||
| interface MakeInput extends Omit<Input, "id" | "provider"> { | ||
| interface MakeInput<Options extends ImageOptions = ImageOptions> extends Omit<Input<Options>, "id" | "provider"> { | ||
| readonly id: string | ModelID; | ||
@@ -28,31 +30,22 @@ readonly provider: string | ProviderID; | ||
| } | ||
| export interface ImageModelDefaults { | ||
| readonly providerOptions?: Record<string, Record<string, unknown>>; | ||
| readonly http?: HttpOptions; | ||
| } | ||
| export declare const ImageModelSchema: Schema.declare<ImageModel, ImageModel>; | ||
| export declare const ImageSize: Schema.Struct<{ | ||
| readonly width: Schema.Int; | ||
| readonly height: Schema.Int; | ||
| }>; | ||
| export type ImageSize = Schema.Schema.Type<typeof ImageSize>; | ||
| export declare const ImageModelSchema: Schema.declare<ImageModel<ImageOptions>, ImageModel<ImageOptions>>; | ||
| declare const ImageRequest_base: Schema.Class<ImageRequest, Schema.Struct<{ | ||
| readonly model: Schema.declare<ImageModel, ImageModel>; | ||
| readonly model: Schema.declare<ImageModel<ImageOptions>, ImageModel<ImageOptions>>; | ||
| readonly prompt: Schema.String; | ||
| readonly count: Schema.optional<Schema.Int>; | ||
| readonly size: Schema.optional<Schema.Struct<{ | ||
| readonly width: Schema.Int; | ||
| readonly height: Schema.Int; | ||
| }>>; | ||
| readonly aspectRatio: Schema.optional<Schema.String>; | ||
| readonly seed: Schema.optional<Schema.Number>; | ||
| readonly providerOptions: Schema.optional<Schema.$Record<Schema.String, Schema.$Record<Schema.String, Schema.Unknown>>>; | ||
| readonly options: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>; | ||
| readonly http: Schema.optional<typeof HttpOptions>; | ||
| readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>; | ||
| }>, {}>; | ||
| export declare class ImageRequest extends ImageRequest_base { | ||
| protected readonly _ImageRequest: void; | ||
| } | ||
| export type ImageRequestInput = Omit<ConstructorParameters<typeof ImageRequest>[0], "http"> & { | ||
| export type ImageRequestFor<Options extends ImageOptions = ImageOptions> = Omit<ImageRequest, "model" | "options"> & { | ||
| readonly model: ImageModel<Options>; | ||
| readonly options?: Options; | ||
| }; | ||
| export type ImageModelOptions<Model> = Model extends ImageModel<infer Options> ? Options : never; | ||
| export type ImageRequestInput<Model extends object = ImageModel> = Omit<ConstructorParameters<typeof ImageRequest>[0], "model" | "options" | "http"> & { | ||
| readonly model: Model; | ||
| readonly options?: NoInfer<ImageModelOptions<Model>>; | ||
| readonly http?: HttpOptions.Input; | ||
| }; | ||
| } & (Model extends ImageModel<ImageModelOptions<Model>> ? unknown : never); | ||
| declare const GeneratedImage_base: Schema.Class<GeneratedImage, Schema.Struct<{ | ||
@@ -73,8 +66,10 @@ readonly mediaType: Schema.String; | ||
| } | ||
| export declare const request: (input: ImageRequest | ImageRequestInput) => ImageRequest; | ||
| export declare const generate: (input: ImageRequest | ImageRequestInput) => Effect.Effect<ImageResponse, LLMError, never>; | ||
| export declare function request<const Model extends object>(input: ImageRequestInput<Model>): ImageRequestFor<ImageModelOptions<Model>>; | ||
| export declare function request(input: ImageRequest): ImageRequest; | ||
| export declare function generate<const Model extends object>(input: ImageRequestInput<Model>): Effect.Effect<ImageResponse, LLMError, Service>; | ||
| export declare function generate(input: ImageRequest): Effect.Effect<ImageResponse, LLMError, Service>; | ||
| export declare const Image: { | ||
| readonly request: (input: ImageRequest | ImageRequestInput) => ImageRequest; | ||
| readonly generate: (input: ImageRequest | ImageRequestInput) => Effect.Effect<ImageResponse, LLMError, never>; | ||
| readonly request: typeof request; | ||
| readonly generate: typeof generate; | ||
| }; | ||
| export {}; |
+18
-24
| import { Effect, Schema } from "effect"; | ||
| import { HttpOptions, InvalidRequestReason, LLMError, ModelID, ProviderID, ProviderMetadata, Usage } from "./schema"; | ||
| import { ImageClient } from "./image-client"; | ||
| import { ImageClient, Service } from "./image-client"; | ||
| export class ImageModel { | ||
@@ -8,3 +8,3 @@ id; | ||
| route; | ||
| defaults; | ||
| http; | ||
| constructor(input) { | ||
@@ -14,3 +14,3 @@ this.id = input.id; | ||
| this.route = input.route; | ||
| this.defaults = input.defaults; | ||
| this.http = input.http; | ||
| } | ||
@@ -22,3 +22,3 @@ static make(input) { | ||
| route: input.route, | ||
| defaults: input.defaults, | ||
| http: input.http, | ||
| }); | ||
@@ -30,16 +30,7 @@ } | ||
| }); | ||
| export const ImageSize = Schema.Struct({ | ||
| width: Schema.Int.check(Schema.isGreaterThanOrEqualTo(1)), | ||
| height: Schema.Int.check(Schema.isGreaterThanOrEqualTo(1)), | ||
| }).annotate({ identifier: "Image.Size" }); | ||
| export class ImageRequest extends Schema.Class("Image.Request")({ | ||
| model: ImageModelSchema, | ||
| prompt: Schema.String, | ||
| count: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))), | ||
| size: Schema.optional(ImageSize), | ||
| aspectRatio: Schema.optional(Schema.String), | ||
| seed: Schema.optional(Schema.Number), | ||
| providerOptions: Schema.optional(Schema.Record(Schema.String, Schema.Record(Schema.String, Schema.Unknown))), | ||
| options: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)), | ||
| http: Schema.optional(HttpOptions), | ||
| metadata: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)), | ||
| }) { | ||
@@ -62,3 +53,3 @@ } | ||
| } | ||
| export const request = (input) => { | ||
| export function request(input) { | ||
| if (input instanceof ImageRequest) | ||
@@ -68,13 +59,16 @@ return input; | ||
| ...input, | ||
| model: input.model, | ||
| http: input.http === undefined ? undefined : HttpOptions.make(input.http), | ||
| }); | ||
| }; | ||
| export const generate = (input) => Effect.try({ | ||
| try: () => request(input), | ||
| catch: (error) => new LLMError({ | ||
| module: "Image", | ||
| method: "generate", | ||
| reason: new InvalidRequestReason({ message: error instanceof Error ? error.message : String(error) }), | ||
| }), | ||
| }).pipe(Effect.flatMap(ImageClient.generate)); | ||
| } | ||
| export function generate(input) { | ||
| return Effect.try({ | ||
| try: () => (input instanceof ImageRequest ? input : request(input)), | ||
| catch: (error) => new LLMError({ | ||
| module: "Image", | ||
| method: "generate", | ||
| reason: new InvalidRequestReason({ message: error instanceof Error ? error.message : String(error) }), | ||
| }), | ||
| }).pipe(Effect.flatMap((request) => ImageClient.generate(request))); | ||
| } | ||
| export const Image = { | ||
@@ -81,0 +75,0 @@ request, |
+2
-2
@@ -9,4 +9,4 @@ export { LLMClient } from "./route/client"; | ||
| export * from "./schema"; | ||
| export { GeneratedImage, ImageModel, ImageRequest, ImageResponse, ImageSize } from "./image"; | ||
| export type { ImageModelDefaults, ImageRequestInput, ImageRoute } from "./image"; | ||
| export { GeneratedImage, ImageModel, ImageRequest, ImageResponse } from "./image"; | ||
| export type { ImageModelOptions, ImageOptions, ImageRequestFor, ImageRequestInput, ImageRoute } from "./image"; | ||
| export { Image } from "./image"; | ||
@@ -13,0 +13,0 @@ export { Tool, ToolFailure, toDefinitions } from "./tool"; |
+1
-1
@@ -8,3 +8,3 @@ export { LLMClient } from "./route/client"; | ||
| export * from "./schema"; | ||
| export { GeneratedImage, ImageModel, ImageRequest, ImageResponse, ImageSize } from "./image"; | ||
| export { GeneratedImage, ImageModel, ImageRequest, ImageResponse } from "./image"; | ||
| export { Image } from "./image"; | ||
@@ -11,0 +11,0 @@ export { Tool, ToolFailure, toDefinitions } from "./tool"; |
@@ -73,10 +73,10 @@ import { Route, type RouteRoutedModelInput } from "../route/client"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -83,0 +83,0 @@ readonly temperature?: number | undefined; |
@@ -1,25 +0,20 @@ | ||
| import { Schema } from "effect"; | ||
| import { ImageModel, type ImageModelDefaults } from "../image"; | ||
| import { ImageModel } from "../image"; | ||
| import { type Definition as AuthDefinition } from "../route/auth"; | ||
| import { type HttpOptions } from "../schema"; | ||
| export declare const DEFAULT_BASE_URL = "https://api.openai.com/v1"; | ||
| export declare const PATH = "/images/generations"; | ||
| export interface OpenAIImageOptions { | ||
| readonly quality?: "auto" | "low" | "medium" | "high"; | ||
| readonly background?: "auto" | "opaque" | "transparent"; | ||
| readonly moderation?: "auto" | "low"; | ||
| readonly outputFormat?: "png" | "jpeg" | "webp"; | ||
| export type OpenAIImageString<Known extends string> = Known | (string & {}); | ||
| export type OpenAIImageOptions = { | ||
| readonly n?: number; | ||
| readonly size?: OpenAIImageString<"auto" | "256x256" | "512x512" | "1024x1024" | "1536x1024" | "1024x1536" | "1792x1024" | "1024x1792">; | ||
| readonly quality?: OpenAIImageString<"auto" | "low" | "medium" | "high" | "standard" | "hd">; | ||
| readonly background?: OpenAIImageString<"auto" | "opaque" | "transparent">; | ||
| readonly moderation?: OpenAIImageString<"auto" | "low">; | ||
| readonly outputFormat?: OpenAIImageString<"png" | "jpeg" | "webp">; | ||
| readonly outputCompression?: number; | ||
| } | ||
| declare const OpenAIImageBody: Schema.Struct<{ | ||
| readonly model: Schema.String; | ||
| readonly prompt: Schema.String; | ||
| readonly n: Schema.optional<Schema.Int>; | ||
| readonly size: Schema.optional<Schema.String>; | ||
| readonly quality: Schema.optional<Schema.Literals<readonly ["auto", "low", "medium", "high"]>>; | ||
| readonly background: Schema.optional<Schema.Literals<readonly ["auto", "opaque", "transparent"]>>; | ||
| readonly moderation: Schema.optional<Schema.Literals<readonly ["auto", "low"]>>; | ||
| readonly output_format: Schema.optional<Schema.Literals<readonly ["png", "jpeg", "webp"]>>; | ||
| readonly output_compression: Schema.optional<Schema.Int>; | ||
| }>; | ||
| export type OpenAIImageBody = Schema.Schema.Type<typeof OpenAIImageBody>; | ||
| } & Record<string, unknown>; | ||
| export type OpenAIImageBody = Record<string, unknown> & { | ||
| readonly model: string; | ||
| readonly prompt: string; | ||
| }; | ||
| export interface ModelInput { | ||
@@ -30,8 +25,7 @@ readonly id: string; | ||
| readonly headers?: Record<string, string>; | ||
| readonly defaults?: ImageModelDefaults; | ||
| readonly http?: HttpOptions; | ||
| } | ||
| export declare const model: (input: ModelInput) => ImageModel; | ||
| export declare const model: (input: ModelInput) => ImageModel<OpenAIImageOptions>; | ||
| export declare const OpenAIImages: { | ||
| readonly model: (input: ModelInput) => ImageModel; | ||
| readonly model: (input: ModelInput) => ImageModel<OpenAIImageOptions>; | ||
| }; | ||
| export {}; |
| import { Effect, Encoding, Schema } from "effect"; | ||
| import { Headers, HttpClientRequest } from "effect/unstable/http"; | ||
| import { ImageModel, GeneratedImage, ImageResponse, } from "../image"; | ||
| import { ImageModel, GeneratedImage, ImageResponse } from "../image"; | ||
| import { Auth } from "../route/auth"; | ||
| import { InvalidProviderOutputReason, LLMError, Usage, mergeHttpOptions, mergeJsonRecords } from "../schema"; | ||
| import { InvalidProviderOutputReason, LLMError, Usage, mergeHttpOptions, mergeJsonRecords, } from "../schema"; | ||
| import { ProviderShared } from "./shared"; | ||
@@ -11,13 +11,2 @@ import { OpenAIImage } from "./utils/openai-image"; | ||
| export const PATH = "/images/generations"; | ||
| const OpenAIImageBody = Schema.Struct({ | ||
| model: Schema.String, | ||
| prompt: Schema.String, | ||
| n: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))), | ||
| size: Schema.optional(Schema.String), | ||
| quality: Schema.optional(Schema.Literals(["auto", "low", "medium", "high"])), | ||
| background: Schema.optional(Schema.Literals(["auto", "opaque", "transparent"])), | ||
| moderation: Schema.optional(Schema.Literals(["auto", "low"])), | ||
| output_format: Schema.optional(Schema.Literals(["png", "jpeg", "webp"])), | ||
| output_compression: Schema.optional(Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 100 }))), | ||
| }); | ||
| const OpenAIImageResponse = Schema.Struct({ | ||
@@ -38,18 +27,10 @@ data: Schema.Array(Schema.Struct({ | ||
| }); | ||
| const providerOptions = (request) => ({ | ||
| ...request.model.defaults?.providerOptions?.openai, | ||
| ...request.providerOptions?.openai, | ||
| }); | ||
| const body = (request) => { | ||
| const options = providerOptions(request); | ||
| const nativeOptions = (options) => { | ||
| if (!options) | ||
| return undefined; | ||
| const { outputFormat, outputCompression, ...native } = options; | ||
| return { | ||
| model: request.model.id, | ||
| prompt: request.prompt, | ||
| n: request.count, | ||
| size: request.size === undefined ? undefined : `${request.size.width}x${request.size.height}`, | ||
| quality: options.quality, | ||
| background: options.background, | ||
| moderation: options.moderation, | ||
| output_format: options.outputFormat, | ||
| output_compression: options.outputCompression, | ||
| output_format: outputFormat, | ||
| output_compression: outputCompression, | ||
| ...native, | ||
| }; | ||
@@ -69,21 +50,2 @@ }; | ||
| }; | ||
| const PROTOCOL_BODY_FIELDS = new Set([ | ||
| "model", | ||
| "prompt", | ||
| "n", | ||
| "size", | ||
| "quality", | ||
| "background", | ||
| "moderation", | ||
| "output_format", | ||
| "output_compression", | ||
| ]); | ||
| const bodyWithOverlay = Effect.fn("OpenAIImages.bodyWithOverlay")(function* (imageBody, overlay) { | ||
| if (!overlay) | ||
| return imageBody; | ||
| const reserved = Object.keys(overlay).filter((key) => PROTOCOL_BODY_FIELDS.has(key)); | ||
| if (reserved.length > 0) | ||
| return yield* ProviderShared.invalidRequest(`http.body cannot overlay protocol-owned field(s): ${reserved.join(", ")}`); | ||
| return mergeJsonRecords(imageBody, overlay) ?? imageBody; | ||
| }); | ||
| export const model = (input) => { | ||
@@ -93,10 +55,5 @@ const route = { | ||
| generate: Effect.fn("OpenAIImages.generate")(function* (request, execute) { | ||
| if (request.aspectRatio !== undefined) | ||
| return yield* ProviderShared.invalidRequest("OpenAI Images does not support the common aspectRatio option"); | ||
| if (request.seed !== undefined) | ||
| return yield* ProviderShared.invalidRequest("OpenAI Images does not support the common seed option"); | ||
| const requestBody = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(OpenAIImageBody))(body(request)); | ||
| const http = mergeHttpOptions(request.model.defaults?.http, request.http); | ||
| const overlaidBody = yield* bodyWithOverlay(requestBody, http?.body); | ||
| const text = ProviderShared.encodeJson(overlaidBody); | ||
| const http = mergeHttpOptions(request.model.http, request.http); | ||
| const requestBody = mergeJsonRecords({ model: request.model.id, prompt: request.prompt }, nativeOptions(request.options), http?.body); | ||
| const text = ProviderShared.encodeJson(requestBody); | ||
| const url = applyQuery(`${(input.baseURL ?? DEFAULT_BASE_URL).replace(/\/$/, "")}${PATH}`, http?.query); | ||
@@ -113,3 +70,3 @@ const headers = yield* Auth.toEffect(input.auth)({ | ||
| const decoded = yield* Schema.decodeUnknownEffect(OpenAIImageResponse)(payload).pipe(Effect.mapError(() => invalidOutput("OpenAI Images returned an invalid response"))); | ||
| const format = decoded.output_format ?? providerOptions(request).outputFormat ?? "png"; | ||
| const format = decoded.output_format ?? (typeof requestBody.output_format === "string" ? requestBody.output_format : "png"); | ||
| const images = yield* Effect.forEach(decoded.data, (item, index) => { | ||
@@ -146,3 +103,3 @@ if (item.b64_json) | ||
| }; | ||
| return ImageModel.make({ id: input.id, provider: "openai", route, defaults: input.defaults }); | ||
| return ImageModel.make({ id: input.id, provider: "openai", route, http: input.http }); | ||
| }; | ||
@@ -149,0 +106,0 @@ export const OpenAIImages = { |
@@ -167,10 +167,10 @@ import { Schema } from "effect"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -320,10 +320,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -410,10 +410,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -500,10 +500,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -590,10 +590,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -680,10 +680,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -690,0 +690,0 @@ readonly temperature?: number | undefined; |
@@ -152,10 +152,10 @@ import { type AtLeastOne, type ProviderAuthOption } from "../route/auth-options"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -162,0 +162,0 @@ readonly temperature?: number | undefined; |
@@ -140,10 +140,10 @@ import { type ProviderAuthOption } from "../route/auth-options"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -150,0 +150,0 @@ readonly temperature?: number | undefined; |
@@ -84,10 +84,10 @@ import type { ProviderPackage } from "../provider-package"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -94,0 +94,0 @@ readonly temperature?: number | undefined; |
@@ -5,2 +5,3 @@ import type { RouteDefaultsInput } from "../route/client"; | ||
| import { type ModelID, type ProviderOptions } from "../schema"; | ||
| export type { GoogleImageOptions } from "../protocols/google-images"; | ||
| export declare const id: string & import("effect/Brand").Brand<"LLM.ProviderID">; | ||
@@ -73,2 +74,3 @@ export declare const routes: import("../route").Route<{ | ||
| model: (modelID: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./google").GoogleImageOptions>; | ||
| configure: (input?: Config) => /*elided*/ any; | ||
@@ -79,5 +81,7 @@ }; | ||
| model: (modelID: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./google").GoogleImageOptions>; | ||
| configure: (input?: Config) => { | ||
| id: string & import("effect/Brand").Brand<"LLM.ProviderID">; | ||
| model: (modelID: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./google").GoogleImageOptions>; | ||
| configure: /*elided*/ any; | ||
@@ -87,1 +91,2 @@ }; | ||
| export declare const model: ProviderPackage.Definition<Settings>["model"]; | ||
| export declare const image: (modelID: string | ModelID) => import("..").ImageModel<import("./google").GoogleImageOptions>; |
| import { Auth } from "../route/auth"; | ||
| import { ProviderID } from "../schema"; | ||
| import * as Gemini from "../protocols/gemini"; | ||
| import { HttpOptions, ProviderID, mergeHttpOptions } from "../schema"; | ||
| import { Gemini } from "../protocols/gemini"; | ||
| import { GoogleImages } from "../protocols/google-images"; | ||
| export const id = ProviderID.make("google"); | ||
@@ -19,5 +20,13 @@ export const routes = [Gemini.route]; | ||
| const route = configuredRoute(input); | ||
| const image = (modelID) => GoogleImages.model({ | ||
| id: modelID, | ||
| auth: auth(input), | ||
| baseURL: input.baseURL, | ||
| headers: input.headers, | ||
| http: mergeHttpOptions(input.http === undefined ? undefined : HttpOptions.make(input.http)), | ||
| }); | ||
| return { | ||
| id, | ||
| model: (modelID) => route.model({ id: modelID }), | ||
| image, | ||
| configure, | ||
@@ -35,1 +44,2 @@ }; | ||
| }).model(modelID); | ||
| export const image = provider.image; |
@@ -18,1 +18,2 @@ export * as Anthropic from "./anthropic"; | ||
| export * as XAI from "./xai"; | ||
| export * as ZAI from "./zai"; |
@@ -18,1 +18,2 @@ export * as Anthropic from "./anthropic"; | ||
| export * as XAI from "./xai"; | ||
| export * as ZAI from "./zai"; |
@@ -82,10 +82,10 @@ import type { ProviderPackage } from "../provider-package"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -92,0 +92,0 @@ readonly temperature?: number | undefined; |
@@ -6,3 +6,3 @@ import { type ProviderAuthOption } from "../route/auth-options"; | ||
| import { type OpenAIProviderOptionsInput } from "./openai-options"; | ||
| import { type OpenAIImageOptions } from "../protocols/openai-images"; | ||
| import { type OpenAIImageString } from "../protocols/openai-images"; | ||
| export type { OpenAIOptionsInput, OpenAIResponseIncludable } from "./openai-options"; | ||
@@ -139,10 +139,10 @@ export type { OpenAIImageOptions } from "../protocols/openai-images"; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -228,10 +228,10 @@ readonly temperature?: number | undefined; | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -257,16 +257,12 @@ readonly temperature?: number | undefined; | ||
| readonly providerOptions?: OpenAIProviderOptionsInput; | ||
| readonly image?: ImageConfig; | ||
| }; | ||
| export interface ImageConfig { | ||
| readonly providerOptions?: OpenAIImageOptions; | ||
| } | ||
| export interface ImageGenerationOptions { | ||
| readonly action?: "auto" | "generate" | "edit"; | ||
| readonly background?: "auto" | "opaque" | "transparent"; | ||
| readonly inputFidelity?: "low" | "high"; | ||
| readonly action?: OpenAIImageString<"auto" | "generate" | "edit">; | ||
| readonly background?: OpenAIImageString<"auto" | "opaque" | "transparent">; | ||
| readonly inputFidelity?: OpenAIImageString<"low" | "high">; | ||
| readonly outputCompression?: number; | ||
| readonly outputFormat?: "png" | "jpeg" | "webp"; | ||
| readonly outputFormat?: OpenAIImageString<"png" | "jpeg" | "webp">; | ||
| readonly partialImages?: number; | ||
| readonly quality?: "auto" | "low" | "medium" | "high"; | ||
| readonly size?: string; | ||
| readonly quality?: OpenAIImageString<"auto" | "low" | "medium" | "high" | "standard" | "hd">; | ||
| readonly size?: OpenAIImageString<"auto" | "256x256" | "512x512" | "1024x1024" | "1536x1024" | "1024x1536" | "1792x1024" | "1024x1792">; | ||
| } | ||
@@ -289,3 +285,3 @@ export declare const imageGeneration: (options?: ImageGenerationOptions) => ToolDefinition; | ||
| chat: (id: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./openai").OpenAIImageOptions>; | ||
| configure: (input?: Config) => /*elided*/ any; | ||
@@ -299,3 +295,3 @@ }; | ||
| chat: (id: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./openai").OpenAIImageOptions>; | ||
| configure: (input?: Config) => { | ||
@@ -307,3 +303,3 @@ id: string & import("effect/Brand").Brand<"LLM.ProviderID">; | ||
| chat: (id: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./openai").OpenAIImageOptions>; | ||
| configure: /*elided*/ any; | ||
@@ -317,2 +313,2 @@ }; | ||
| export declare const chat: (id: string | ModelID) => import("..").Model; | ||
| export declare const image: (modelID: string | ModelID) => import("..").ImageModel; | ||
| export declare const image: (modelID: string | ModelID) => import("..").ImageModel<import("./openai").OpenAIImageOptions>; |
@@ -29,3 +29,3 @@ import { AuthOptions } from "../route/auth-options"; | ||
| const defaults = (input) => { | ||
| const { apiKey: _, auth: _auth, baseURL: _baseURL, queryParams: _queryParams, image: _image, ...rest } = input; | ||
| const { apiKey: _, auth: _auth, baseURL: _baseURL, queryParams: _queryParams, ...rest } = input; | ||
| return rest; | ||
@@ -50,6 +50,3 @@ }; | ||
| headers: input.headers, | ||
| defaults: { | ||
| providerOptions: input.image?.providerOptions === undefined ? undefined : { openai: { ...input.image.providerOptions } }, | ||
| http: mergeHttpOptions(input.http === undefined ? undefined : HttpOptions.make(input.http), input.queryParams === undefined ? undefined : new HttpOptions({ query: input.queryParams })), | ||
| }, | ||
| http: mergeHttpOptions(input.http === undefined ? undefined : HttpOptions.make(input.http), input.queryParams === undefined ? undefined : new HttpOptions({ query: input.queryParams })), | ||
| }); | ||
@@ -56,0 +53,0 @@ return { |
@@ -8,2 +8,3 @@ import { type ProviderAuthOption } from "../route/auth-options"; | ||
| }; | ||
| export type { XAIImageOptions } from "../protocols/xai-images"; | ||
| export declare const routes: (import("../route").Route<{ | ||
@@ -137,10 +138,10 @@ readonly messages: readonly (import("effect/Schema").Struct.ReadonlySide<{ | ||
| readonly type: "image_generation"; | ||
| readonly size?: string | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly output_format?: "png" | "jpeg" | "webp" | undefined; | ||
| readonly output_compression?: number | undefined; | ||
| readonly action?: "generate" | "auto" | "edit" | undefined; | ||
| readonly background?: "auto" | "opaque" | "transparent" | undefined; | ||
| readonly input_fidelity?: "low" | "high" | undefined; | ||
| readonly partial_images?: number | undefined; | ||
| readonly quality?: "low" | "medium" | "high" | "auto" | undefined; | ||
| readonly size?: string | undefined; | ||
| })[] | undefined; | ||
@@ -167,2 +168,3 @@ readonly temperature?: number | undefined; | ||
| chat: (modelID: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./xai").XAIImageOptions>; | ||
| configure: (input?: ModelOptions) => /*elided*/ any; | ||
@@ -175,2 +177,3 @@ }; | ||
| chat: (modelID: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./xai").XAIImageOptions>; | ||
| configure: (input?: ModelOptions) => { | ||
@@ -181,2 +184,3 @@ id: string & import("effect/Brand").Brand<"LLM.ProviderID">; | ||
| chat: (modelID: string | ModelID) => import("..").Model; | ||
| image: (modelID: string | ModelID) => import("..").ImageModel<import("./xai").XAIImageOptions>; | ||
| configure: /*elided*/ any; | ||
@@ -188,1 +192,2 @@ }; | ||
| export declare const chat: (modelID: string | ModelID) => import("..").Model; | ||
| export declare const image: (modelID: string | ModelID) => import("..").ImageModel<import("./xai").XAIImageOptions>; |
| import { AuthOptions } from "../route/auth-options"; | ||
| import { ProviderID } from "../schema"; | ||
| import { HttpOptions, ProviderID } from "../schema"; | ||
| import * as OpenAICompatibleProfiles from "./openai-compatible-profile"; | ||
| import * as OpenAICompatibleChat from "../protocols/openai-compatible-chat"; | ||
| import * as OpenAIResponses from "../protocols/openai-responses"; | ||
| import { XAIImages } from "../protocols/xai-images"; | ||
| export const id = ProviderID.make("xai"); | ||
@@ -32,2 +33,9 @@ export const routes = [OpenAIResponses.route, OpenAICompatibleChat.route]; | ||
| const chat = (modelID) => chatRoute.model({ id: modelID }); | ||
| const image = (modelID) => XAIImages.model({ | ||
| id: modelID, | ||
| auth: auth(input), | ||
| baseURL: input.baseURL ?? OpenAICompatibleProfiles.profiles.xai.baseURL, | ||
| headers: input.headers, | ||
| http: input.http === undefined ? undefined : HttpOptions.make(input.http), | ||
| }); | ||
| return { | ||
@@ -38,2 +46,3 @@ id, | ||
| chat, | ||
| image, | ||
| configure, | ||
@@ -46,1 +55,2 @@ }; | ||
| export const chat = provider.chat; | ||
| export const image = provider.image; |
+4
-4
| { | ||
| "$schema": "https://json.schemastore.org/package.json", | ||
| "version": "0.0.0-next-15898", | ||
| "version": "0.0.0-next-15910", | ||
| "name": "@opencode-ai/ai", | ||
@@ -10,3 +10,3 @@ "type": "module", | ||
| "test": "bun test --timeout 30000 --only-failures", | ||
| "typecheck": "tsgo --noEmit", | ||
| "typecheck": "tsgo --noEmit && tsgo --noEmit -p tsconfig.types.json", | ||
| "build": "tsc -p tsconfig.build.json" | ||
@@ -30,3 +30,3 @@ }, | ||
| "@effect/platform-node": "4.0.0-beta.98", | ||
| "@opencode-ai/http-recorder": "0.0.0-next-15898", | ||
| "@opencode-ai/http-recorder": "0.0.0-next-15910", | ||
| "@tsconfig/bun": "1.0.9", | ||
@@ -40,3 +40,3 @@ "@types/bun": "1.3.13", | ||
| "@smithy/util-utf8": "4.2.2", | ||
| "@opencode-ai/schema": "0.0.0-next-15898", | ||
| "@opencode-ai/schema": "0.0.0-next-15910", | ||
| "aws4fetch": "1.0.20", | ||
@@ -43,0 +43,0 @@ "effect": "4.0.0-beta.98", |
+89
-4
@@ -39,5 +39,9 @@ # @opencode-ai/ai | ||
| prompt: "A robot tending a rooftop garden", | ||
| count: 2, | ||
| size: { width: 1024, height: 1024 }, | ||
| providerOptions: { openai: { quality: "high", outputFormat: "webp" } }, | ||
| options: { | ||
| n: 2, | ||
| size: "1024x1024", | ||
| quality: "high", // inferred from the OpenAI image model | ||
| outputFormat: "webp", | ||
| future_option: true, // unknown native options pass through unchanged | ||
| }, | ||
| }) | ||
@@ -49,2 +53,83 @@ | ||
| Provider-native image options belong to each request. Raw `http.body` fields have final precedence over them: | ||
| ```ts | ||
| const model = OpenAI.configure({ apiKey }).image("gpt-image-2") | ||
| yield * | ||
| Image.generate({ | ||
| model, | ||
| prompt, | ||
| options: { quality: "medium" }, | ||
| http, | ||
| }) | ||
| ``` | ||
| xAI image models use the same request API with xAI-native controls: | ||
| ```ts | ||
| yield * | ||
| Image.generate({ | ||
| model: XAI.configure({ apiKey }).image("any-model-id"), | ||
| prompt, | ||
| options: { | ||
| n: 2, | ||
| aspectRatio: "16:9", | ||
| resolution: "1k", | ||
| responseFormat: "b64_json", | ||
| future_option: true, | ||
| }, | ||
| http, | ||
| }) | ||
| ``` | ||
| Google's current Gemini image models use the same direct API: | ||
| ```ts | ||
| import { Google } from "@opencode-ai/ai/providers" | ||
| const googleProgram = Effect.gen(function* () { | ||
| const response = yield* Image.generate({ | ||
| model: Google.configure({ apiKey }).image("any-model-id"), | ||
| prompt: "A robot tending a rooftop garden", | ||
| options: { | ||
| aspectRatio: "16:9", | ||
| imageSize: "2K", | ||
| seed: 42, | ||
| thinkingLevel: "HIGH", | ||
| includeThoughts: true, | ||
| futureOption: true, | ||
| }, | ||
| http, | ||
| }) | ||
| return response.images | ||
| }) | ||
| ``` | ||
| Google image options are request-scoped and inferred from the selected model. Known fields autocomplete while | ||
| future string values and arbitrary native Gemini `generationConfig` fields remain available. Native fields override | ||
| their mapped aliases, and `http.body` is the final deep overlay. The selected model ID is sent to Gemini | ||
| `generateContent` without a local allowlist. | ||
| Z.ai image models infer open Z.ai-native options from the selected model: | ||
| ```ts | ||
| yield * | ||
| Image.generate({ | ||
| model: ZAI.configure({ apiKey }).image("any-model-id"), | ||
| prompt, | ||
| options: { | ||
| quality: "hd", | ||
| userID: "user-123", | ||
| future_option: true, | ||
| }, | ||
| http, | ||
| }) | ||
| ``` | ||
| Z.ai does not include trustworthy MIME metadata for output URLs, so generated images use | ||
| `application/octet-stream`. Output URLs expire after 30 days; download and persist them promptly if they must | ||
| remain available. | ||
| Conversational image generation remains part of the LLM interaction. OpenAI Responses exposes it through its hosted image tool: | ||
@@ -150,3 +235,3 @@ | ||
| Included providers: OpenAI, Anthropic, Google (Gemini), Google Vertex Gemini and Anthropic, Amazon Bedrock, Azure OpenAI, Cloudflare AI Gateway, Cloudflare Workers AI, GitHub Copilot, OpenRouter, xAI, plus generic OpenAI-compatible Chat and Responses entrypoints and an Anthropic Messages-compatible entrypoint. | ||
| Included providers: OpenAI, Anthropic, Google (Gemini), Google Vertex Gemini and Anthropic, Amazon Bedrock, Azure OpenAI, Cloudflare AI Gateway, Cloudflare Workers AI, GitHub Copilot, OpenRouter, xAI, Z.ai, plus generic OpenAI-compatible Chat and Responses entrypoints and an Anthropic Messages-compatible entrypoint. | ||
@@ -153,0 +238,0 @@ ### Package-like entrypoints |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
998826
2.61%172
4.88%21086
2.12%319
36.32%+ Added
- Removed